madt.c revision 197439
1121992Sjhb/*-
2121992Sjhb * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org>
3121992Sjhb * All rights reserved.
4121992Sjhb *
5121992Sjhb * Redistribution and use in source and binary forms, with or without
6121992Sjhb * modification, are permitted provided that the following conditions
7121992Sjhb * are met:
8121992Sjhb * 1. Redistributions of source code must retain the above copyright
9121992Sjhb *    notice, this list of conditions and the following disclaimer.
10121992Sjhb * 2. Redistributions in binary form must reproduce the above copyright
11121992Sjhb *    notice, this list of conditions and the following disclaimer in the
12121992Sjhb *    documentation and/or other materials provided with the distribution.
13121992Sjhb * 3. Neither the name of the author nor the names of any co-contributors
14121992Sjhb *    may be used to endorse or promote products derived from this software
15121992Sjhb *    without specific prior written permission.
16121992Sjhb *
17121992Sjhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18121992Sjhb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19121992Sjhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20121992Sjhb * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21121992Sjhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22121992Sjhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23121992Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24121992Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25121992Sjhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26121992Sjhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27121992Sjhb * SUCH DAMAGE.
28121992Sjhb */
29121992Sjhb
30121992Sjhb#include <sys/cdefs.h>
31121992Sjhb__FBSDID("$FreeBSD: head/sys/i386/acpica/madt.c 197439 2009-09-23 15:42:35Z jhb $");
32121992Sjhb
33121992Sjhb#include <sys/param.h>
34121992Sjhb#include <sys/systm.h>
35121992Sjhb#include <sys/bus.h>
36121992Sjhb#include <sys/kernel.h>
37121992Sjhb#include <sys/malloc.h>
38121992Sjhb#include <sys/smp.h>
39121992Sjhb#include <vm/vm.h>
40121992Sjhb#include <vm/pmap.h>
41121992Sjhb
42121992Sjhb#include <machine/apicreg.h>
43121992Sjhb#include <machine/intr_machdep.h>
44121992Sjhb#include <machine/apicvar.h>
45121992Sjhb
46193530Sjkim#include <contrib/dev/acpica/include/acpi.h>
47193530Sjkim#include <contrib/dev/acpica/include/actables.h>
48193530Sjkim
49121992Sjhb#include <dev/acpica/acpivar.h>
50121992Sjhb#include <dev/pci/pcivar.h>
51121992Sjhb
52121992Sjhb/* These two arrays are indexed by APIC IDs. */
53121992Sjhbstruct ioapic_info {
54121992Sjhb	void *io_apic;
55121992Sjhb	UINT32 io_vector;
56169395Sjhb} ioapics[MAX_APIC_ID + 1];
57121992Sjhb
58121992Sjhbstruct lapic_info {
59121992Sjhb	u_int la_enabled:1;
60129960Sjhb	u_int la_acpi_id:8;
61169395Sjhb} lapics[MAX_APIC_ID + 1];
62121992Sjhb
63128930Sjhbstatic int madt_found_sci_override;
64167814Sjkimstatic ACPI_TABLE_MADT *madt;
65121992Sjhbstatic vm_paddr_t madt_physaddr;
66121992Sjhbstatic vm_offset_t madt_length;
67121992Sjhb
68151897SrwatsonMALLOC_DEFINE(M_MADT, "madt_table", "ACPI MADT Table Items");
69121992Sjhb
70167814Sjkimstatic enum intr_polarity interrupt_polarity(UINT16 IntiFlags, UINT8 Source);
71167814Sjkimstatic enum intr_trigger interrupt_trigger(UINT16 IntiFlags, UINT8 Source);
72121992Sjhbstatic int	madt_find_cpu(u_int acpi_id, u_int *apic_id);
73121992Sjhbstatic int	madt_find_interrupt(int intr, void **apic, u_int *pin);
74167814Sjkimstatic void	madt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg);
75167814Sjkimstatic void	madt_parse_interrupt_override(
76167814Sjkim		    ACPI_MADT_INTERRUPT_OVERRIDE *intr);
77167814Sjkimstatic void	madt_parse_ints(ACPI_SUBTABLE_HEADER *entry,
78167814Sjkim		    void *arg __unused);
79167814Sjkimstatic void	madt_parse_local_nmi(ACPI_MADT_LOCAL_APIC_NMI *nmi);
80167814Sjkimstatic void	madt_parse_nmi(ACPI_MADT_NMI_SOURCE *nmi);
81121992Sjhbstatic int	madt_probe(void);
82121992Sjhbstatic int	madt_probe_cpus(void);
83167814Sjkimstatic void	madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry,
84167814Sjkim		    void *arg __unused);
85121992Sjhbstatic void	madt_register(void *dummy);
86121992Sjhbstatic int	madt_setup_local(void);
87121992Sjhbstatic int	madt_setup_io(void);
88197439Sjhbstatic void	madt_walk_table(acpi_subtable_handler *handler, void *arg);
89121992Sjhb
90121992Sjhbstatic struct apic_enumerator madt_enumerator = {
91121992Sjhb	"MADT",
92121992Sjhb	madt_probe,
93121992Sjhb	madt_probe_cpus,
94121992Sjhb	madt_setup_local,
95121992Sjhb	madt_setup_io
96121992Sjhb};
97121992Sjhb
98121992Sjhb
99121992Sjhb/*
100121992Sjhb * Look for an ACPI Multiple APIC Description Table ("APIC")
101121992Sjhb */
102121992Sjhbstatic int
103121992Sjhbmadt_probe(void)
104121992Sjhb{
105121992Sjhb
106197439Sjhb	madt_physaddr = acpi_find_table(ACPI_SIG_MADT);
107197439Sjhb	if (madt_physaddr == 0)
108121992Sjhb		return (ENXIO);
109121992Sjhb	return (0);
110121992Sjhb}
111121992Sjhb
112121992Sjhb/*
113121992Sjhb * Run through the MP table enumerating CPUs.
114121992Sjhb */
115121992Sjhbstatic int
116121992Sjhbmadt_probe_cpus(void)
117121992Sjhb{
118121992Sjhb
119197439Sjhb	madt = acpi_map_table(madt_physaddr, ACPI_SIG_MADT);
120197439Sjhb	madt_length = madt->Header.Length;
121121992Sjhb	KASSERT(madt != NULL, ("Unable to re-map MADT"));
122121992Sjhb	madt_walk_table(madt_probe_cpus_handler, NULL);
123197439Sjhb	acpi_unmap_table(madt);
124121992Sjhb	madt = NULL;
125121992Sjhb	return (0);
126121992Sjhb}
127121992Sjhb
128121992Sjhb/*
129121992Sjhb * Initialize the local APIC on the BSP.
130121992Sjhb */
131121992Sjhbstatic int
132121992Sjhbmadt_setup_local(void)
133121992Sjhb{
134121992Sjhb
135161223Sjhb	madt = pmap_mapbios(madt_physaddr, madt_length);
136167814Sjkim	lapic_init(madt->Address);
137121992Sjhb	printf("ACPI APIC Table: <%.*s %.*s>\n",
138167814Sjkim	    (int)sizeof(madt->Header.OemId), madt->Header.OemId,
139167814Sjkim	    (int)sizeof(madt->Header.OemTableId), madt->Header.OemTableId);
140121992Sjhb
141121992Sjhb	/*
142121992Sjhb	 * We ignore 64-bit local APIC override entries.  Should we
143121992Sjhb	 * perhaps emit a warning here if we find one?
144121992Sjhb	 */
145121992Sjhb	return (0);
146121992Sjhb}
147121992Sjhb
148121992Sjhb/*
149125048Sjhb * Enumerate I/O APICs and setup interrupt sources.
150121992Sjhb */
151121992Sjhbstatic int
152121992Sjhbmadt_setup_io(void)
153121992Sjhb{
154128930Sjhb	void *ioapic;
155128930Sjhb	u_int pin;
156121992Sjhb	int i;
157121992Sjhb
158125048Sjhb	/* Try to initialize ACPI so that we can access the FADT. */
159125048Sjhb	i = acpi_Startup();
160125048Sjhb	if (ACPI_FAILURE(i)) {
161125048Sjhb		printf("MADT: ACPI Startup failed with %s\n",
162125048Sjhb		    AcpiFormatException(i));
163125048Sjhb		printf("Try disabling either ACPI or apic support.\n");
164125048Sjhb		panic("Using MADT but ACPI doesn't work");
165125048Sjhb	}
166125048Sjhb
167121992Sjhb	/* First, we run through adding I/O APIC's. */
168121992Sjhb	madt_walk_table(madt_parse_apics, NULL);
169121992Sjhb
170121992Sjhb	/* Second, we run through the table tweaking interrupt sources. */
171121992Sjhb	madt_walk_table(madt_parse_ints, NULL);
172121992Sjhb
173128930Sjhb	/*
174128930Sjhb	 * If there was not an explicit override entry for the SCI,
175128930Sjhb	 * force it to use level trigger and active-low polarity.
176128930Sjhb	 */
177128930Sjhb	if (!madt_found_sci_override) {
178167814Sjkim		if (madt_find_interrupt(AcpiGbl_FADT.SciInterrupt, &ioapic,
179167814Sjkim		    &pin) != 0)
180167814Sjkim			printf("MADT: Could not find APIC for SCI IRQ %u\n",
181167814Sjkim			    AcpiGbl_FADT.SciInterrupt);
182128930Sjhb		else {
183128930Sjhb			printf(
184128930Sjhb	"MADT: Forcing active-low polarity and level trigger for SCI\n");
185128930Sjhb			ioapic_set_polarity(ioapic, pin, INTR_POLARITY_LOW);
186128930Sjhb			ioapic_set_triggermode(ioapic, pin, INTR_TRIGGER_LEVEL);
187128930Sjhb		}
188128930Sjhb	}
189128930Sjhb
190121992Sjhb	/* Third, we register all the I/O APIC's. */
191169395Sjhb	for (i = 0; i <= MAX_APIC_ID; i++)
192121992Sjhb		if (ioapics[i].io_apic != NULL)
193121992Sjhb			ioapic_register(ioapics[i].io_apic);
194121992Sjhb
195121992Sjhb	/* Finally, we throw the switch to enable the I/O APIC's. */
196121992Sjhb	acpi_SetDefaultIntrModel(ACPI_INTR_APIC);
197121992Sjhb
198121992Sjhb	return (0);
199121992Sjhb}
200121992Sjhb
201121992Sjhbstatic void
202121992Sjhbmadt_register(void *dummy __unused)
203121992Sjhb{
204121992Sjhb
205121992Sjhb	apic_register_enumerator(&madt_enumerator);
206121992Sjhb}
207177253SrwatsonSYSINIT(madt_register, SI_SUB_CPU - 1, SI_ORDER_SECOND, madt_register, NULL);
208121992Sjhb
209121992Sjhb/*
210121992Sjhb * Call the handler routine for each entry in the MADT table.
211121992Sjhb */
212121992Sjhbstatic void
213197439Sjhbmadt_walk_table(acpi_subtable_handler *handler, void *arg)
214121992Sjhb{
215121992Sjhb
216197439Sjhb	acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length,
217197439Sjhb	    handler, arg);
218121992Sjhb}
219121992Sjhb
220121992Sjhbstatic void
221167814Sjkimmadt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
222121992Sjhb{
223167814Sjkim	ACPI_MADT_LOCAL_APIC *proc;
224121992Sjhb	struct lapic_info *la;
225121992Sjhb
226121992Sjhb	switch (entry->Type) {
227167814Sjkim	case ACPI_MADT_TYPE_LOCAL_APIC:
228121992Sjhb		/*
229121992Sjhb		 * The MADT does not include a BSP flag, so we have to
230121992Sjhb		 * let the MP code figure out which CPU is the BSP on
231121992Sjhb		 * its own.
232121992Sjhb		 */
233167814Sjkim		proc = (ACPI_MADT_LOCAL_APIC *)entry;
234121992Sjhb		if (bootverbose)
235167814Sjkim			printf("MADT: Found CPU APIC ID %u ACPI ID %u: %s\n",
236167814Sjkim			    proc->Id, proc->ProcessorId,
237167814Sjkim			    (proc->LapicFlags & ACPI_MADT_ENABLED) ?
238167814Sjkim			    "enabled" : "disabled");
239167814Sjkim		if (!(proc->LapicFlags & ACPI_MADT_ENABLED))
240130310Sjhb			break;
241169395Sjhb		if (proc->Id > MAX_APIC_ID)
242167814Sjkim			panic("%s: CPU ID %u too high", __func__, proc->Id);
243167814Sjkim		la = &lapics[proc->Id];
244130310Sjhb		KASSERT(la->la_enabled == 0,
245167814Sjkim		    ("Duplicate local APIC ID %u", proc->Id));
246130310Sjhb		la->la_enabled = 1;
247129960Sjhb		la->la_acpi_id = proc->ProcessorId;
248167814Sjkim		lapic_create(proc->Id, 0);
249121992Sjhb		break;
250121992Sjhb	}
251121992Sjhb}
252121992Sjhb
253121992Sjhb
254121992Sjhb/*
255121992Sjhb * Add an I/O APIC from an entry in the table.
256121992Sjhb */
257121992Sjhbstatic void
258167814Sjkimmadt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg __unused)
259121992Sjhb{
260167814Sjkim	ACPI_MADT_IO_APIC *apic;
261121992Sjhb
262121992Sjhb	switch (entry->Type) {
263167814Sjkim	case ACPI_MADT_TYPE_IO_APIC:
264167814Sjkim		apic = (ACPI_MADT_IO_APIC *)entry;
265121992Sjhb		if (bootverbose)
266167814Sjkim			printf(
267167814Sjkim			    "MADT: Found IO APIC ID %u, Interrupt %u at %p\n",
268167814Sjkim			    apic->Id, apic->GlobalIrqBase,
269123326Snjl			    (void *)(uintptr_t)apic->Address);
270169395Sjhb		if (apic->Id > MAX_APIC_ID)
271167814Sjkim			panic("%s: I/O APIC ID %u too high", __func__,
272167814Sjkim			    apic->Id);
273167814Sjkim		if (ioapics[apic->Id].io_apic != NULL)
274167814Sjkim			panic("%s: Double APIC ID %u", __func__, apic->Id);
275189404Sjhb		if (apic->GlobalIrqBase >= FIRST_MSI_INT) {
276189404Sjhb			printf("MADT: Ignoring bogus I/O APIC ID %u", apic->Id);
277189404Sjhb			break;
278189404Sjhb		}
279167814Sjkim		ioapics[apic->Id].io_apic = ioapic_create(apic->Address,
280167814Sjkim		    apic->Id, apic->GlobalIrqBase);
281167814Sjkim		ioapics[apic->Id].io_vector = apic->GlobalIrqBase;
282121992Sjhb		break;
283121992Sjhb	default:
284121992Sjhb		break;
285121992Sjhb	}
286121992Sjhb}
287121992Sjhb
288121992Sjhb/*
289129128Sjhb * Determine properties of an interrupt source.  Note that for ACPI these
290129128Sjhb * functions are only used for ISA interrupts, so we assume ISA bus values
291128930Sjhb * (Active Hi, Edge Triggered) for conforming values except for the ACPI
292129128Sjhb * SCI for which we use Active Lo, Level Triggered.
293121992Sjhb */
294128930Sjhbstatic enum intr_polarity
295167814Sjkiminterrupt_polarity(UINT16 IntiFlags, UINT8 Source)
296121992Sjhb{
297121992Sjhb
298167814Sjkim	switch (IntiFlags & ACPI_MADT_POLARITY_MASK) {
299167814Sjkim	case ACPI_MADT_POLARITY_CONFORMS:
300167814Sjkim		if (Source == AcpiGbl_FADT.SciInterrupt)
301128930Sjhb			return (INTR_POLARITY_LOW);
302128930Sjhb		else
303128930Sjhb			return (INTR_POLARITY_HIGH);
304167814Sjkim	case ACPI_MADT_POLARITY_ACTIVE_HIGH:
305128930Sjhb		return (INTR_POLARITY_HIGH);
306167814Sjkim	case ACPI_MADT_POLARITY_ACTIVE_LOW:
307128930Sjhb		return (INTR_POLARITY_LOW);
308121992Sjhb	default:
309121992Sjhb		panic("Bogus Interrupt Polarity");
310121992Sjhb	}
311121992Sjhb}
312121992Sjhb
313128930Sjhbstatic enum intr_trigger
314167814Sjkiminterrupt_trigger(UINT16 IntiFlags, UINT8 Source)
315121992Sjhb{
316121992Sjhb
317167814Sjkim	switch (IntiFlags & ACPI_MADT_TRIGGER_MASK) {
318167814Sjkim	case ACPI_MADT_TRIGGER_CONFORMS:
319167814Sjkim		if (Source == AcpiGbl_FADT.SciInterrupt)
320128930Sjhb			return (INTR_TRIGGER_LEVEL);
321128930Sjhb		else
322128930Sjhb			return (INTR_TRIGGER_EDGE);
323167814Sjkim	case ACPI_MADT_TRIGGER_EDGE:
324128930Sjhb		return (INTR_TRIGGER_EDGE);
325167814Sjkim	case ACPI_MADT_TRIGGER_LEVEL:
326128930Sjhb		return (INTR_TRIGGER_LEVEL);
327121992Sjhb	default:
328121992Sjhb		panic("Bogus Interrupt Trigger Mode");
329121992Sjhb	}
330121992Sjhb}
331121992Sjhb
332121992Sjhb/*
333121992Sjhb * Find the local APIC ID associated with a given ACPI Processor ID.
334121992Sjhb */
335121992Sjhbstatic int
336121992Sjhbmadt_find_cpu(u_int acpi_id, u_int *apic_id)
337121992Sjhb{
338129960Sjhb	int i;
339121992Sjhb
340169395Sjhb	for (i = 0; i <= MAX_APIC_ID; i++) {
341130310Sjhb		if (!lapics[i].la_enabled)
342129960Sjhb			continue;
343129960Sjhb		if (lapics[i].la_acpi_id != acpi_id)
344129960Sjhb			continue;
345129960Sjhb		*apic_id = i;
346130310Sjhb		return (0);
347129960Sjhb	}
348129960Sjhb	return (ENOENT);
349121992Sjhb}
350121992Sjhb
351121992Sjhb/*
352121992Sjhb * Find the IO APIC and pin on that APIC associated with a given global
353121992Sjhb * interrupt.
354121992Sjhb */
355121992Sjhbstatic int
356121992Sjhbmadt_find_interrupt(int intr, void **apic, u_int *pin)
357121992Sjhb{
358121992Sjhb	int i, best;
359121992Sjhb
360121992Sjhb	best = -1;
361169395Sjhb	for (i = 0; i <= MAX_APIC_ID; i++) {
362121992Sjhb		if (ioapics[i].io_apic == NULL ||
363121992Sjhb		    ioapics[i].io_vector > intr)
364121992Sjhb			continue;
365121992Sjhb		if (best == -1 ||
366121992Sjhb		    ioapics[best].io_vector < ioapics[i].io_vector)
367121992Sjhb			best = i;
368121992Sjhb	}
369121992Sjhb	if (best == -1)
370121992Sjhb		return (ENOENT);
371121992Sjhb	*apic = ioapics[best].io_apic;
372121992Sjhb	*pin = intr - ioapics[best].io_vector;
373121992Sjhb	if (*pin > 32)
374121992Sjhb		printf("WARNING: Found intpin of %u for vector %d\n", *pin,
375121992Sjhb		    intr);
376121992Sjhb	return (0);
377121992Sjhb}
378121992Sjhb
379121992Sjhb/*
380121992Sjhb * Parse an interrupt source override for an ISA interrupt.
381121992Sjhb */
382121992Sjhbstatic void
383167814Sjkimmadt_parse_interrupt_override(ACPI_MADT_INTERRUPT_OVERRIDE *intr)
384121992Sjhb{
385122149Sjhb	void *new_ioapic, *old_ioapic;
386122149Sjhb	u_int new_pin, old_pin;
387128930Sjhb	enum intr_trigger trig;
388128930Sjhb	enum intr_polarity pol;
389128930Sjhb	char buf[64];
390121992Sjhb
391167814Sjkim	if (acpi_quirks & ACPI_Q_MADT_IRQ0 && intr->SourceIrq == 0 &&
392167814Sjkim	    intr->GlobalIrq == 2) {
393142257Sjhb		if (bootverbose)
394142257Sjhb			printf("MADT: Skipping timer override\n");
395142257Sjhb		return;
396142257Sjhb	}
397121992Sjhb	if (bootverbose)
398142257Sjhb		printf("MADT: Interrupt override: source %u, irq %u\n",
399167814Sjkim		    intr->SourceIrq, intr->GlobalIrq);
400121992Sjhb	KASSERT(intr->Bus == 0, ("bus for interrupt overrides must be zero"));
401167814Sjkim	if (madt_find_interrupt(intr->GlobalIrq, &new_ioapic, &new_pin) != 0) {
402167814Sjkim		printf("MADT: Could not find APIC for vector %u (IRQ %u)\n",
403167814Sjkim		    intr->GlobalIrq, intr->SourceIrq);
404121992Sjhb		return;
405121992Sjhb	}
406121992Sjhb
407125048Sjhb	/*
408128930Sjhb	 * Lookup the appropriate trigger and polarity modes for this
409128930Sjhb	 * entry.
410128930Sjhb	 */
411167814Sjkim	trig = interrupt_trigger(intr->IntiFlags, intr->SourceIrq);
412167814Sjkim	pol = interrupt_polarity(intr->IntiFlags, intr->SourceIrq);
413128930Sjhb
414128930Sjhb	/*
415125048Sjhb	 * If the SCI is identity mapped but has edge trigger and
416128329Sjhb	 * active-hi polarity or the force_sci_lo tunable is set,
417128329Sjhb	 * force it to use level/lo.
418125048Sjhb	 */
419167814Sjkim	if (intr->SourceIrq == AcpiGbl_FADT.SciInterrupt) {
420128930Sjhb		madt_found_sci_override = 1;
421128930Sjhb		if (getenv_string("hw.acpi.sci.trigger", buf, sizeof(buf))) {
422128930Sjhb			if (tolower(buf[0]) == 'e')
423128930Sjhb				trig = INTR_TRIGGER_EDGE;
424128930Sjhb			else if (tolower(buf[0]) == 'l')
425128930Sjhb				trig = INTR_TRIGGER_LEVEL;
426128930Sjhb			else
427128930Sjhb				panic(
428128930Sjhb				"Invalid trigger %s: must be 'edge' or 'level'",
429128930Sjhb				    buf);
430128930Sjhb			printf("MADT: Forcing SCI to %s trigger\n",
431128930Sjhb			    trig == INTR_TRIGGER_EDGE ? "edge" : "level");
432128930Sjhb		}
433128930Sjhb		if (getenv_string("hw.acpi.sci.polarity", buf, sizeof(buf))) {
434128930Sjhb			if (tolower(buf[0]) == 'h')
435128930Sjhb				pol = INTR_POLARITY_HIGH;
436128930Sjhb			else if (tolower(buf[0]) == 'l')
437128930Sjhb				pol = INTR_POLARITY_LOW;
438128930Sjhb			else
439128930Sjhb				panic(
440128930Sjhb				"Invalid polarity %s: must be 'high' or 'low'",
441128930Sjhb				    buf);
442128930Sjhb			printf("MADT: Forcing SCI to active %s polarity\n",
443128930Sjhb			    pol == INTR_POLARITY_HIGH ? "high" : "low");
444128930Sjhb		}
445128930Sjhb	}
446125048Sjhb
447128930Sjhb	/* Remap the IRQ if it is mapped to a different interrupt vector. */
448167814Sjkim	if (intr->SourceIrq != intr->GlobalIrq) {
449125048Sjhb		/*
450125048Sjhb		 * If the SCI is remapped to a non-ISA global interrupt,
451125048Sjhb		 * then override the vector we use to setup and allocate
452125048Sjhb		 * the interrupt.
453125048Sjhb		 */
454167814Sjkim		if (intr->GlobalIrq > 15 &&
455167814Sjkim		    intr->SourceIrq == AcpiGbl_FADT.SciInterrupt)
456167814Sjkim			acpi_OverrideInterruptLevel(intr->GlobalIrq);
457122502Sjhb		else
458167814Sjkim			ioapic_remap_vector(new_ioapic, new_pin,
459167814Sjkim			    intr->SourceIrq);
460167814Sjkim		if (madt_find_interrupt(intr->SourceIrq, &old_ioapic,
461122149Sjhb		    &old_pin) != 0)
462167814Sjkim			printf("MADT: Could not find APIC for source IRQ %u\n",
463167814Sjkim			    intr->SourceIrq);
464122172Sjhb		else if (ioapic_get_vector(old_ioapic, old_pin) ==
465167814Sjkim		    intr->SourceIrq)
466122149Sjhb			ioapic_disable_pin(old_ioapic, old_pin);
467122149Sjhb	}
468128930Sjhb
469128930Sjhb	/* Program the polarity and trigger mode. */
470128930Sjhb	ioapic_set_triggermode(new_ioapic, new_pin, trig);
471128930Sjhb	ioapic_set_polarity(new_ioapic, new_pin, pol);
472121992Sjhb}
473121992Sjhb
474121992Sjhb/*
475121992Sjhb * Parse an entry for an NMI routed to an IO APIC.
476121992Sjhb */
477121992Sjhbstatic void
478167814Sjkimmadt_parse_nmi(ACPI_MADT_NMI_SOURCE *nmi)
479121992Sjhb{
480121992Sjhb	void *ioapic;
481121992Sjhb	u_int pin;
482121992Sjhb
483167814Sjkim	if (madt_find_interrupt(nmi->GlobalIrq, &ioapic, &pin) != 0) {
484167814Sjkim		printf("MADT: Could not find APIC for vector %u\n",
485167814Sjkim		    nmi->GlobalIrq);
486121992Sjhb		return;
487121992Sjhb	}
488121992Sjhb
489121992Sjhb	ioapic_set_nmi(ioapic, pin);
490167814Sjkim	if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS))
491121992Sjhb		ioapic_set_triggermode(ioapic, pin,
492167814Sjkim		    interrupt_trigger(nmi->IntiFlags, 0));
493167814Sjkim	if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS))
494121992Sjhb		ioapic_set_polarity(ioapic, pin,
495167814Sjkim		    interrupt_polarity(nmi->IntiFlags, 0));
496121992Sjhb}
497121992Sjhb
498121992Sjhb/*
499121992Sjhb * Parse an entry for an NMI routed to a local APIC LVT pin.
500121992Sjhb */
501121992Sjhbstatic void
502167814Sjkimmadt_parse_local_nmi(ACPI_MADT_LOCAL_APIC_NMI *nmi)
503121992Sjhb{
504121992Sjhb	u_int apic_id, pin;
505121992Sjhb
506123326Snjl	if (nmi->ProcessorId == 0xff)
507121992Sjhb		apic_id = APIC_ID_ALL;
508123326Snjl	else if (madt_find_cpu(nmi->ProcessorId, &apic_id) != 0) {
509121992Sjhb		if (bootverbose)
510167814Sjkim			printf("MADT: Ignoring local NMI routed to "
511167814Sjkim			    "ACPI CPU %u\n", nmi->ProcessorId);
512121992Sjhb		return;
513121992Sjhb	}
514123326Snjl	if (nmi->Lint == 0)
515121992Sjhb		pin = LVT_LINT0;
516121992Sjhb	else
517121992Sjhb		pin = LVT_LINT1;
518121992Sjhb	lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_NMI);
519167814Sjkim	if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS))
520121992Sjhb		lapic_set_lvt_triggermode(apic_id, pin,
521167814Sjkim		    interrupt_trigger(nmi->IntiFlags, 0));
522167814Sjkim	if (!(nmi->IntiFlags & ACPI_MADT_POLARITY_CONFORMS))
523121992Sjhb		lapic_set_lvt_polarity(apic_id, pin,
524167814Sjkim		    interrupt_polarity(nmi->IntiFlags, 0));
525121992Sjhb}
526121992Sjhb
527121992Sjhb/*
528121992Sjhb * Parse interrupt entries.
529121992Sjhb */
530121992Sjhbstatic void
531167814Sjkimmadt_parse_ints(ACPI_SUBTABLE_HEADER *entry, void *arg __unused)
532121992Sjhb{
533121992Sjhb
534121992Sjhb	switch (entry->Type) {
535167814Sjkim	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
536121992Sjhb		madt_parse_interrupt_override(
537167814Sjkim			(ACPI_MADT_INTERRUPT_OVERRIDE *)entry);
538121992Sjhb		break;
539167814Sjkim	case ACPI_MADT_TYPE_NMI_SOURCE:
540167814Sjkim		madt_parse_nmi((ACPI_MADT_NMI_SOURCE *)entry);
541121992Sjhb		break;
542167814Sjkim	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
543167814Sjkim		madt_parse_local_nmi((ACPI_MADT_LOCAL_APIC_NMI *)entry);
544121992Sjhb		break;
545121992Sjhb	}
546121992Sjhb}
547121992Sjhb
548121992Sjhb/*
549121992Sjhb * Setup per-CPU ACPI IDs.
550121992Sjhb */
551121992Sjhbstatic void
552121992Sjhbmadt_set_ids(void *dummy)
553121992Sjhb{
554129960Sjhb	struct lapic_info *la;
555121992Sjhb	struct pcpu *pc;
556129960Sjhb	u_int i;
557121992Sjhb
558121992Sjhb	if (madt == NULL)
559121992Sjhb		return;
560123133Sjhb	for (i = 0; i <= mp_maxid; i++) {
561121992Sjhb		if (CPU_ABSENT(i))
562121992Sjhb			continue;
563121992Sjhb		pc = pcpu_find(i);
564167814Sjkim		KASSERT(pc != NULL, ("no pcpu data for CPU %u", i));
565129960Sjhb		la = &lapics[pc->pc_apic_id];
566130310Sjhb		if (!la->la_enabled)
567129960Sjhb			panic("APIC: CPU with APIC ID %u is not enabled",
568129960Sjhb			    pc->pc_apic_id);
569129960Sjhb		pc->pc_acpi_id = la->la_acpi_id;
570129960Sjhb		if (bootverbose)
571129960Sjhb			printf("APIC: CPU %u has ACPI ID %u\n", i,
572129960Sjhb			    la->la_acpi_id);
573121992Sjhb	}
574121992Sjhb}
575177253SrwatsonSYSINIT(madt_set_ids, SI_SUB_CPU, SI_ORDER_ANY, madt_set_ids, NULL);
576