AMD64 - Enable module building, sync i386 headers etc as needed.
[dragonfly.git] / sys / platform / pc64 / 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.17 2004/06/10 20:03:46 jhb Exp $
30  * $DragonFly: src/sys/platform/pc32/acpica5/madt.c,v 1.9 2007/04/30 07:18:55 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_base/apic/apicreg.h>
45 #include <machine/frame.h>
46 /*#include <machine/intr_machdep.h>*/
47 #include <machine/md_var.h>
48 #include <machine_base/apic/apicvar.h>
49 #include <machine/specialreg.h>
50 #include <machine/smp.h>
51 #include <machine/globaldata.h>
52
53 #include "acpi.h"
54 #include "actables.h"
55 #include "acpivar.h"
56 #include <bus/pci/pcivar.h>
57
58 #define NIOAPICS                32      /* Max number of I/O APICs */
59 #define NLAPICS                 32      /* Max number of local APICs */
60
61 typedef void madt_entry_handler(APIC_HEADER *entry, void *arg);
62
63 /* These two arrays are indexed by APIC IDs. */
64 struct ioapic_info {
65         void *io_apic;
66         UINT32 io_vector;
67 } ioapics[NIOAPICS];
68
69 struct lapic_info {
70         u_int la_enabled:1;
71         u_int la_acpi_id:8;
72 } lapics[NLAPICS];
73
74 static int madt_found_sci_override;
75 static MULTIPLE_APIC_TABLE *madt;
76 static vm_paddr_t madt_physaddr;
77 static vm_offset_t madt_length;
78
79 MALLOC_DEFINE(M_MADT, "MADT Table", "ACPI MADT Table Items");
80
81 static enum intr_polarity interrupt_polarity(UINT16 Polarity, UINT8 Source);
82 static enum intr_trigger interrupt_trigger(UINT16 TriggerMode, UINT8 Source);
83 static int      madt_find_cpu(u_int acpi_id, u_int *apic_id);
84 static int      madt_find_interrupt(int intr, void **apic, u_int *pin);
85 static void     *madt_map(vm_paddr_t pa, int offset, vm_offset_t length);
86 static void     *madt_map_table(vm_paddr_t pa, int offset, const char *sig);
87 static void     madt_parse_apics(APIC_HEADER *entry, void *arg);
88 static void     madt_parse_interrupt_override(MADT_INTERRUPT_OVERRIDE *intr);
89 static void     madt_parse_ints(APIC_HEADER *entry, void *arg __unused);
90 static void     madt_parse_local_nmi(MADT_LOCAL_APIC_NMI *nmi);
91 static void     madt_parse_nmi(MADT_NMI_SOURCE *nmi);
92 static int      madt_probe(void);
93 static int      madt_probe_cpus(void);
94 static void     madt_probe_cpus_handler(APIC_HEADER *entry, void *arg __unused);
95 static int      madt_probe_table(vm_paddr_t address);
96 static void     madt_register(void *dummy);
97 static int      madt_setup_local(void);
98 static int      madt_setup_io(void);
99 static void     madt_unmap(void *data, vm_offset_t length);
100 static void     madt_unmap_table(void *table);
101 static void     madt_walk_table(madt_entry_handler *handler, void *arg);
102
103 static struct apic_enumerator madt_enumerator = {
104         "MADT",
105         madt_probe,
106         madt_probe_cpus,
107         madt_setup_local,
108         madt_setup_io
109 };
110
111 /*
112  * Code to abuse the crashdump map to map in the tables for the early
113  * probe.  We cheat and make the following assumptions about how we
114  * use this KVA: page 0 is used to map in the first page of each table
115  * found via the RSDT or XSDT and pages 1 to n are used to map in the
116  * RSDT or XSDT.  The offset is in pages; the length is in bytes.
117  */
118 static void *
119 madt_map(vm_paddr_t pa, int offset, vm_offset_t length)
120 {
121         vm_offset_t va, off;
122         void *data;
123
124         off = pa & PAGE_MASK;
125         length = roundup(length + off, PAGE_SIZE);
126         pa = pa & PG_FRAME;
127         va = (vm_offset_t)pmap_kenter_temporary(pa, offset) +
128             (offset * PAGE_SIZE);
129         data = (void *)(va + off);
130         length -= PAGE_SIZE;
131         while (length > 0) {
132                 va += PAGE_SIZE;
133                 pa += PAGE_SIZE;
134                 length -= PAGE_SIZE;
135                 pmap_kenter(va, pa);
136                 cpu_invlpg((void *)va);
137         }
138         return (data);
139 }
140
141 static void
142 madt_unmap(void *data, vm_offset_t length)
143 {
144         vm_offset_t va, off;
145
146         va = (vm_offset_t)data;
147         off = va & PAGE_MASK;
148         length = roundup(length + off, PAGE_SIZE);
149         va &= ~PAGE_MASK;
150         while (length > 0) {
151                 pmap_kremove(va);
152                 cpu_invlpg((void *)va);
153                 va += PAGE_SIZE;
154                 length -= PAGE_SIZE;
155         }
156 }
157
158 static void *
159 madt_map_table(vm_paddr_t pa, int offset, const char *sig)
160 {
161         ACPI_TABLE_HEADER *header;
162         vm_offset_t length;
163         void *table;
164
165         header = madt_map(pa, offset, sizeof(ACPI_TABLE_HEADER));
166         if (strncmp(header->Signature, sig, 4) != 0) {
167                 madt_unmap(header, sizeof(ACPI_TABLE_HEADER));
168                 return (NULL);
169         }
170         length = header->Length;
171         madt_unmap(header, sizeof(ACPI_TABLE_HEADER));
172         table = madt_map(pa, offset, length);
173         if (ACPI_FAILURE(AcpiTbVerifyTableChecksum(table))) {
174                 if (bootverbose)
175                         kprintf("MADT: Failed checksum for table %s\n", sig);
176                 madt_unmap(table, length);
177                 return (NULL);
178         }
179         return (table);
180 }
181
182 static void
183 madt_unmap_table(void *table)
184 {
185         ACPI_TABLE_HEADER *header;
186
187         header = (ACPI_TABLE_HEADER *)table;
188         madt_unmap(table, header->Length);
189 }
190
191 /*
192  * Look for an ACPI Multiple APIC Description Table ("APIC")
193  */
194 static int
195 madt_probe(void)
196 {
197         ACPI_POINTER rsdp_ptr;
198         RSDP_DESCRIPTOR *rsdp;
199         RSDT_DESCRIPTOR *rsdt;
200         XSDT_DESCRIPTOR *xsdt;
201         int i, count;
202
203         if (resource_disabled("acpi", 0))
204                 return (ENXIO);
205
206         /*
207          * Map in the RSDP.  Since ACPI uses AcpiOsMapMemory() which in turn
208          * calls pmap_mapdev() to find the RSDP, we assume that we can use
209          * pmap_mapdev() to map the RSDP.
210          */
211         if (AcpiOsGetRootPointer(ACPI_LOGICAL_ADDRESSING, &rsdp_ptr) != AE_OK)
212                 return (ENXIO);
213         rsdp = pmap_mapdev(rsdp_ptr.Pointer.Physical, sizeof(RSDP_DESCRIPTOR));
214         if (rsdp == NULL) {
215                 if (bootverbose)
216                         kprintf("MADT: Failed to map RSDP\n");
217                 return (ENXIO);
218         }
219
220         /*
221          * For ACPI < 2.0, use the RSDT.  For ACPI >= 2.0, use the XSDT.
222          * We map the XSDT and RSDT at page 1 in the crashdump area.
223          * Page 0 is used to map in the headers of candidate ACPI tables.
224          */
225         if (rsdp->Revision >= 2) {
226                 /*
227                  * AcpiOsGetRootPointer only verifies the checksum for
228                  * the version 1.0 portion of the RSDP.  Version 2.0 has
229                  * an additional checksum that we verify first.
230                  */
231                 if (AcpiTbChecksum(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) {
232                         if (bootverbose)
233                                 kprintf("MADT: RSDP failed extended checksum\n");
234                         return (ENXIO);
235                 }
236                 xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 1, XSDT_SIG);
237                 if (xsdt == NULL) {
238                         if (bootverbose)
239                                 kprintf("MADT: Failed to map XSDT\n");
240                         return (ENXIO);
241                 }
242                 count = (xsdt->Length - sizeof(ACPI_TABLE_HEADER)) /
243                     sizeof(UINT64);
244                 for (i = 0; i < count; i++)
245                         if (madt_probe_table(xsdt->TableOffsetEntry[i]))
246                                 break;
247                 madt_unmap_table(xsdt);
248         } else {
249                 rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 1, RSDT_SIG);
250                 if (rsdt == NULL) {
251                         if (bootverbose)
252                                 kprintf("MADT: Failed to map RSDT\n");
253                         return (ENXIO);
254                 }
255                 count = (rsdt->Length - sizeof(ACPI_TABLE_HEADER)) /
256                     sizeof(UINT32);
257                 for (i = 0; i < count; i++)
258                         if (madt_probe_table(rsdt->TableOffsetEntry[i]))
259                                 break;
260                 madt_unmap_table(rsdt);
261         }
262         pmap_unmapdev((vm_offset_t)rsdp, sizeof(RSDP_DESCRIPTOR));
263         if (madt_physaddr == 0) {
264                 if (bootverbose)
265                         kprintf("MADT: No MADT table found\n");
266                 return (ENXIO);
267         }
268         if (bootverbose)
269                 kprintf("MADT: Found table at 0x%jx\n",
270                     (uintmax_t)madt_physaddr);
271
272         /*
273          * Verify that we can map the full table and that its checksum is
274          * correct, etc.
275          */
276         madt = madt_map_table(madt_physaddr, 0, APIC_SIG);
277         if (madt == NULL)
278                 return (ENXIO);
279         madt_unmap_table(madt);
280         madt = NULL;
281
282         return (0);
283 }
284
285 /*
286  * See if a given ACPI table is the MADT.
287  */
288 static int
289 madt_probe_table(vm_paddr_t address)
290 {
291         ACPI_TABLE_HEADER *table;
292
293         table = madt_map(address, 0, sizeof(ACPI_TABLE_HEADER));
294         if (table == NULL) {
295                 if (bootverbose)
296                         kprintf("MADT: Failed to map table at 0x%jx\n",
297                             (uintmax_t)address);
298                 return (0);
299         }
300         if (bootverbose)
301                 kprintf("Table '%.4s' at 0x%jx\n", table->Signature,
302                     (uintmax_t)address);
303
304         if (strncmp(table->Signature, APIC_SIG, 4) != 0) {
305                 madt_unmap(table, sizeof(ACPI_TABLE_HEADER));
306                 return (0);
307         }
308         madt_physaddr = address;
309         madt_length = table->Length;
310         madt_unmap(table, sizeof(ACPI_TABLE_HEADER));
311         return (1);
312 }
313
314 /*
315  * Run through the MP table enumerating CPUs.
316  */
317 static int
318 madt_probe_cpus(void)
319 {
320
321         madt = madt_map_table(madt_physaddr, 0, APIC_SIG);
322         KASSERT(madt != NULL, ("Unable to re-map MADT"));
323         madt_walk_table(madt_probe_cpus_handler, NULL);
324         madt_unmap_table(madt);
325         madt = NULL;
326         return (0);
327 }
328
329 /*
330  * Initialize the local APIC on the BSP.
331  */
332 static int
333 madt_setup_local(void)
334 {
335
336         madt = pmap_mapdev(madt_physaddr, madt_length);
337         lapic_init((uintptr_t)madt->LocalApicAddress);
338         kprintf("ACPI APIC Table: <%.*s %.*s>\n",
339             (int)sizeof(madt->OemId), madt->OemId,
340             (int)sizeof(madt->OemTableId), madt->OemTableId);
341
342         /*
343          * We ignore 64-bit local APIC override entries.  Should we
344          * perhaps emit a warning here if we find one?
345          */
346         return (0);
347 }
348
349 /*
350  * Enumerate I/O APICs and setup interrupt sources.
351  */
352 static int
353 madt_setup_io(void)
354 {
355         void *ioapic;
356         u_int pin;
357         int i;
358
359         /* Try to initialize ACPI so that we can access the FADT. */
360         i = acpi_Startup();
361         if (ACPI_FAILURE(i)) {
362                 kprintf("MADT: ACPI Startup failed with %s\n",
363                     AcpiFormatException(i));
364                 kprintf("Try disabling either ACPI or apic support.\n");
365                 panic("Using MADT but ACPI doesn't work");
366         }
367
368         /* First, we run through adding I/O APIC's. */
369         if (madt->PCATCompat)
370                 ioapic_enable_mixed_mode();
371         madt_walk_table(madt_parse_apics, NULL);
372
373         /* Second, we run through the table tweaking interrupt sources. */
374         madt_walk_table(madt_parse_ints, NULL);
375
376         /*
377          * If there was not an explicit override entry for the SCI,
378          * force it to use level trigger and active-low polarity.
379          */
380         if (!madt_found_sci_override) {
381                 if (madt_find_interrupt(AcpiGbl_FADT->SciInt, &ioapic, &pin)
382                     != 0)
383                         kprintf("MADT: Could not find APIC for SCI IRQ %d\n",
384                             AcpiGbl_FADT->SciInt);
385                 else {
386                         kprintf(
387         "MADT: Forcing active-low polarity and level trigger for SCI\n");
388                         ioapic_set_polarity(ioapic, pin, INTR_POLARITY_LOW);
389                         ioapic_set_triggermode(ioapic, pin, INTR_TRIGGER_LEVEL);
390                 }
391         }
392
393         /* Third, we register all the I/O APIC's. */
394         for (i = 0; i < NIOAPICS; i++)
395                 if (ioapics[i].io_apic != NULL)
396                         ioapic_register(ioapics[i].io_apic);
397
398         /* Finally, we throw the switch to enable the I/O APIC's. */
399         acpi_SetDefaultIntrModel(ACPI_INTR_APIC);
400
401         return (0);
402 }
403
404 /*
405  * Register an enumerator that the SMP startup code might use
406  */
407 static void
408 madt_register(void *dummy __unused)
409 {
410         apic_register_enumerator(&madt_enumerator);
411 }
412 SYSINIT(madt_register, SI_BOOT2_PRESMP, SI_ORDER_FIRST, madt_register, NULL)
413
414 /*
415  * Call the handler routine for each entry in the MADT table.
416  */
417 static void
418 madt_walk_table(madt_entry_handler *handler, void *arg)
419 {
420         APIC_HEADER *entry;
421         u_char *p, *end;
422
423         end = (u_char *)(madt) + madt->Length;
424         for (p = (u_char *)(madt + 1); p < end; ) {
425                 entry = (APIC_HEADER *)p;
426                 handler(entry, arg);
427                 p += entry->Length;
428         }
429 }
430
431 static void
432 madt_probe_cpus_handler(APIC_HEADER *entry, void *arg)
433 {
434         MADT_PROCESSOR_APIC *proc;
435         struct lapic_info *la;
436
437         switch (entry->Type) {
438         case APIC_PROCESSOR:
439                 /*
440                  * The MADT does not include a BSP flag, so we have to
441                  * let the MP code figure out which CPU is the BSP on
442                  * its own.
443                  */
444                 proc = (MADT_PROCESSOR_APIC *)entry;
445                 if (bootverbose)
446                         kprintf("MADT: Found CPU APIC ID %d ACPI ID %d: %s\n",
447                             proc->LocalApicId, proc->ProcessorId,
448                             proc->ProcessorEnabled ? "enabled" : "disabled");
449                 if (!proc->ProcessorEnabled)
450                         break;
451                 if (proc->LocalApicId >= NLAPICS)
452                         panic("%s: CPU ID %d too high", __func__,
453                             proc->LocalApicId);
454                 la = &lapics[proc->LocalApicId];
455                 KASSERT(la->la_enabled == 0,
456                     ("Duplicate local APIC ID %d", proc->LocalApicId));
457                 la->la_enabled = 1;
458                 la->la_acpi_id = proc->ProcessorId;
459                 lapic_create(proc->LocalApicId, 0);
460                 break;
461         }
462 }
463
464
465 /*
466  * Add an I/O APIC from an entry in the table.
467  */
468 static void
469 madt_parse_apics(APIC_HEADER *entry, void *arg __unused)
470 {
471         MADT_IO_APIC *apic;
472
473         switch (entry->Type) {
474         case APIC_IO:
475                 apic = (MADT_IO_APIC *)entry;
476                 if (bootverbose)
477                         kprintf("MADT: Found IO APIC ID %d, Interrupt %d at %p\n",
478                             apic->IoApicId, apic->Interrupt,
479                             (void *)(uintptr_t)apic->Address);
480                 if (apic->IoApicId >= NIOAPICS)
481                         panic("%s: I/O APIC ID %d too high", __func__,
482                             apic->IoApicId);
483                 if (ioapics[apic->IoApicId].io_apic != NULL)
484                         panic("%s: Double APIC ID %d", __func__,
485                             apic->IoApicId);
486                 ioapics[apic->IoApicId].io_apic = ioapic_create(
487                         (uintptr_t)apic->Address, apic->IoApicId,
488                             apic->Interrupt);
489                 ioapics[apic->IoApicId].io_vector = apic->Interrupt;
490                 break;
491         default:
492                 break;
493         }
494 }
495
496 /*
497  * Determine properties of an interrupt source.  Note that for ACPI these
498  * functions are only used for ISA interrupts, so we assume ISA bus values
499  * (Active Hi, Edge Triggered) for conforming values except for the ACPI
500  * SCI for which we use Active Lo, Level Triggered.
501  */
502 static enum intr_polarity
503 interrupt_polarity(UINT16 Polarity, UINT8 Source)
504 {
505
506         switch (Polarity) {
507         case POLARITY_CONFORMS:
508                 if (Source == AcpiGbl_FADT->SciInt)
509                         return (INTR_POLARITY_LOW);
510                 else
511                         return (INTR_POLARITY_HIGH);
512         case POLARITY_ACTIVE_HIGH:
513                 return (INTR_POLARITY_HIGH);
514         case POLARITY_ACTIVE_LOW:
515                 return (INTR_POLARITY_LOW);
516         default:
517                 panic("Bogus Interrupt Polarity");
518         }
519 }
520
521 static enum intr_trigger
522 interrupt_trigger(UINT16 TriggerMode, UINT8 Source)
523 {
524
525         switch (TriggerMode) {
526         case TRIGGER_CONFORMS:
527                 if (Source == AcpiGbl_FADT->SciInt)
528                         return (INTR_TRIGGER_LEVEL);
529                 else
530                         return (INTR_TRIGGER_EDGE);
531         case TRIGGER_EDGE:
532                 return (INTR_TRIGGER_EDGE);
533         case TRIGGER_LEVEL:
534                 return (INTR_TRIGGER_LEVEL);
535         default:
536                 panic("Bogus Interrupt Trigger Mode");
537         }
538 }
539
540 /*
541  * Find the local APIC ID associated with a given ACPI Processor ID.
542  */
543 static int
544 madt_find_cpu(u_int acpi_id, u_int *apic_id)
545 {
546         int i;
547
548         for (i = 0; i < NLAPICS; i++) {
549                 if (!lapics[i].la_enabled)
550                         continue;
551                 if (lapics[i].la_acpi_id != acpi_id)
552                         continue;
553                 *apic_id = i;
554                 return (0);
555         }
556         return (ENOENT);
557 }
558
559 /*
560  * Find the IO APIC and pin on that APIC associated with a given global
561  * interrupt.
562  */
563 static int
564 madt_find_interrupt(int intr, void **apic, u_int *pin)
565 {
566         int i, best;
567
568         best = -1;
569         for (i = 0; i < NIOAPICS; i++) {
570                 if (ioapics[i].io_apic == NULL ||
571                     ioapics[i].io_vector > intr)
572                         continue;
573                 if (best == -1 ||
574                     ioapics[best].io_vector < ioapics[i].io_vector)
575                         best = i;
576         }
577         if (best == -1)
578                 return (ENOENT);
579         *apic = ioapics[best].io_apic;
580         *pin = intr - ioapics[best].io_vector;
581         if (*pin > 32)
582                 kprintf("WARNING: Found intpin of %u for vector %d\n", *pin,
583                     intr);
584         return (0);
585 }
586
587 /*
588  * Parse an interrupt source override for an ISA interrupt.
589  */
590 static void
591 madt_parse_interrupt_override(MADT_INTERRUPT_OVERRIDE *intr)
592 {
593         void *new_ioapic, *old_ioapic;
594         u_int new_pin, old_pin;
595         enum intr_trigger trig;
596         enum intr_polarity pol;
597         char buf[64];
598
599         if (bootverbose)
600                 kprintf("MADT: intr override: source %u, irq %u\n",
601                     intr->Source, intr->Interrupt);
602         KASSERT(intr->Bus == 0, ("bus for interrupt overrides must be zero"));
603         if (madt_find_interrupt(intr->Interrupt, &new_ioapic,
604             &new_pin) != 0) {
605                 kprintf("MADT: Could not find APIC for vector %d (IRQ %d)\n",
606                     intr->Interrupt, intr->Source);
607                 return;
608         }
609
610         /*
611          * Lookup the appropriate trigger and polarity modes for this
612          * entry.
613          */
614         trig = interrupt_trigger(intr->TriggerMode, intr->Source);
615         pol = interrupt_polarity(intr->Polarity, intr->Source);
616
617         /*
618          * If the SCI is identity mapped but has edge trigger and
619          * active-hi polarity or the force_sci_lo tunable is set,
620          * force it to use level/lo.
621          */
622         if (intr->Source == AcpiGbl_FADT->SciInt) {
623                 madt_found_sci_override = 1;
624                 if (kgetenv_string("hw.acpi.sci.trigger", buf, sizeof(buf))) {
625                         if (tolower(buf[0]) == 'e')
626                                 trig = INTR_TRIGGER_EDGE;
627                         else if (tolower(buf[0]) == 'l')
628                                 trig = INTR_TRIGGER_LEVEL;
629                         else
630                                 panic(
631                                 "Invalid trigger %s: must be 'edge' or 'level'",
632                                     buf);
633                         kprintf("MADT: Forcing SCI to %s trigger\n",
634                             trig == INTR_TRIGGER_EDGE ? "edge" : "level");
635                 }
636                 if (kgetenv_string("hw.acpi.sci.polarity", buf, sizeof(buf))) {
637                         if (tolower(buf[0]) == 'h')
638                                 pol = INTR_POLARITY_HIGH;
639                         else if (tolower(buf[0]) == 'l')
640                                 pol = INTR_POLARITY_LOW;
641                         else
642                                 panic(
643                                 "Invalid polarity %s: must be 'high' or 'low'",
644                                     buf);
645                         kprintf("MADT: Forcing SCI to active %s polarity\n",
646                             pol == INTR_POLARITY_HIGH ? "high" : "low");
647                 }
648         }
649
650         /* Remap the IRQ if it is mapped to a different interrupt vector. */
651         if (intr->Source != intr->Interrupt) {
652                 /*
653                  * If the SCI is remapped to a non-ISA global interrupt,
654                  * then override the vector we use to setup and allocate
655                  * the interrupt.
656                  */
657                 if (intr->Interrupt > 15 &&
658                     intr->Source == AcpiGbl_FADT->SciInt)
659                         acpi_OverrideInterruptLevel(intr->Interrupt);
660                 else
661                         ioapic_remap_vector(new_ioapic, new_pin, intr->Source);
662                 if (madt_find_interrupt(intr->Source, &old_ioapic,
663                     &old_pin) != 0)
664                         kprintf("MADT: Could not find APIC for source IRQ %d\n",
665                             intr->Source);
666                 else if (ioapic_get_vector(old_ioapic, old_pin) ==
667                     intr->Source)
668                         ioapic_disable_pin(old_ioapic, old_pin);
669         }
670
671         /* Program the polarity and trigger mode. */
672         ioapic_set_triggermode(new_ioapic, new_pin, trig);
673         ioapic_set_polarity(new_ioapic, new_pin, pol);
674 }
675
676 /*
677  * Parse an entry for an NMI routed to an IO APIC.
678  */
679 static void
680 madt_parse_nmi(MADT_NMI_SOURCE *nmi)
681 {
682         void *ioapic;
683         u_int pin;
684
685         if (madt_find_interrupt(nmi->Interrupt, &ioapic, &pin) != 0) {
686                 kprintf("MADT: Could not find APIC for vector %d\n",
687                     nmi->Interrupt);
688                 return;
689         }
690
691         ioapic_set_nmi(ioapic, pin);
692         if (nmi->TriggerMode != TRIGGER_CONFORMS)
693                 ioapic_set_triggermode(ioapic, pin,
694                     interrupt_trigger(nmi->TriggerMode, 0));
695         if (nmi->Polarity != TRIGGER_CONFORMS)
696                 ioapic_set_polarity(ioapic, pin,
697                     interrupt_polarity(nmi->Polarity, 0));
698 }
699
700 /*
701  * Parse an entry for an NMI routed to a local APIC LVT pin.
702  */
703 static void
704 madt_parse_local_nmi(MADT_LOCAL_APIC_NMI *nmi)
705 {
706         u_int apic_id, pin;
707
708         if (nmi->ProcessorId == 0xff)
709                 apic_id = APIC_ID_ALL;
710         else if (madt_find_cpu(nmi->ProcessorId, &apic_id) != 0) {
711                 if (bootverbose)
712                         kprintf("MADT: Ignoring local NMI routed to ACPI CPU %u\n",
713                             nmi->ProcessorId);
714                 return;
715         }
716         if (nmi->Lint == 0)
717                 pin = LVT_LINT0;
718         else
719                 pin = LVT_LINT1;
720         lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_NMI);
721         if (nmi->TriggerMode != TRIGGER_CONFORMS)
722                 lapic_set_lvt_triggermode(apic_id, pin,
723                     interrupt_trigger(nmi->TriggerMode, 0));
724         if (nmi->Polarity != POLARITY_CONFORMS)
725                 lapic_set_lvt_polarity(apic_id, pin,
726                     interrupt_polarity(nmi->Polarity, 0));
727 }
728
729 /*
730  * Parse interrupt entries.
731  */
732 static void
733 madt_parse_ints(APIC_HEADER *entry, void *arg __unused)
734 {
735
736         switch (entry->Type) {
737         case APIC_XRUPT_OVERRIDE:
738                 madt_parse_interrupt_override(
739                         (MADT_INTERRUPT_OVERRIDE *)entry);
740                 break;
741         case APIC_NMI:
742                 madt_parse_nmi((MADT_NMI_SOURCE *)entry);
743                 break;
744         case APIC_LOCAL_NMI:
745                 madt_parse_local_nmi((MADT_LOCAL_APIC_NMI *)entry);
746                 break;
747         }
748 }
749
750 /*
751  * Setup per-CPU ACPI IDs.  This is done as part of the high-level BIOS
752  * setup (after SMP), but before MACHDEP systems are initialized.
753  */
754 static void
755 madt_set_ids(void *dummy)
756 {
757         struct lapic_info *la;
758         struct mdglobaldata *md;
759         u_int i;
760
761         if (madt == NULL)
762                 return;
763         for (i = 0; i < ncpus; i++) {
764                 if ((smp_active_mask & (1 << i)) == 0)
765                         continue;
766                 md = (struct mdglobaldata *)globaldata_find(i);
767                 KKASSERT(md != NULL);
768                 la = &lapics[md->gd_apic_id];
769                 if (!la->la_enabled)
770                         panic("APIC: CPU with APIC ID %u is not enabled",
771                             md->gd_apic_id);
772                 md->gd_acpi_id = la->la_acpi_id;
773                 if (bootverbose)
774                         kprintf("APIC: CPU %u has ACPI ID %u\n", i,
775                             la->la_acpi_id);
776         }
777 }
778 SYSINIT(madt_set_ids, SI_BOOT2_BIOS, SI_ORDER_FIRST, madt_set_ids, NULL)