dc125a49164d0bce15ba8cc322397adaa2f693b4
[dragonfly.git] / sys / platform / pc64 / apic / mpapic.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/mpapic.c,v 1.37.2.7 2003/01/25 02:31:47 peter Exp $
26  */
27
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/kernel.h>
31 #include <machine/globaldata.h>
32 #include <machine/smp.h>
33 #include <machine/md_var.h>
34 #include <machine/pmap.h>
35 #include <machine_base/apic/mpapic.h>
36 #include <machine/segments.h>
37 #include <sys/thread2.h>
38
39 #include <machine/intr_machdep.h>
40
41 #include "apicvar.h"
42
43 /* EISA Edge/Level trigger control registers */
44 #define ELCR0   0x4d0                   /* eisa irq 0-7 */
45 #define ELCR1   0x4d1                   /* eisa irq 8-15 */
46
47 volatile lapic_t *lapic;
48
49 static void     lapic_timer_calibrate(void);
50 static void     lapic_timer_set_divisor(int);
51 static void     lapic_timer_fixup_handler(void *);
52 static void     lapic_timer_restart_handler(void *);
53
54 void            lapic_timer_process(void);
55 void            lapic_timer_process_frame(struct intrframe *);
56 void            lapic_timer_always(struct intrframe *);
57
58 static int      lapic_timer_enable = 1;
59 TUNABLE_INT("hw.lapic_timer_enable", &lapic_timer_enable);
60
61 static void     lapic_timer_intr_reload(struct cputimer_intr *, sysclock_t);
62 static void     lapic_timer_intr_enable(struct cputimer_intr *);
63 static void     lapic_timer_intr_restart(struct cputimer_intr *);
64 static void     lapic_timer_intr_pmfixup(struct cputimer_intr *);
65
66 static struct cputimer_intr lapic_cputimer_intr = {
67         .freq = 0,
68         .reload = lapic_timer_intr_reload,
69         .enable = lapic_timer_intr_enable,
70         .config = cputimer_intr_default_config,
71         .restart = lapic_timer_intr_restart,
72         .pmfixup = lapic_timer_intr_pmfixup,
73         .initclock = cputimer_intr_default_initclock,
74         .next = SLIST_ENTRY_INITIALIZER,
75         .name = "lapic",
76         .type = CPUTIMER_INTR_LAPIC,
77         .prio = CPUTIMER_INTR_PRIO_LAPIC,
78         .caps = CPUTIMER_INTR_CAP_NONE
79 };
80
81 /*
82  * pointers to pmapped apic hardware.
83  */
84
85 volatile ioapic_t       **ioapic;
86
87 static int              lapic_timer_divisor_idx = -1;
88 static const uint32_t   lapic_timer_divisors[] = {
89         APIC_TDCR_2,    APIC_TDCR_4,    APIC_TDCR_8,    APIC_TDCR_16,
90         APIC_TDCR_32,   APIC_TDCR_64,   APIC_TDCR_128,  APIC_TDCR_1
91 };
92 #define APIC_TIMER_NDIVISORS (int)(NELEM(lapic_timer_divisors))
93
94
95 void
96 lapic_eoi(void)
97 {
98
99         lapic->eoi = 0;
100 }
101
102 /*
103  * Enable LAPIC, configure interrupts.
104  */
105 void
106 apic_initialize(boolean_t bsp)
107 {
108         uint32_t timer;
109         u_int   temp;
110
111         /*
112          * Setup LINT0 as ExtINT on the BSP.  This is theoretically an
113          * aggregate interrupt input from the 8259.  The INTA cycle
114          * will be routed to the external controller (the 8259) which
115          * is expected to supply the vector.
116          *
117          * Must be setup edge triggered, active high.
118          *
119          * Disable LINT0 on the APs.  It doesn't matter what delivery
120          * mode we use because we leave it masked.
121          */
122         temp = lapic->lvt_lint0;
123         temp &= ~(APIC_LVT_MASKED | APIC_LVT_TRIG_MASK | 
124                   APIC_LVT_POLARITY_MASK | APIC_LVT_DM_MASK);
125         if (mycpu->gd_cpuid == 0)
126                 temp |= APIC_LVT_DM_EXTINT;
127         else
128                 temp |= APIC_LVT_DM_FIXED | APIC_LVT_MASKED;
129         lapic->lvt_lint0 = temp;
130
131         /*
132          * Setup LINT1 as NMI, masked till later.
133          * Edge trigger, active high.
134          */
135         temp = lapic->lvt_lint1;
136         temp &= ~(APIC_LVT_MASKED | APIC_LVT_TRIG_MASK | 
137                   APIC_LVT_POLARITY_MASK | APIC_LVT_DM_MASK);
138         temp |= APIC_LVT_MASKED | APIC_LVT_DM_NMI;
139         lapic->lvt_lint1 = temp;
140
141         /*
142          * Mask the LAPIC error interrupt, LAPIC performance counter
143          * interrupt.
144          */
145         lapic->lvt_error = lapic->lvt_error | APIC_LVT_MASKED;
146         lapic->lvt_pcint = lapic->lvt_pcint | APIC_LVT_MASKED;
147
148         /*
149          * Set LAPIC timer vector and mask the LAPIC timer interrupt.
150          */
151         timer = lapic->lvt_timer;
152         timer &= ~APIC_LVTT_VECTOR;
153         timer |= XTIMER_OFFSET;
154         timer |= APIC_LVTT_MASKED;
155         lapic->lvt_timer = timer;
156
157         /*
158          * Set the Task Priority Register as needed.   At the moment allow
159          * interrupts on all cpus (the APs will remain CLId until they are
160          * ready to deal).  We could disable all but IPIs by setting
161          * temp |= TPR_IPI for cpu != 0.
162          */
163         temp = lapic->tpr;
164         temp &= ~APIC_TPR_PRIO;         /* clear priority field */
165 #ifdef SMP /* APIC-IO */
166 if (!apic_io_enable) {
167 #endif
168         /*
169          * If we are NOT running the IO APICs, the LAPIC will only be used
170          * for IPIs.  Set the TPR to prevent any unintentional interrupts.
171          */
172         temp |= TPR_IPI;
173 #ifdef SMP /* APIC-IO */
174 }
175 #endif
176         lapic->tpr = temp;
177
178         /* 
179          * Enable the LAPIC 
180          */
181         temp = lapic->svr;
182         temp |= APIC_SVR_ENABLE;        /* enable the LAPIC */
183         temp &= ~APIC_SVR_FOCUS_DISABLE; /* enable lopri focus processor */
184
185         /*
186          * Set the spurious interrupt vector.  The low 4 bits of the vector
187          * must be 1111.
188          */
189         if ((XSPURIOUSINT_OFFSET & 0x0F) != 0x0F)
190                 panic("bad XSPURIOUSINT_OFFSET: 0x%08x", XSPURIOUSINT_OFFSET);
191         temp &= ~APIC_SVR_VECTOR;
192         temp |= XSPURIOUSINT_OFFSET;
193
194         lapic->svr = temp;
195
196         /*
197          * Pump out a few EOIs to clean out interrupts that got through
198          * before we were able to set the TPR.
199          */
200         lapic_eoi();
201         lapic_eoi();
202         lapic_eoi();
203
204         if (bsp) {
205                 lapic_timer_calibrate();
206                 if (lapic_timer_enable) {
207                         cputimer_intr_register(&lapic_cputimer_intr);
208                         cputimer_intr_select(&lapic_cputimer_intr, 0);
209                 }
210         } else {
211                 lapic_timer_set_divisor(lapic_timer_divisor_idx);
212         }
213
214         if (bootverbose)
215                 apic_dump("apic_initialize()");
216 }
217
218 static void
219 lapic_timer_set_divisor(int divisor_idx)
220 {
221         KKASSERT(divisor_idx >= 0 && divisor_idx < APIC_TIMER_NDIVISORS);
222         lapic->dcr_timer = lapic_timer_divisors[divisor_idx];
223 }
224
225 static void
226 lapic_timer_oneshot(u_int count)
227 {
228         uint32_t value;
229
230         value = lapic->lvt_timer;
231         value &= ~APIC_LVTT_PERIODIC;
232         lapic->lvt_timer = value;
233         lapic->icr_timer = count;
234 }
235
236 static void
237 lapic_timer_oneshot_quick(u_int count)
238 {
239         lapic->icr_timer = count;
240 }
241
242 static void
243 lapic_timer_calibrate(void)
244 {
245         sysclock_t value;
246
247         /* Try to calibrate the local APIC timer. */
248         for (lapic_timer_divisor_idx = 0;
249              lapic_timer_divisor_idx < APIC_TIMER_NDIVISORS;
250              lapic_timer_divisor_idx++) {
251                 lapic_timer_set_divisor(lapic_timer_divisor_idx);
252                 lapic_timer_oneshot(APIC_TIMER_MAX_COUNT);
253                 DELAY(2000000);
254                 value = APIC_TIMER_MAX_COUNT - lapic->ccr_timer;
255                 if (value != APIC_TIMER_MAX_COUNT)
256                         break;
257         }
258         if (lapic_timer_divisor_idx >= APIC_TIMER_NDIVISORS)
259                 panic("lapic: no proper timer divisor?!\n");
260         lapic_cputimer_intr.freq = value / 2;
261
262         kprintf("lapic: divisor index %d, frequency %u Hz\n",
263                 lapic_timer_divisor_idx, lapic_cputimer_intr.freq);
264 }
265
266 static void
267 lapic_timer_process_oncpu(struct globaldata *gd, struct intrframe *frame)
268 {
269         sysclock_t count;
270
271         gd->gd_timer_running = 0;
272
273         count = sys_cputimer->count();
274         if (TAILQ_FIRST(&gd->gd_systimerq) != NULL)
275                 systimer_intr(&count, 0, frame);
276 }
277
278 void
279 lapic_timer_process(void)
280 {
281         lapic_timer_process_oncpu(mycpu, NULL);
282 }
283
284 void
285 lapic_timer_process_frame(struct intrframe *frame)
286 {
287         lapic_timer_process_oncpu(mycpu, frame);
288 }
289
290 /*
291  * This manual debugging code is called unconditionally from Xtimer
292  * (the lapic timer interrupt) whether the current thread is in a
293  * critical section or not) and can be useful in tracking down lockups.
294  *
295  * NOTE: MANUAL DEBUG CODE
296  */
297 #if 0
298 static int saveticks[SMP_MAXCPU];
299 static int savecounts[SMP_MAXCPU];
300 #endif
301
302 void
303 lapic_timer_always(struct intrframe *frame)
304 {
305 #if 0
306         globaldata_t gd = mycpu;
307         int cpu = gd->gd_cpuid;
308         char buf[64];
309         short *gptr;
310         int i;
311
312         if (cpu <= 20) {
313                 gptr = (short *)0xFFFFFFFF800b8000 + 80 * cpu;
314                 *gptr = ((*gptr + 1) & 0x00FF) | 0x0700;
315                 ++gptr;
316
317                 ksnprintf(buf, sizeof(buf), " %p %16s %d %16s ",
318                     (void *)frame->if_rip, gd->gd_curthread->td_comm, ticks,
319                     gd->gd_infomsg);
320                 for (i = 0; buf[i]; ++i) {
321                         gptr[i] = 0x0700 | (unsigned char)buf[i];
322                 }
323         }
324 #if 0
325         if (saveticks[gd->gd_cpuid] != ticks) {
326                 saveticks[gd->gd_cpuid] = ticks;
327                 savecounts[gd->gd_cpuid] = 0;
328         }
329         ++savecounts[gd->gd_cpuid];
330         if (savecounts[gd->gd_cpuid] > 2000 && panicstr == NULL) {
331                 panic("cpud %d panicing on ticks failure",
332                         gd->gd_cpuid);
333         }
334         for (i = 0; i < ncpus; ++i) {
335                 int delta;
336                 if (saveticks[i] && panicstr == NULL) {
337                         delta = saveticks[i] - ticks;
338                         if (delta < -10 || delta > 10) {
339                                 panic("cpu %d panicing on cpu %d watchdog",
340                                       gd->gd_cpuid, i);
341                         }
342                 }
343         }
344 #endif
345 #endif
346 }
347
348 static void
349 lapic_timer_intr_reload(struct cputimer_intr *cti, sysclock_t reload)
350 {
351         struct globaldata *gd = mycpu;
352
353         reload = (int64_t)reload * cti->freq / sys_cputimer->freq;
354         if (reload < 2)
355                 reload = 2;
356
357         if (gd->gd_timer_running) {
358                 if (reload < lapic->ccr_timer)
359                         lapic_timer_oneshot_quick(reload);
360         } else {
361                 gd->gd_timer_running = 1;
362                 lapic_timer_oneshot_quick(reload);
363         }
364 }
365
366 static void
367 lapic_timer_intr_enable(struct cputimer_intr *cti __unused)
368 {
369         uint32_t timer;
370
371         timer = lapic->lvt_timer;
372         timer &= ~(APIC_LVTT_MASKED | APIC_LVTT_PERIODIC);
373         lapic->lvt_timer = timer;
374
375         lapic_timer_fixup_handler(NULL);
376 }
377
378 static void
379 lapic_timer_fixup_handler(void *arg)
380 {
381         int *started = arg;
382
383         if (started != NULL)
384                 *started = 0;
385
386         if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
387                 /*
388                  * Detect the presence of C1E capability mostly on latest
389                  * dual-cores (or future) k8 family.  This feature renders
390                  * the local APIC timer dead, so we disable it by reading
391                  * the Interrupt Pending Message register and clearing both
392                  * C1eOnCmpHalt (bit 28) and SmiOnCmpHalt (bit 27).
393                  * 
394                  * Reference:
395                  *   "BIOS and Kernel Developer's Guide for AMD NPT
396                  *    Family 0Fh Processors"
397                  *   #32559 revision 3.00
398                  */
399                 if ((cpu_id & 0x00000f00) == 0x00000f00 &&
400                     (cpu_id & 0x0fff0000) >= 0x00040000) {
401                         uint64_t msr;
402
403                         msr = rdmsr(0xc0010055);
404                         if (msr & 0x18000000) {
405                                 struct globaldata *gd = mycpu;
406
407                                 kprintf("cpu%d: AMD C1E detected\n",
408                                         gd->gd_cpuid);
409                                 wrmsr(0xc0010055, msr & ~0x18000000ULL);
410
411                                 /*
412                                  * We are kinda stalled;
413                                  * kick start again.
414                                  */
415                                 gd->gd_timer_running = 1;
416                                 lapic_timer_oneshot_quick(2);
417
418                                 if (started != NULL)
419                                         *started = 1;
420                         }
421                 }
422         }
423 }
424
425 static void
426 lapic_timer_restart_handler(void *dummy __unused)
427 {
428         int started;
429
430         lapic_timer_fixup_handler(&started);
431         if (!started) {
432                 struct globaldata *gd = mycpu;
433
434                 gd->gd_timer_running = 1;
435                 lapic_timer_oneshot_quick(2);
436         }
437 }
438
439 /*
440  * This function is called only by ACPI-CA code currently:
441  * - AMD C1E fixup.  AMD C1E only seems to happen after ACPI
442  *   module controls PM.  So once ACPI-CA is attached, we try
443  *   to apply the fixup to prevent LAPIC timer from hanging.
444  */
445 static void
446 lapic_timer_intr_pmfixup(struct cputimer_intr *cti __unused)
447 {
448         lwkt_send_ipiq_mask(smp_active_mask,
449                             lapic_timer_fixup_handler, NULL);
450 }
451
452 static void
453 lapic_timer_intr_restart(struct cputimer_intr *cti __unused)
454 {
455         lwkt_send_ipiq_mask(smp_active_mask, lapic_timer_restart_handler, NULL);
456 }
457
458
459 /*
460  * dump contents of local APIC registers
461  */
462 void
463 apic_dump(char* str)
464 {
465         kprintf("SMP: CPU%d %s:\n", mycpu->gd_cpuid, str);
466         kprintf("     lint0: 0x%08x lint1: 0x%08x TPR: 0x%08x SVR: 0x%08x\n",
467                 lapic->lvt_lint0, lapic->lvt_lint1, lapic->tpr, lapic->svr);
468 }
469
470
471 #ifdef SMP /* APIC-IO */
472
473 /*
474  * IO APIC code,
475  */
476
477 #define IOAPIC_ISA_INTS         16
478 #define REDIRCNT_IOAPIC(A) \
479             ((int)((io_apic_versions[(A)] & IOART_VER_MAXREDIR) >> MAXREDIRSHIFT) + 1)
480
481 static int trigger (int apic, int pin, u_int32_t * flags);
482 static void polarity (int apic, int pin, u_int32_t * flags, int level);
483
484 #define DEFAULT_FLAGS           \
485         ((u_int32_t)            \
486          (IOART_INTMSET |       \
487           IOART_DESTPHY |       \
488           IOART_DELLOPRI))
489
490 #define DEFAULT_ISA_FLAGS       \
491         ((u_int32_t)            \
492          (IOART_INTMSET |       \
493           IOART_TRGREDG |       \
494           IOART_INTAHI |        \
495           IOART_DESTPHY |       \
496           IOART_DELLOPRI))
497
498 void
499 io_apic_set_id(int apic, int id)
500 {
501         u_int32_t ux;
502         
503         ux = ioapic_read(apic, IOAPIC_ID);      /* get current contents */
504         if (((ux & APIC_ID_MASK) >> 24) != id) {
505                 kprintf("Changing APIC ID for IO APIC #%d"
506                        " from %d to %d on chip\n",
507                        apic, ((ux & APIC_ID_MASK) >> 24), id);
508                 ux &= ~APIC_ID_MASK;    /* clear the ID field */
509                 ux |= (id << 24);
510                 ioapic_write(apic, IOAPIC_ID, ux);      /* write new value */
511                 ux = ioapic_read(apic, IOAPIC_ID);      /* re-read && test */
512                 if (((ux & APIC_ID_MASK) >> 24) != id)
513                         panic("can't control IO APIC #%d ID, reg: 0x%08x",
514                               apic, ux);
515         }
516 }
517
518
519 int
520 io_apic_get_id(int apic)
521 {
522   return (ioapic_read(apic, IOAPIC_ID) & APIC_ID_MASK) >> 24;
523 }
524   
525
526
527 /*
528  * Setup the IO APIC.
529  */
530 void
531 io_apic_setup_intpin(int apic, int pin)
532 {
533         int bus, bustype, irq;
534         u_char          select;         /* the select register is 8 bits */
535         u_int32_t       flags;          /* the window register is 32 bits */
536         u_int32_t       target;         /* the window register is 32 bits */
537         u_int32_t       vector;         /* the window register is 32 bits */
538         int             level;
539         int             cpuid;
540         char            envpath[32];
541
542         select = pin * 2 + IOAPIC_REDTBL0;      /* register */
543
544         /*
545          * Always clear an IO APIC pin before [re]programming it.  This is
546          * particularly important if the pin is set up for a level interrupt
547          * as the IOART_REM_IRR bit might be set.   When we reprogram the
548          * vector any EOI from pending ints on this pin could be lost and
549          * IRR might never get reset.
550          *
551          * To fix this problem, clear the vector and make sure it is 
552          * programmed as an edge interrupt.  This should theoretically
553          * clear IRR so we can later, safely program it as a level 
554          * interrupt.
555          */
556         imen_lock();
557
558         flags = ioapic_read(apic, select) & IOART_RESV;
559         flags |= IOART_INTMSET | IOART_TRGREDG | IOART_INTAHI;
560         flags |= IOART_DESTPHY | IOART_DELFIXED;
561
562         target = ioapic_read(apic, select + 1) & IOART_HI_DEST_RESV;
563         target |= 0;    /* fixed mode cpu mask of 0 - don't deliver anywhere */
564
565         vector = 0;
566
567         ioapic_write(apic, select, flags | vector);
568         ioapic_write(apic, select + 1, target);
569
570         imen_unlock();
571
572         /*
573          * We only deal with vectored interrupts here.  ? documentation is
574          * lacking, I'm guessing an interrupt type of 0 is the 'INT' type,
575          * vs ExTINT, etc.
576          *
577          * This test also catches unconfigured pins.
578          */
579         if (apic_int_type(apic, pin) != 0)
580                 return;
581
582         /*
583          * Leave the pin unprogrammed if it does not correspond to
584          * an IRQ.
585          */
586         irq = apic_irq(apic, pin);
587         if (irq < 0)
588                 return;
589         
590         /* determine the bus type for this pin */
591         bus = apic_src_bus_id(apic, pin);
592         if (bus < 0)
593                 return;
594         bustype = apic_bus_type(bus);
595         
596         if ((bustype == ISA) &&
597             (pin < IOAPIC_ISA_INTS) && 
598             (irq == pin) &&
599             (apic_polarity(apic, pin) == 0x1) &&
600             (apic_trigger(apic, pin) == 0x3)) {
601                 /* 
602                  * A broken BIOS might describe some ISA 
603                  * interrupts as active-high level-triggered.
604                  * Use default ISA flags for those interrupts.
605                  */
606                 flags = DEFAULT_ISA_FLAGS;
607         } else {
608                 /* 
609                  * Program polarity and trigger mode according to 
610                  * interrupt entry.
611                  */
612                 flags = DEFAULT_FLAGS;
613                 level = trigger(apic, pin, &flags);
614                 if (level == 1)
615                         int_to_apicintpin[irq].flags |= IOAPIC_IM_FLAG_LEVEL;
616                 polarity(apic, pin, &flags, level);
617         }
618
619         cpuid = 0;
620         ksnprintf(envpath, sizeof(envpath), "hw.irq.%d.dest", irq);
621         kgetenv_int(envpath, &cpuid);
622
623         /* ncpus may not be available yet */
624         if (cpuid > mp_naps)
625                 cpuid = 0;
626
627         if (bootverbose) {
628                 kprintf("IOAPIC #%d intpin %d -> irq %d (CPU%d)\n",
629                        apic, pin, irq, cpuid);
630         }
631
632         /*
633          * Program the appropriate registers.  This routing may be 
634          * overridden when an interrupt handler for a device is
635          * actually added (see register_int(), which calls through
636          * the MACHINTR ABI to set up an interrupt handler/vector).
637          *
638          * The order in which we must program the two registers for
639          * safety is unclear! XXX
640          */
641         imen_lock();
642
643         vector = IDT_OFFSET + irq;                      /* IDT vec */
644         target = ioapic_read(apic, select + 1) & IOART_HI_DEST_RESV;
645         /* Deliver all interrupts to CPU0 (BSP) */
646         target |= (CPU_TO_ID(cpuid) << IOART_HI_DEST_SHIFT) &
647                   IOART_HI_DEST_MASK;
648         flags |= ioapic_read(apic, select) & IOART_RESV;
649         ioapic_write(apic, select, flags | vector);
650         ioapic_write(apic, select + 1, target);
651
652         imen_unlock();
653 }
654
655 int
656 io_apic_setup(int apic)
657 {
658         int             maxpin;
659         int             pin;
660
661         maxpin = REDIRCNT_IOAPIC(apic);         /* pins in APIC */
662         kprintf("Programming %d pins in IOAPIC #%d\n", maxpin, apic);
663         
664         for (pin = 0; pin < maxpin; ++pin) {
665                 io_apic_setup_intpin(apic, pin);
666         }
667         while (pin < 32) {
668                 if (apic_int_type(apic, pin) >= 0) {
669                         kprintf("Warning: IOAPIC #%d pin %d does not exist,"
670                                 " cannot program!\n", apic, pin);
671                 }
672                 ++pin;
673         }
674
675         /* return GOOD status */
676         return 0;
677 }
678 #undef DEFAULT_ISA_FLAGS
679 #undef DEFAULT_FLAGS
680
681
682 #define DEFAULT_EXTINT_FLAGS    \
683         ((u_int32_t)            \
684          (IOART_INTMSET |       \
685           IOART_TRGREDG |       \
686           IOART_INTAHI |        \
687           IOART_DESTPHY |       \
688           IOART_DELLOPRI))
689
690 /*
691  * XXX this function is only used by 8254 setup
692  * Setup the source of External INTerrupts.
693  */
694 int
695 ext_int_setup(int apic, int intr)
696 {
697         u_char  select;         /* the select register is 8 bits */
698         u_int32_t flags;        /* the window register is 32 bits */
699         u_int32_t target;       /* the window register is 32 bits */
700         u_int32_t vector;       /* the window register is 32 bits */
701         int cpuid;
702         char envpath[32];
703
704         if (apic_int_type(apic, intr) != 3)
705                 return -1;
706
707         cpuid = 0;
708         ksnprintf(envpath, sizeof(envpath), "hw.irq.%d.dest", intr);
709         kgetenv_int(envpath, &cpuid);
710
711         /* ncpus may not be available yet */
712         if (cpuid > mp_naps)
713                 cpuid = 0;
714
715         /* Deliver interrupts to CPU0 (BSP) */
716         target = (CPU_TO_ID(cpuid) << IOART_HI_DEST_SHIFT) &
717                  IOART_HI_DEST_MASK;
718         select = IOAPIC_REDTBL0 + (2 * intr);
719         vector = IDT_OFFSET + intr;
720         flags = DEFAULT_EXTINT_FLAGS;
721
722         ioapic_write(apic, select, flags | vector);
723         ioapic_write(apic, select + 1, target);
724
725         return 0;
726 }
727 #undef DEFAULT_EXTINT_FLAGS
728
729
730 /*
731  * Set the trigger level for an IO APIC pin.
732  */
733 static int
734 trigger(int apic, int pin, u_int32_t * flags)
735 {
736         int     id;
737         int     eirq;
738         int     level;
739         static int intcontrol = -1;
740
741         switch (apic_trigger(apic, pin)) {
742
743         case 0x00:
744                 break;
745
746         case 0x01:
747                 *flags &= ~IOART_TRGRLVL;       /* *flags |= IOART_TRGREDG */
748                 return 0;
749
750         case 0x03:
751                 *flags |= IOART_TRGRLVL;
752                 return 1;
753
754         case -1:
755         default:
756                 goto bad;
757         }
758
759         if ((id = apic_src_bus_id(apic, pin)) == -1)
760                 goto bad;
761
762         switch (apic_bus_type(id)) {
763         case ISA:
764                 *flags &= ~IOART_TRGRLVL;       /* *flags |= IOART_TRGREDG; */
765                 return 0;
766
767         case EISA:
768                 eirq = apic_src_bus_irq(apic, pin);
769
770                 if (eirq < 0 || eirq > 15) {
771                         kprintf("EISA IRQ %d?!?!\n", eirq);
772                         goto bad;
773                 }
774
775                 if (intcontrol == -1) {
776                         intcontrol = inb(ELCR1) << 8;
777                         intcontrol |= inb(ELCR0);
778                         kprintf("EISA INTCONTROL = %08x\n", intcontrol);
779                 }
780
781                 /* Use ELCR settings to determine level or edge mode */
782                 level = (intcontrol >> eirq) & 1;
783
784                 /*
785                  * Note that on older Neptune chipset based systems, any
786                  * pci interrupts often show up here and in the ELCR as well
787                  * as level sensitive interrupts attributed to the EISA bus.
788                  */
789
790                 if (level)
791                         *flags |= IOART_TRGRLVL;
792                 else
793                         *flags &= ~IOART_TRGRLVL;
794
795                 return level;
796
797         case PCI:
798                 *flags |= IOART_TRGRLVL;
799                 return 1;
800
801         case -1:
802         default:
803                 goto bad;
804         }
805
806 bad:
807         panic("bad APIC IO INT flags");
808 }
809
810
811 /*
812  * Set the polarity value for an IO APIC pin.
813  */
814 static void
815 polarity(int apic, int pin, u_int32_t * flags, int level)
816 {
817         int     id;
818
819         switch (apic_polarity(apic, pin)) {
820
821         case 0x00:
822                 break;
823
824         case 0x01:
825                 *flags &= ~IOART_INTALO;        /* *flags |= IOART_INTAHI */
826                 return;
827
828         case 0x03:
829                 *flags |= IOART_INTALO;
830                 return;
831
832         case -1:
833         default:
834                 goto bad;
835         }
836
837         if ((id = apic_src_bus_id(apic, pin)) == -1)
838                 goto bad;
839
840         switch (apic_bus_type(id)) {
841         case ISA:
842                 *flags &= ~IOART_INTALO;        /* *flags |= IOART_INTAHI */
843                 return;
844
845         case EISA:
846                 /* polarity converter always gives active high */
847                 *flags &= ~IOART_INTALO;
848                 return;
849
850         case PCI:
851                 *flags |= IOART_INTALO;
852                 return;
853
854         case -1:
855         default:
856                 goto bad;
857         }
858
859 bad:
860         panic("bad APIC IO INT flags");
861 }
862
863
864 /*
865  * Print contents of unmasked IRQs.
866  */
867 void
868 imen_dump(void)
869 {
870         int x;
871
872         kprintf("SMP: enabled INTs: ");
873         for (x = 0; x < APIC_INTMAPSIZE; ++x) {
874                 if ((int_to_apicintpin[x].flags & IOAPIC_IM_FLAG_MASKED) == 0)
875                         kprintf("%d ", x);
876         }
877         kprintf("\n");
878 }
879
880
881 /*
882  * Inter Processor Interrupt functions.
883  */
884
885 #endif  /* SMP APIC-IO */
886
887 /*
888  * Send APIC IPI 'vector' to 'destType' via 'deliveryMode'.
889  *
890  *  destType is 1 of: APIC_DEST_SELF, APIC_DEST_ALLISELF, APIC_DEST_ALLESELF
891  *  vector is any valid SYSTEM INT vector
892  *  delivery_mode is 1 of: APIC_DELMODE_FIXED, APIC_DELMODE_LOWPRIO
893  *
894  * A backlog of requests can create a deadlock between cpus.  To avoid this
895  * we have to be able to accept IPIs at the same time we are trying to send
896  * them.  The critical section prevents us from attempting to send additional
897  * IPIs reentrantly, but also prevents IPIQ processing so we have to call
898  * lwkt_process_ipiq() manually.  It's rather messy and expensive for this
899  * to occur but fortunately it does not happen too often.
900  */
901 int
902 apic_ipi(int dest_type, int vector, int delivery_mode)
903 {
904         u_long  icr_lo;
905
906         crit_enter();
907         if ((lapic->icr_lo & APIC_DELSTAT_MASK) != 0) {
908             unsigned long rflags = read_rflags();
909             cpu_enable_intr();
910             DEBUG_PUSH_INFO("apic_ipi");
911             while ((lapic->icr_lo & APIC_DELSTAT_MASK) != 0) {
912                 lwkt_process_ipiq();
913             }
914             DEBUG_POP_INFO();
915             write_rflags(rflags);
916         }
917
918         icr_lo = (lapic->icr_lo & APIC_ICRLO_RESV_MASK) | dest_type | 
919                 delivery_mode | vector;
920         lapic->icr_lo = icr_lo;
921         crit_exit();
922         return 0;
923 }
924
925 void
926 single_apic_ipi(int cpu, int vector, int delivery_mode)
927 {
928         u_long  icr_lo;
929         u_long  icr_hi;
930
931         crit_enter();
932         if ((lapic->icr_lo & APIC_DELSTAT_MASK) != 0) {
933             unsigned long rflags = read_rflags();
934             cpu_enable_intr();
935             DEBUG_PUSH_INFO("single_apic_ipi");
936             while ((lapic->icr_lo & APIC_DELSTAT_MASK) != 0) {
937                 lwkt_process_ipiq();
938             }
939             DEBUG_POP_INFO();
940             write_rflags(rflags);
941         }
942         icr_hi = lapic->icr_hi & ~APIC_ID_MASK;
943         icr_hi |= (CPU_TO_ID(cpu) << 24);
944         lapic->icr_hi = icr_hi;
945
946         /* build ICR_LOW */
947         icr_lo = (lapic->icr_lo & APIC_ICRLO_RESV_MASK)
948             | APIC_DEST_DESTFLD | delivery_mode | vector;
949
950         /* write APIC ICR */
951         lapic->icr_lo = icr_lo;
952         crit_exit();
953 }
954
955 #if 0   
956
957 /*
958  * Returns 0 if the apic is busy, 1 if we were able to queue the request.
959  *
960  * NOT WORKING YET!  The code as-is may end up not queueing an IPI at all
961  * to the target, and the scheduler does not 'poll' for IPI messages.
962  */
963 int
964 single_apic_ipi_passive(int cpu, int vector, int delivery_mode)
965 {
966         u_long  icr_lo;
967         u_long  icr_hi;
968
969         crit_enter();
970         if ((lapic->icr_lo & APIC_DELSTAT_MASK) != 0) {
971             crit_exit();
972             return(0);
973         }
974         icr_hi = lapic->icr_hi & ~APIC_ID_MASK;
975         icr_hi |= (CPU_TO_ID(cpu) << 24);
976         lapic->icr_hi = icr_hi;
977
978         /* build IRC_LOW */
979         icr_lo = (lapic->icr_lo & APIC_RESV2_MASK)
980             | APIC_DEST_DESTFLD | delivery_mode | vector;
981
982         /* write APIC ICR */
983         lapic->icr_lo = icr_lo;
984         crit_exit();
985         return(1);
986 }
987
988 #endif
989
990 /*
991  * Send APIC IPI 'vector' to 'target's via 'delivery_mode'.
992  *
993  * target is a bitmask of destination cpus.  Vector is any
994  * valid system INT vector.  Delivery mode may be either
995  * APIC_DELMODE_FIXED or APIC_DELMODE_LOWPRIO.
996  */
997 void
998 selected_apic_ipi(cpumask_t target, int vector, int delivery_mode)
999 {
1000         crit_enter();
1001         while (target) {
1002                 int n = BSFCPUMASK(target);
1003                 target &= ~CPUMASK(n);
1004                 single_apic_ipi(n, vector, delivery_mode);
1005         }
1006         crit_exit();
1007 }
1008
1009 /*
1010  * Timer code, in development...
1011  *  - suggested by rgrimes@gndrsh.aac.dev.com
1012  */
1013 int
1014 get_apic_timer_frequency(void)
1015 {
1016         return(lapic_cputimer_intr.freq);
1017 }
1018
1019 /*
1020  * Load a 'downcount time' in uSeconds.
1021  */
1022 void
1023 set_apic_timer(int us)
1024 {
1025         u_int count;
1026
1027         /*
1028          * When we reach here, lapic timer's frequency
1029          * must have been calculated as well as the
1030          * divisor (lapic->dcr_timer is setup during the
1031          * divisor calculation).
1032          */
1033         KKASSERT(lapic_cputimer_intr.freq != 0 &&
1034                  lapic_timer_divisor_idx >= 0);
1035
1036         count = ((us * (int64_t)lapic_cputimer_intr.freq) + 999999) / 1000000;
1037         lapic_timer_oneshot(count);
1038 }
1039
1040
1041 /*
1042  * Read remaining time in timer.
1043  */
1044 int
1045 read_apic_timer(void)
1046 {
1047 #if 0
1048         /** XXX FIXME: we need to return the actual remaining time,
1049          *         for now we just return the remaining count.
1050          */
1051 #else
1052         return lapic->ccr_timer;
1053 #endif
1054 }
1055
1056
1057 /*
1058  * Spin-style delay, set delay time in uS, spin till it drains.
1059  */
1060 void
1061 u_sleep(int count)
1062 {
1063         set_apic_timer(count);
1064         while (read_apic_timer())
1065                  /* spin */ ;
1066 }
1067
1068 void
1069 lapic_map(vm_offset_t lapic_addr)
1070 {
1071         lapic = pmap_mapdev_uncacheable(lapic_addr, sizeof(struct LAPIC));
1072
1073         kprintf("lapic: at 0x%08lx\n", lapic_addr);
1074 }
1075
1076 static TAILQ_HEAD(, lapic_enumerator) lapic_enumerators =
1077         TAILQ_HEAD_INITIALIZER(lapic_enumerators);
1078
1079 void
1080 lapic_config(void)
1081 {
1082         struct lapic_enumerator *e;
1083         int error;
1084
1085         TAILQ_FOREACH(e, &lapic_enumerators, lapic_link) {
1086                 error = e->lapic_probe(e);
1087                 if (!error)
1088                         break;
1089         }
1090         if (e == NULL)
1091                 panic("can't config lapic\n");
1092
1093         e->lapic_enumerate(e);
1094 }
1095
1096 void
1097 lapic_enumerator_register(struct lapic_enumerator *ne)
1098 {
1099         struct lapic_enumerator *e;
1100
1101         TAILQ_FOREACH(e, &lapic_enumerators, lapic_link) {
1102                 if (e->lapic_prio < ne->lapic_prio) {
1103                         TAILQ_INSERT_BEFORE(e, ne, lapic_link);
1104                         return;
1105                 }
1106         }
1107         TAILQ_INSERT_TAIL(&lapic_enumerators, ne, lapic_link);
1108 }