Merge from vendor branch TCPDUMP:
[dragonfly.git] / sys / i386 / acpica5 / madt.c
1 /*-
2  * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org>
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. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the author nor the names of any co-contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD: src/sys/i386/acpica/madt.c,v 1.10 2004/01/26 19:34:24 jhb Exp $
30  * $DragonFly: src/sys/i386/acpica5/Attic/madt.c,v 1.1 2004/02/21 06:48:05 dillon Exp $
31  */
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/bus.h>
36 #include <sys/kernel.h>
37 #include <sys/malloc.h>
38 #include <sys/globaldata.h>
39
40 #include <vm/vm.h>
41 #include <vm/vm_param.h>
42 #include <vm/pmap.h>
43
44 #include <machine/apicreg.h>
45 #include <machine/frame.h>
46 /*#include <machine/intr_machdep.h>*/
47 #include <machine/md_var.h>
48 #include <machine/apicvar.h>
49 #include <machine/specialreg.h>
50 #include <machine/smp.h>
51 #include <machine/globaldata.h>
52
53 #include "acpi.h"
54 #include "acpivar.h"
55 #include <bus/pci/pcivar.h>
56
57 #define NIOAPICS                32      /* Max number of I/O APICs */
58 #define NLAPICS                 32      /* Max number of local APICs */
59
60 typedef struct {
61         APIC_HEADER_DEF
62 } APIC_HEADER;
63
64
65 typedef void madt_entry_handler(APIC_HEADER *entry, void *arg);
66
67 /* These two arrays are indexed by APIC IDs. */
68 struct ioapic_info {
69         void *io_apic;
70         UINT32 io_vector;
71 } ioapics[NIOAPICS];
72
73 struct lapic_info {
74         u_int la_present:1;
75         u_int la_enabled:1;
76         u_int la_apic_id:8;
77 } lapics[NLAPICS + 1];
78
79 static MULTIPLE_APIC_TABLE *madt;
80 static vm_paddr_t madt_physaddr;
81 static vm_offset_t madt_length;
82
83 MALLOC_DEFINE(M_MADT, "MADT Table", "ACPI MADT Table Items");
84
85 static u_char   interrupt_polarity(UINT16 Polarity);
86 static u_char   interrupt_trigger(UINT16 TriggerMode);
87 static int      madt_find_cpu(u_int acpi_id, u_int *apic_id);
88 static int      madt_find_interrupt(int intr, void **apic, u_int *pin);
89 static void     *madt_map(vm_paddr_t pa, int offset, vm_offset_t length);
90 static void     *madt_map_table(vm_paddr_t pa, int offset, const char *sig);
91 static void     madt_parse_apics(APIC_HEADER *entry, void *arg);
92 static void     madt_parse_interrupt_override(MADT_INTERRUPT_OVERRIDE *intr);
93 static void     madt_parse_ints(APIC_HEADER *entry, void *arg __unused);
94 static void     madt_parse_local_nmi(MADT_LOCAL_APIC_NMI *nmi);
95 static void     madt_parse_nmi(MADT_NMI_SOURCE *nmi);
96 static int      madt_probe(void);
97 static int      madt_probe_cpus(void);
98 static void     madt_probe_cpus_handler(APIC_HEADER *entry, void *arg __unused);
99 static int      madt_probe_table(vm_paddr_t address);
100 static void     madt_register(void *dummy);
101 static int      madt_setup_local(void);
102 static int      madt_setup_io(void);
103 static void     madt_unmap(void *data, vm_offset_t length);
104 static void     madt_unmap_table(void *table);
105 static void     madt_walk_table(madt_entry_handler *handler, void *arg);
106
107 static struct apic_enumerator madt_enumerator = {
108         "MADT",
109         madt_probe,
110         madt_probe_cpus,
111         madt_setup_local,
112         madt_setup_io
113 };
114
115 /*
116  * Code to abuse the crashdump map to map in the tables for the early
117  * probe.  We cheat and make the following assumptions about how we
118  * use this KVA: page 0 is used to map in the first page of each table
119  * found via the RSDT or XSDT and pages 1 to n are used to map in the
120  * RSDT or XSDT.  The offset is in pages; the length is in bytes.
121  */
122 static void *
123 madt_map(vm_paddr_t pa, int offset, vm_offset_t length)
124 {
125         vm_offset_t va, off;
126         void *data;
127
128         off = pa & PAGE_MASK;
129         length = roundup(length + off, PAGE_SIZE);
130         pa = pa & PG_FRAME;
131         va = (vm_offset_t)pmap_kenter_temporary(pa, offset) +
132             (offset * PAGE_SIZE);
133         data = (void *)(va + off);
134         length -= PAGE_SIZE;
135         while (length > 0) {
136                 va += PAGE_SIZE;
137                 pa += PAGE_SIZE;
138                 length -= PAGE_SIZE;
139                 pmap_kenter(va, pa);
140                 cpu_invlpg((void *)va);
141         }
142         return (data);
143 }
144
145 static void
146 madt_unmap(void *data, vm_offset_t length)
147 {
148         vm_offset_t va, off;
149
150         va = (vm_offset_t)data;
151         off = va & PAGE_MASK;
152         length = roundup(length + off, PAGE_SIZE);
153         va &= ~PAGE_MASK;
154         while (length > 0) {
155                 pmap_kremove(va);
156                 cpu_invlpg((void *)va);
157                 va += PAGE_SIZE;
158                 length -= PAGE_SIZE;
159         }
160 }
161
162 static void *
163 madt_map_table(vm_paddr_t pa, int offset, const char *sig)
164 {
165         ACPI_TABLE_HEADER *header;
166         vm_offset_t length;
167
168         header = madt_map(pa, offset, sizeof(ACPI_TABLE_HEADER));
169         if (strncmp(header->Signature, sig, 4) != 0) {
170                 madt_unmap(header, sizeof(ACPI_TABLE_HEADER));
171                 return (NULL);
172         }
173         length = header->Length;
174         madt_unmap(header, sizeof(ACPI_TABLE_HEADER));
175         return (madt_map(pa, offset, length));
176 }
177
178 static void
179 madt_unmap_table(void *table)
180 {
181         ACPI_TABLE_HEADER *header;
182
183         header = (ACPI_TABLE_HEADER *)table;
184         madt_unmap(table, header->Length);
185 }
186
187 /*
188  * Look for an ACPI Multiple APIC Description Table ("APIC")
189  */
190 static int
191 madt_probe(void)
192 {
193         ACPI_POINTER rsdp_ptr;
194         RSDP_DESCRIPTOR *rsdp;
195         RSDT_DESCRIPTOR *rsdt;
196         XSDT_DESCRIPTOR *xsdt;
197         int i, count;
198
199 #if 0
200         if (resource_disabled("acpi", 0))
201                 return (ENXIO);
202 #endif
203
204         /*
205          * Map in the RSDP.  Since ACPI uses AcpiOsMapMemory() which in turn
206          * calls pmap_mapdev() to find the RSDP, we assume that we can use
207          * pmap_mapdev() to map the RSDP.
208          */
209         if (AcpiOsGetRootPointer(ACPI_LOGICAL_ADDRESSING, &rsdp_ptr) != AE_OK)
210                 return (ENXIO);
211 #ifdef __i386__
212         KASSERT(rsdp_ptr.Pointer.Physical < KERNLOAD, ("RSDP too high"));
213 #endif
214         rsdp = pmap_mapdev(rsdp_ptr.Pointer.Physical, sizeof(RSDP_DESCRIPTOR));
215         if (rsdp == NULL) {
216                 if (bootverbose)
217                         printf("MADT: Failed to map RSDP\n");
218                 return (ENXIO);
219         }
220
221         /*
222          * For ACPI < 2.0, use the RSDT.  For ACPI >= 2.0, use the XSDT.
223          * We map the XSDT and RSDT at page 1 in the crashdump area.
224          * Page 0 is used to map in the headers of candidate ACPI tables.
225          */
226         if (rsdp->Revision >= 2) {
227                 xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 1, XSDT_SIG);
228                 if (xsdt == NULL) {
229                         if (bootverbose)
230                                 printf("MADT: Failed to map XSDT\n");
231                         return (ENXIO);
232                 }
233                 count = (xsdt->Length - sizeof(ACPI_TABLE_HEADER)) /
234                     sizeof(UINT64);
235                 for (i = 0; i < count; i++)
236                         if (madt_probe_table(xsdt->TableOffsetEntry[i]))
237                                 break;
238                 madt_unmap_table(xsdt);
239         } else {
240                 rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 1, RSDT_SIG);
241                 if (rsdt == NULL) {
242                         if (bootverbose)
243                                 printf("MADT: Failed to map RSDT\n");
244                         return (ENXIO);
245                 }
246                 count = (rsdt->Length - sizeof(ACPI_TABLE_HEADER)) /
247                     sizeof(UINT32);
248                 for (i = 0; i < count; i++)
249                         if (madt_probe_table(rsdt->TableOffsetEntry[i]))
250                                 break;
251                 madt_unmap_table(rsdt);
252         }
253         pmap_unmapdev((vm_offset_t)rsdp, sizeof(RSDP_DESCRIPTOR));
254         if (madt_physaddr == 0) {
255                 if (bootverbose)
256                         printf("MADT: No MADT table found\n");
257                 return (ENXIO);
258         }
259         if (bootverbose)
260                 printf("MADT: Found table at 0x%jx\n",
261                     (uintmax_t)madt_physaddr);
262
263         return (0);
264 }
265
266 /*
267  * See if a given ACPI table is the MADT.
268  */
269 static int
270 madt_probe_table(vm_paddr_t address)
271 {
272         ACPI_TABLE_HEADER *table;
273
274         table = madt_map(address, 0, sizeof(ACPI_TABLE_HEADER));
275         if (table == NULL) {
276                 if (bootverbose)
277                         printf("MADT: Failed to map table at 0x%jx\n",
278                             (uintmax_t)address);
279                 return (0);
280         }
281         if (bootverbose)
282                 printf("Table '%.4s' at 0x%jx\n", table->Signature,
283                     (uintmax_t)address);
284
285         /* XXX: Verify checksum? */
286         if (strncmp(table->Signature, APIC_SIG, 4) != 0) {
287                 madt_unmap(table, sizeof(ACPI_TABLE_HEADER));
288                 return (0);
289         }
290         madt_physaddr = address;
291         madt_length = table->Length;
292         madt_unmap(table, sizeof(ACPI_TABLE_HEADER));
293         return (1);
294 }
295
296 /*
297  * Run through the MP table enumerating CPUs.
298  */
299 static int
300 madt_probe_cpus(void)
301 {
302
303         madt = madt_map_table(madt_physaddr, 0, APIC_SIG);
304         KASSERT(madt != NULL, ("Unable to re-map MADT"));
305         madt_walk_table(madt_probe_cpus_handler, NULL);
306         madt_unmap_table(madt);
307         madt = NULL;
308         return (0);
309 }
310
311 /*
312  * Initialize the local APIC on the BSP.
313  */
314 static int
315 madt_setup_local(void)
316 {
317
318         madt = pmap_mapdev(madt_physaddr, madt_length);
319         lapic_init((uintptr_t)madt->LocalApicAddress);
320         printf("ACPI APIC Table: <%.*s %.*s>\n",
321             (int)sizeof(madt->OemId), madt->OemId,
322             (int)sizeof(madt->OemTableId), madt->OemTableId);
323
324         /*
325          * We ignore 64-bit local APIC override entries.  Should we
326          * perhaps emit a warning here if we find one?
327          */
328         return (0);
329 }
330
331 /*
332  * Enumerate I/O APICs and setup interrupt sources.
333  */
334 static int
335 madt_setup_io(void)
336 {
337         int i;
338
339         /* Try to initialize ACPI so that we can access the FADT. */
340         i = acpi_Startup();
341         if (ACPI_FAILURE(i)) {
342                 printf("MADT: ACPI Startup failed with %s\n",
343                     AcpiFormatException(i));
344                 printf("Try disabling either ACPI or apic support.\n");
345                 panic("Using MADT but ACPI doesn't work");
346         }
347                     
348         /* First, we run through adding I/O APIC's. */
349         madt_walk_table(madt_parse_apics, NULL);
350
351         /* Second, we run through the table tweaking interrupt sources. */
352         madt_walk_table(madt_parse_ints, NULL);
353
354         /* Third, we register all the I/O APIC's. */
355         for (i = 0; i < NIOAPICS; i++)
356                 if (ioapics[i].io_apic != NULL)
357                         ioapic_register(ioapics[i].io_apic);
358
359         /* Finally, we throw the switch to enable the I/O APIC's. */
360         acpi_SetDefaultIntrModel(ACPI_INTR_APIC);
361
362         return (0);
363 }
364
365 static void
366 madt_register(void *dummy __unused)
367 {
368
369         apic_register_enumerator(&madt_enumerator);
370 }
371 SYSINIT(madt_register, SI_SUB_CPU - 1, SI_ORDER_FIRST, madt_register, NULL)
372
373 /*
374  * Call the handler routine for each entry in the MADT table.
375  */
376 static void
377 madt_walk_table(madt_entry_handler *handler, void *arg)
378 {
379         APIC_HEADER *entry;
380         u_char *p, *end;
381
382         end = (u_char *)(madt) + madt->Length;
383         for (p = (u_char *)(madt + 1); p < end; ) {
384                 entry = (APIC_HEADER *)p;
385                 handler(entry, arg);
386                 p += entry->Length;
387         }
388 }
389
390 static void
391 madt_probe_cpus_handler(APIC_HEADER *entry, void *arg)
392 {
393         MADT_PROCESSOR_APIC *proc;
394         struct lapic_info *la;
395
396         switch (entry->Type) {
397         case APIC_PROCESSOR:
398                 /*
399                  * The MADT does not include a BSP flag, so we have to
400                  * let the MP code figure out which CPU is the BSP on
401                  * its own.
402                  */
403                 proc = (MADT_PROCESSOR_APIC *)entry;
404                 if (bootverbose)
405                         printf("MADT: Found CPU APIC ID %d ACPI ID %d: %s\n",
406                             proc->LocalApicId, proc->ProcessorId,
407                             proc->ProcessorEnabled ? "enabled" : "disabled");
408                 if (proc->ProcessorId > NLAPICS)
409                         panic("%s: CPU ID %d too high", __func__,
410                             proc->ProcessorId);
411                 la = &lapics[proc->ProcessorId];
412                 KASSERT(la->la_present == 0,
413                     ("Duplicate local ACPI ID %d", proc->ProcessorId));
414                 la->la_present = 1;
415                 la->la_apic_id = proc->LocalApicId;
416                 if (proc->ProcessorEnabled) {
417                         la->la_enabled = 1;
418                         lapic_create(proc->LocalApicId, 0);
419                 }
420                 break;
421         }
422 }
423
424
425 /*
426  * Add an I/O APIC from an entry in the table.
427  */
428 static void
429 madt_parse_apics(APIC_HEADER *entry, void *arg __unused)
430 {
431         MADT_IO_APIC *apic;
432
433         switch (entry->Type) {
434         case APIC_IO:
435                 apic = (MADT_IO_APIC *)entry;
436                 if (bootverbose)
437                         printf("MADT: Found IO APIC ID %d, Interrupt %d at %p\n",
438                             apic->IoApicId, apic->Interrupt,
439                             (void *)(uintptr_t)apic->Address);
440                 if (apic->IoApicId >= NIOAPICS)
441                         panic("%s: I/O APIC ID %d too high", __func__,
442                             apic->IoApicId);
443                 if (ioapics[apic->IoApicId].io_apic != NULL)
444                         panic("%s: Double APIC ID %d", __func__,
445                             apic->IoApicId);
446                 ioapics[apic->IoApicId].io_apic = ioapic_create(
447                         (uintptr_t)apic->Address, apic->IoApicId,
448                             apic->Interrupt);
449                 ioapics[apic->IoApicId].io_vector = apic->Interrupt;
450                 break;
451         default:
452                 break;
453         }
454 }
455
456 /*
457  * Determine properties of an interrupt source.  Note that for ACPI,
458  * these are only used for ISA interrupts, so we assume ISA bus values
459  * (Active Hi, Edge Triggered) for conforming values.
460  */
461 static u_char
462 interrupt_polarity(UINT16 Polarity)
463 {
464
465         switch (Polarity) {
466         case POLARITY_CONFORMS:
467         case POLARITY_ACTIVE_HIGH:
468                 return (1);
469         case POLARITY_ACTIVE_LOW:
470                 return (0);
471         default:
472                 panic("Bogus Interrupt Polarity");
473         }
474 }
475
476 static u_char
477 interrupt_trigger(UINT16 TriggerMode)
478 {
479
480         switch (TriggerMode) {
481         case TRIGGER_CONFORMS:
482         case TRIGGER_EDGE:
483                 return (1);
484         case TRIGGER_LEVEL:
485                 return (0);
486         default:
487                 panic("Bogus Interrupt Trigger Mode");
488         }
489 }
490
491 /*
492  * Find the local APIC ID associated with a given ACPI Processor ID.
493  */
494 static int
495 madt_find_cpu(u_int acpi_id, u_int *apic_id)
496 {
497
498         if (!lapics[acpi_id].la_present)
499                 return (ENOENT);
500         *apic_id = lapics[acpi_id].la_apic_id;
501         if (lapics[acpi_id].la_enabled)
502                 return (0);
503         else
504                 return (ENXIO);
505 }
506
507 /*
508  * Find the IO APIC and pin on that APIC associated with a given global
509  * interrupt.
510  */
511 static int
512 madt_find_interrupt(int intr, void **apic, u_int *pin)
513 {
514         int i, best;
515
516         best = -1;
517         for (i = 0; i < NIOAPICS; i++) {
518                 if (ioapics[i].io_apic == NULL ||
519                     ioapics[i].io_vector > intr)
520                         continue;
521                 if (best == -1 ||
522                     ioapics[best].io_vector < ioapics[i].io_vector)
523                         best = i;
524         }
525         if (best == -1)
526                 return (ENOENT);
527         *apic = ioapics[best].io_apic;
528         *pin = intr - ioapics[best].io_vector;
529         if (*pin > 32)
530                 printf("WARNING: Found intpin of %u for vector %d\n", *pin,
531                     intr);
532         return (0);
533 }
534
535 /*
536  * Parse an interrupt source override for an ISA interrupt.
537  */
538 static void
539 madt_parse_interrupt_override(MADT_INTERRUPT_OVERRIDE *intr)
540 {
541         void *new_ioapic, *old_ioapic;
542         u_int new_pin, old_pin;
543         int force_lo;
544
545         if (bootverbose)
546                 printf("MADT: intr override: source %u, irq %u\n",
547                     intr->Source, intr->Interrupt);
548         KASSERT(intr->Bus == 0, ("bus for interrupt overrides must be zero"));
549         if (madt_find_interrupt(intr->Interrupt, &new_ioapic,
550             &new_pin) != 0) {
551                 printf("MADT: Could not find APIC for vector %d (IRQ %d)\n",
552                     intr->Interrupt, intr->Source);
553                 return;
554         }
555
556         /*
557          * If the SCI is remapped to a non-ISA global interrupt,
558          * force it to level trigger and active-lo polarity.
559          * If the SCI is identity mapped but has edge trigger and
560          * active-hi polarity, also force it to use level/lo. 
561          */
562         force_lo = 0;
563         if (intr->Source == AcpiGbl_FADT->SciInt)
564                 if (intr->Interrupt > 15 || (intr->Interrupt == intr->Source &&
565                     intr->TriggerMode == TRIGGER_EDGE &&
566                     intr->Polarity == POLARITY_ACTIVE_HIGH))
567                         force_lo = 1;
568
569         if (intr->Source != intr->Interrupt) {
570                 /*
571                  * If the SCI is remapped to a non-ISA global interrupt,
572                  * then override the vector we use to setup and allocate
573                  * the interrupt.
574                  */
575                 if (intr->Interrupt > 15 &&
576                     intr->Source == AcpiGbl_FADT->SciInt)
577                         acpi_OverrideInterruptLevel(intr->Interrupt);
578                 else
579                         ioapic_remap_vector(new_ioapic, new_pin, intr->Source);
580                 if (madt_find_interrupt(intr->Source, &old_ioapic,
581                     &old_pin) != 0)
582                         printf("MADT: Could not find APIC for source IRQ %d\n",
583                             intr->Source);
584                 else if (ioapic_get_vector(old_ioapic, old_pin) ==
585                     intr->Source)
586                         ioapic_disable_pin(old_ioapic, old_pin);
587         }
588         if (force_lo) {
589                 printf(
590         "MADT: Forcing active-lo polarity and level trigger for IRQ %d\n",
591                     intr->Source);
592                 ioapic_set_polarity(new_ioapic, new_pin, 0);
593                 ioapic_set_triggermode(new_ioapic, new_pin, 0);
594         } else {
595                 ioapic_set_polarity(new_ioapic, new_pin,
596                     interrupt_polarity(intr->Polarity));
597                 ioapic_set_triggermode(new_ioapic, new_pin,
598                     interrupt_trigger(intr->TriggerMode));
599         }
600 }
601
602 /*
603  * Parse an entry for an NMI routed to an IO APIC.
604  */
605 static void
606 madt_parse_nmi(MADT_NMI_SOURCE *nmi)
607 {
608         void *ioapic;
609         u_int pin;
610
611         if (madt_find_interrupt(nmi->Interrupt, &ioapic, &pin) != 0) {
612                 printf("MADT: Could not find APIC for vector %d\n",
613                     nmi->Interrupt);
614                 return;
615         }
616
617         ioapic_set_nmi(ioapic, pin);
618         if (nmi->TriggerMode != TRIGGER_CONFORMS)
619                 ioapic_set_triggermode(ioapic, pin,
620                     interrupt_trigger(nmi->TriggerMode));
621         if (nmi->Polarity != TRIGGER_CONFORMS)
622                 ioapic_set_polarity(ioapic, pin,
623                     interrupt_polarity(nmi->Polarity));
624 }
625
626 /*
627  * Parse an entry for an NMI routed to a local APIC LVT pin.
628  */
629 static void
630 madt_parse_local_nmi(MADT_LOCAL_APIC_NMI *nmi)
631 {
632         u_int apic_id, pin;
633
634         if (nmi->ProcessorId == 0xff)
635                 apic_id = APIC_ID_ALL;
636         else if (madt_find_cpu(nmi->ProcessorId, &apic_id) != 0) {
637                 if (bootverbose)
638                         printf("MADT: Ignoring local NMI routed to ACPI CPU %u\n",
639                             nmi->ProcessorId);
640                 return;
641         }
642         if (nmi->Lint == 0)
643                 pin = LVT_LINT0;
644         else
645                 pin = LVT_LINT1;
646         lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_NMI);
647         if (nmi->TriggerMode != TRIGGER_CONFORMS)
648                 lapic_set_lvt_triggermode(apic_id, pin,
649                     interrupt_trigger(nmi->TriggerMode));
650         if (nmi->Polarity != POLARITY_CONFORMS)
651                 lapic_set_lvt_polarity(apic_id, pin,
652                     interrupt_polarity(nmi->Polarity));
653 }
654
655 /*
656  * Parse interrupt entries.
657  */
658 static void
659 madt_parse_ints(APIC_HEADER *entry, void *arg __unused)
660 {
661
662         switch (entry->Type) {
663         case APIC_XRUPT_OVERRIDE:
664                 madt_parse_interrupt_override(
665                         (MADT_INTERRUPT_OVERRIDE *)entry);
666                 break;
667         case APIC_NMI:
668                 madt_parse_nmi((MADT_NMI_SOURCE *)entry);
669                 break;
670         case APIC_LOCAL_NMI:
671                 madt_parse_local_nmi((MADT_LOCAL_APIC_NMI *)entry);
672                 break;
673         }
674 }
675
676 /*
677  * Setup per-CPU ACPI IDs.
678  */
679 static void
680 madt_set_ids(void *dummy)
681 {
682         struct mdglobaldata *md;
683         u_int i, j;
684
685         if (madt == NULL)
686                 return;
687         for (i = 0; i < ncpus; i++) {
688                 if ((smp_active_mask & (1 << i)) == 0)
689                         continue;
690                 md = (struct mdglobaldata *)globaldata_find(i);
691                 KKASSERT(md != NULL);
692                 for (j = 0; j < NLAPICS + 1; j++) {
693                         if (!lapics[j].la_present || !lapics[j].la_enabled)
694                                 continue;
695                         if (lapics[j].la_apic_id == md->gd_apic_id) {
696                                 md->gd_acpi_id = j;
697                                 if (bootverbose)
698                                         printf("APIC: CPU %u has ACPI ID %u\n",
699                                             i, j);
700                                 break;
701                         }
702                 }
703                 if (j == NLAPICS + 1)
704                         panic("Unable to find ACPI ID for CPU %d", i);
705         }
706 }
707 SYSINIT(madt_set_ids, SI_SUB_CPU, SI_ORDER_ANY, madt_set_ids, NULL)