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