madt.c revision 263859
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 *
14121992Sjhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15121992Sjhb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16121992Sjhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17121992Sjhb * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18121992Sjhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19121992Sjhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20121992Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21121992Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22121992Sjhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23121992Sjhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24121992Sjhb * SUCH DAMAGE.
25121992Sjhb */
26121992Sjhb
27121992Sjhb#include <sys/cdefs.h>
28121992Sjhb__FBSDID("$FreeBSD: head/sys/x86/acpica/madt.c 263859 2014-03-28 02:38:14Z takawata $");
29121992Sjhb
30121992Sjhb#include <sys/param.h>
31121992Sjhb#include <sys/systm.h>
32121992Sjhb#include <sys/bus.h>
33121992Sjhb#include <sys/kernel.h>
34121992Sjhb#include <sys/malloc.h>
35121992Sjhb#include <sys/smp.h>
36121992Sjhb#include <vm/vm.h>
37121992Sjhb#include <vm/pmap.h>
38121992Sjhb
39214631Sjhb#include <x86/apicreg.h>
40121992Sjhb#include <machine/intr_machdep.h>
41261087Sjhb#include <x86/apicvar.h>
42121992Sjhb
43193530Sjkim#include <contrib/dev/acpica/include/acpi.h>
44193530Sjkim#include <contrib/dev/acpica/include/actables.h>
45193530Sjkim
46121992Sjhb#include <dev/acpica/acpivar.h>
47121992Sjhb#include <dev/pci/pcivar.h>
48121992Sjhb
49121992Sjhb/* These two arrays are indexed by APIC IDs. */
50233623Sjhbstatic struct {
51121992Sjhb	void *io_apic;
52121992Sjhb	UINT32 io_vector;
53233623Sjhb} *ioapics;
54121992Sjhb
55233623Sjhbstatic struct lapic_info {
56121992Sjhb	u_int la_enabled:1;
57129960Sjhb	u_int la_acpi_id:8;
58233623Sjhb} lapics[MAX_APIC_ID + 1];
59121992Sjhb
60128930Sjhbstatic int madt_found_sci_override;
61167814Sjkimstatic ACPI_TABLE_MADT *madt;
62121992Sjhbstatic vm_paddr_t madt_physaddr;
63121992Sjhbstatic vm_offset_t madt_length;
64121992Sjhb
65227293Sedstatic MALLOC_DEFINE(M_MADT, "madt_table", "ACPI MADT Table Items");
66121992Sjhb
67167814Sjkimstatic enum intr_polarity interrupt_polarity(UINT16 IntiFlags, UINT8 Source);
68167814Sjkimstatic enum intr_trigger interrupt_trigger(UINT16 IntiFlags, UINT8 Source);
69121992Sjhbstatic int	madt_find_cpu(u_int acpi_id, u_int *apic_id);
70121992Sjhbstatic int	madt_find_interrupt(int intr, void **apic, u_int *pin);
71167814Sjkimstatic void	madt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg);
72167814Sjkimstatic void	madt_parse_interrupt_override(
73167814Sjkim		    ACPI_MADT_INTERRUPT_OVERRIDE *intr);
74167814Sjkimstatic void	madt_parse_ints(ACPI_SUBTABLE_HEADER *entry,
75167814Sjkim		    void *arg __unused);
76167814Sjkimstatic void	madt_parse_local_nmi(ACPI_MADT_LOCAL_APIC_NMI *nmi);
77167814Sjkimstatic void	madt_parse_nmi(ACPI_MADT_NMI_SOURCE *nmi);
78121992Sjhbstatic int	madt_probe(void);
79121992Sjhbstatic int	madt_probe_cpus(void);
80167814Sjkimstatic void	madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry,
81167814Sjkim		    void *arg __unused);
82121992Sjhbstatic void	madt_register(void *dummy);
83121992Sjhbstatic int	madt_setup_local(void);
84121992Sjhbstatic int	madt_setup_io(void);
85197439Sjhbstatic void	madt_walk_table(acpi_subtable_handler *handler, void *arg);
86121992Sjhb
87121992Sjhbstatic struct apic_enumerator madt_enumerator = {
88121992Sjhb	"MADT",
89121992Sjhb	madt_probe,
90121992Sjhb	madt_probe_cpus,
91121992Sjhb	madt_setup_local,
92121992Sjhb	madt_setup_io
93121992Sjhb};
94121992Sjhb
95121992Sjhb/*
96121992Sjhb * Look for an ACPI Multiple APIC Description Table ("APIC")
97121992Sjhb */
98121992Sjhbstatic int
99121992Sjhbmadt_probe(void)
100121992Sjhb{
101121992Sjhb
102197439Sjhb	madt_physaddr = acpi_find_table(ACPI_SIG_MADT);
103197439Sjhb	if (madt_physaddr == 0)
104121992Sjhb		return (ENXIO);
105121992Sjhb	return (0);
106121992Sjhb}
107121992Sjhb
108121992Sjhb/*
109121992Sjhb * Run through the MP table enumerating CPUs.
110121992Sjhb */
111121992Sjhbstatic int
112121992Sjhbmadt_probe_cpus(void)
113121992Sjhb{
114121992Sjhb
115197439Sjhb	madt = acpi_map_table(madt_physaddr, ACPI_SIG_MADT);
116197439Sjhb	madt_length = madt->Header.Length;
117121992Sjhb	KASSERT(madt != NULL, ("Unable to re-map MADT"));
118121992Sjhb	madt_walk_table(madt_probe_cpus_handler, NULL);
119197439Sjhb	acpi_unmap_table(madt);
120121992Sjhb	madt = NULL;
121121992Sjhb	return (0);
122121992Sjhb}
123121992Sjhb
124121992Sjhb/*
125121992Sjhb * Initialize the local APIC on the BSP.
126121992Sjhb */
127121992Sjhbstatic int
128121992Sjhbmadt_setup_local(void)
129121992Sjhb{
130121992Sjhb
131161223Sjhb	madt = pmap_mapbios(madt_physaddr, madt_length);
132167814Sjkim	lapic_init(madt->Address);
133121992Sjhb	printf("ACPI APIC Table: <%.*s %.*s>\n",
134167814Sjkim	    (int)sizeof(madt->Header.OemId), madt->Header.OemId,
135167814Sjkim	    (int)sizeof(madt->Header.OemTableId), madt->Header.OemTableId);
136121992Sjhb
137121992Sjhb	/*
138121992Sjhb	 * We ignore 64-bit local APIC override entries.  Should we
139121992Sjhb	 * perhaps emit a warning here if we find one?
140121992Sjhb	 */
141121992Sjhb	return (0);
142121992Sjhb}
143121992Sjhb
144121992Sjhb/*
145125048Sjhb * Enumerate I/O APICs and setup interrupt sources.
146121992Sjhb */
147121992Sjhbstatic int
148121992Sjhbmadt_setup_io(void)
149121992Sjhb{
150128930Sjhb	void *ioapic;
151128930Sjhb	u_int pin;
152121992Sjhb	int i;
153121992Sjhb
154125048Sjhb	/* Try to initialize ACPI so that we can access the FADT. */
155125048Sjhb	i = acpi_Startup();
156125048Sjhb	if (ACPI_FAILURE(i)) {
157125048Sjhb		printf("MADT: ACPI Startup failed with %s\n",
158125048Sjhb		    AcpiFormatException(i));
159125048Sjhb		printf("Try disabling either ACPI or apic support.\n");
160125048Sjhb		panic("Using MADT but ACPI doesn't work");
161125048Sjhb	}
162233623Sjhb
163233623Sjhb	ioapics = malloc(sizeof(*ioapics) * (MAX_APIC_ID + 1), M_MADT,
164233623Sjhb	    M_WAITOK | M_ZERO);
165233623Sjhb
166121992Sjhb	/* First, we run through adding I/O APIC's. */
167121992Sjhb	madt_walk_table(madt_parse_apics, NULL);
168121992Sjhb
169121992Sjhb	/* Second, we run through the table tweaking interrupt sources. */
170121992Sjhb	madt_walk_table(madt_parse_ints, NULL);
171121992Sjhb
172128930Sjhb	/*
173128930Sjhb	 * If there was not an explicit override entry for the SCI,
174128930Sjhb	 * force it to use level trigger and active-low polarity.
175128930Sjhb	 */
176128930Sjhb	if (!madt_found_sci_override) {
177167814Sjkim		if (madt_find_interrupt(AcpiGbl_FADT.SciInterrupt, &ioapic,
178167814Sjkim		    &pin) != 0)
179167814Sjkim			printf("MADT: Could not find APIC for SCI IRQ %u\n",
180167814Sjkim			    AcpiGbl_FADT.SciInterrupt);
181128930Sjhb		else {
182128930Sjhb			printf(
183128930Sjhb	"MADT: Forcing active-low polarity and level trigger for SCI\n");
184128930Sjhb			ioapic_set_polarity(ioapic, pin, INTR_POLARITY_LOW);
185128930Sjhb			ioapic_set_triggermode(ioapic, pin, INTR_TRIGGER_LEVEL);
186128930Sjhb		}
187128930Sjhb	}
188128930Sjhb
189121992Sjhb	/* Third, we register all the I/O APIC's. */
190169395Sjhb	for (i = 0; i <= MAX_APIC_ID; i++)
191121992Sjhb		if (ioapics[i].io_apic != NULL)
192121992Sjhb			ioapic_register(ioapics[i].io_apic);
193121992Sjhb
194121992Sjhb	/* Finally, we throw the switch to enable the I/O APIC's. */
195121992Sjhb	acpi_SetDefaultIntrModel(ACPI_INTR_APIC);
196121992Sjhb
197233623Sjhb	free(ioapics, M_MADT);
198233623Sjhb	ioapics = NULL;
199233623Sjhb
200121992Sjhb	return (0);
201121992Sjhb}
202121992Sjhb
203121992Sjhbstatic void
204121992Sjhbmadt_register(void *dummy __unused)
205121992Sjhb{
206121992Sjhb
207121992Sjhb	apic_register_enumerator(&madt_enumerator);
208121992Sjhb}
209215009SjhbSYSINIT(madt_register, SI_SUB_TUNABLES - 1, SI_ORDER_FIRST, madt_register, NULL);
210121992Sjhb
211121992Sjhb/*
212121992Sjhb * Call the handler routine for each entry in the MADT table.
213121992Sjhb */
214121992Sjhbstatic void
215197439Sjhbmadt_walk_table(acpi_subtable_handler *handler, void *arg)
216121992Sjhb{
217121992Sjhb
218197439Sjhb	acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length,
219197439Sjhb	    handler, arg);
220121992Sjhb}
221121992Sjhb
222121992Sjhbstatic void
223167814Sjkimmadt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
224121992Sjhb{
225167814Sjkim	ACPI_MADT_LOCAL_APIC *proc;
226121992Sjhb	struct lapic_info *la;
227121992Sjhb
228121992Sjhb	switch (entry->Type) {
229167814Sjkim	case ACPI_MADT_TYPE_LOCAL_APIC:
230121992Sjhb		/*
231121992Sjhb		 * The MADT does not include a BSP flag, so we have to
232121992Sjhb		 * let the MP code figure out which CPU is the BSP on
233121992Sjhb		 * its own.
234121992Sjhb		 */
235167814Sjkim		proc = (ACPI_MADT_LOCAL_APIC *)entry;
236121992Sjhb		if (bootverbose)
237167814Sjkim			printf("MADT: Found CPU APIC ID %u ACPI ID %u: %s\n",
238167814Sjkim			    proc->Id, proc->ProcessorId,
239167814Sjkim			    (proc->LapicFlags & ACPI_MADT_ENABLED) ?
240167814Sjkim			    "enabled" : "disabled");
241167814Sjkim		if (!(proc->LapicFlags & ACPI_MADT_ENABLED))
242130310Sjhb			break;
243169395Sjhb		if (proc->Id > MAX_APIC_ID)
244167814Sjkim			panic("%s: CPU ID %u too high", __func__, proc->Id);
245167814Sjkim		la = &lapics[proc->Id];
246130310Sjhb		KASSERT(la->la_enabled == 0,
247167814Sjkim		    ("Duplicate local APIC ID %u", proc->Id));
248130310Sjhb		la->la_enabled = 1;
249129960Sjhb		la->la_acpi_id = proc->ProcessorId;
250167814Sjkim		lapic_create(proc->Id, 0);
251121992Sjhb		break;
252121992Sjhb	}
253121992Sjhb}
254121992Sjhb
255121992Sjhb
256121992Sjhb/*
257121992Sjhb * Add an I/O APIC from an entry in the table.
258121992Sjhb */
259121992Sjhbstatic void
260167814Sjkimmadt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg __unused)
261121992Sjhb{
262167814Sjkim	ACPI_MADT_IO_APIC *apic;
263121992Sjhb
264121992Sjhb	switch (entry->Type) {
265167814Sjkim	case ACPI_MADT_TYPE_IO_APIC:
266167814Sjkim		apic = (ACPI_MADT_IO_APIC *)entry;
267121992Sjhb		if (bootverbose)
268167814Sjkim			printf(
269167814Sjkim			    "MADT: Found IO APIC ID %u, Interrupt %u at %p\n",
270167814Sjkim			    apic->Id, apic->GlobalIrqBase,
271123326Snjl			    (void *)(uintptr_t)apic->Address);
272169395Sjhb		if (apic->Id > MAX_APIC_ID)
273167814Sjkim			panic("%s: I/O APIC ID %u too high", __func__,
274167814Sjkim			    apic->Id);
275167814Sjkim		if (ioapics[apic->Id].io_apic != NULL)
276167814Sjkim			panic("%s: Double APIC ID %u", __func__, apic->Id);
277189404Sjhb		if (apic->GlobalIrqBase >= FIRST_MSI_INT) {
278189404Sjhb			printf("MADT: Ignoring bogus I/O APIC ID %u", apic->Id);
279189404Sjhb			break;
280189404Sjhb		}
281167814Sjkim		ioapics[apic->Id].io_apic = ioapic_create(apic->Address,
282167814Sjkim		    apic->Id, apic->GlobalIrqBase);
283167814Sjkim		ioapics[apic->Id].io_vector = apic->GlobalIrqBase;
284121992Sjhb		break;
285121992Sjhb	default:
286121992Sjhb		break;
287121992Sjhb	}
288121992Sjhb}
289121992Sjhb
290121992Sjhb/*
291129128Sjhb * Determine properties of an interrupt source.  Note that for ACPI these
292129128Sjhb * functions are only used for ISA interrupts, so we assume ISA bus values
293128930Sjhb * (Active Hi, Edge Triggered) for conforming values except for the ACPI
294129128Sjhb * SCI for which we use Active Lo, Level Triggered.
295121992Sjhb */
296128930Sjhbstatic enum intr_polarity
297167814Sjkiminterrupt_polarity(UINT16 IntiFlags, UINT8 Source)
298121992Sjhb{
299121992Sjhb
300167814Sjkim	switch (IntiFlags & ACPI_MADT_POLARITY_MASK) {
301263859Stakawata	default:
302263859Stakawata		printf("WARNING: Bogus Interrupt Polarity. Assume CONFORMS");
303263859Stakawata		/* FALLTHROUGH*/
304167814Sjkim	case ACPI_MADT_POLARITY_CONFORMS:
305167814Sjkim		if (Source == AcpiGbl_FADT.SciInterrupt)
306128930Sjhb			return (INTR_POLARITY_LOW);
307128930Sjhb		else
308128930Sjhb			return (INTR_POLARITY_HIGH);
309167814Sjkim	case ACPI_MADT_POLARITY_ACTIVE_HIGH:
310128930Sjhb		return (INTR_POLARITY_HIGH);
311167814Sjkim	case ACPI_MADT_POLARITY_ACTIVE_LOW:
312263859Stakawata		return (INTR_POLARITY_LOW);
313121992Sjhb	}
314121992Sjhb}
315121992Sjhb
316128930Sjhbstatic enum intr_trigger
317167814Sjkiminterrupt_trigger(UINT16 IntiFlags, UINT8 Source)
318121992Sjhb{
319121992Sjhb
320167814Sjkim	switch (IntiFlags & ACPI_MADT_TRIGGER_MASK) {
321263859Stakawata	default:
322263859Stakawata		printf("WARNING: Bogus Interrupt Trigger Mode. Assume CONFORMS.");
323263859Stakawata		/*FALLTHROUGH*/
324167814Sjkim	case ACPI_MADT_TRIGGER_CONFORMS:
325167814Sjkim		if (Source == AcpiGbl_FADT.SciInterrupt)
326128930Sjhb			return (INTR_TRIGGER_LEVEL);
327128930Sjhb		else
328128930Sjhb			return (INTR_TRIGGER_EDGE);
329167814Sjkim	case ACPI_MADT_TRIGGER_EDGE:
330128930Sjhb		return (INTR_TRIGGER_EDGE);
331167814Sjkim	case ACPI_MADT_TRIGGER_LEVEL:
332263859Stakawata		return (INTR_TRIGGER_LEVEL);
333121992Sjhb	}
334121992Sjhb}
335121992Sjhb
336121992Sjhb/*
337121992Sjhb * Find the local APIC ID associated with a given ACPI Processor ID.
338121992Sjhb */
339121992Sjhbstatic int
340121992Sjhbmadt_find_cpu(u_int acpi_id, u_int *apic_id)
341121992Sjhb{
342129960Sjhb	int i;
343121992Sjhb
344169395Sjhb	for (i = 0; i <= MAX_APIC_ID; i++) {
345130310Sjhb		if (!lapics[i].la_enabled)
346129960Sjhb			continue;
347129960Sjhb		if (lapics[i].la_acpi_id != acpi_id)
348129960Sjhb			continue;
349129960Sjhb		*apic_id = i;
350130310Sjhb		return (0);
351129960Sjhb	}
352129960Sjhb	return (ENOENT);
353121992Sjhb}
354121992Sjhb
355121992Sjhb/*
356121992Sjhb * Find the IO APIC and pin on that APIC associated with a given global
357121992Sjhb * interrupt.
358121992Sjhb */
359121992Sjhbstatic int
360121992Sjhbmadt_find_interrupt(int intr, void **apic, u_int *pin)
361121992Sjhb{
362121992Sjhb	int i, best;
363121992Sjhb
364121992Sjhb	best = -1;
365169395Sjhb	for (i = 0; i <= MAX_APIC_ID; i++) {
366121992Sjhb		if (ioapics[i].io_apic == NULL ||
367121992Sjhb		    ioapics[i].io_vector > intr)
368121992Sjhb			continue;
369121992Sjhb		if (best == -1 ||
370121992Sjhb		    ioapics[best].io_vector < ioapics[i].io_vector)
371121992Sjhb			best = i;
372121992Sjhb	}
373121992Sjhb	if (best == -1)
374121992Sjhb		return (ENOENT);
375121992Sjhb	*apic = ioapics[best].io_apic;
376121992Sjhb	*pin = intr - ioapics[best].io_vector;
377121992Sjhb	if (*pin > 32)
378121992Sjhb		printf("WARNING: Found intpin of %u for vector %d\n", *pin,
379121992Sjhb		    intr);
380121992Sjhb	return (0);
381121992Sjhb}
382121992Sjhb
383121992Sjhb/*
384121992Sjhb * Parse an interrupt source override for an ISA interrupt.
385121992Sjhb */
386121992Sjhbstatic void
387167814Sjkimmadt_parse_interrupt_override(ACPI_MADT_INTERRUPT_OVERRIDE *intr)
388121992Sjhb{
389122149Sjhb	void *new_ioapic, *old_ioapic;
390122149Sjhb	u_int new_pin, old_pin;
391128930Sjhb	enum intr_trigger trig;
392128930Sjhb	enum intr_polarity pol;
393128930Sjhb	char buf[64];
394121992Sjhb
395167814Sjkim	if (acpi_quirks & ACPI_Q_MADT_IRQ0 && intr->SourceIrq == 0 &&
396167814Sjkim	    intr->GlobalIrq == 2) {
397142257Sjhb		if (bootverbose)
398142257Sjhb			printf("MADT: Skipping timer override\n");
399142257Sjhb		return;
400142257Sjhb	}
401121992Sjhb	if (bootverbose)
402142257Sjhb		printf("MADT: Interrupt override: source %u, irq %u\n",
403167814Sjkim		    intr->SourceIrq, intr->GlobalIrq);
404121992Sjhb	KASSERT(intr->Bus == 0, ("bus for interrupt overrides must be zero"));
405167814Sjkim	if (madt_find_interrupt(intr->GlobalIrq, &new_ioapic, &new_pin) != 0) {
406167814Sjkim		printf("MADT: Could not find APIC for vector %u (IRQ %u)\n",
407167814Sjkim		    intr->GlobalIrq, intr->SourceIrq);
408121992Sjhb		return;
409121992Sjhb	}
410121992Sjhb
411125048Sjhb	/*
412128930Sjhb	 * Lookup the appropriate trigger and polarity modes for this
413128930Sjhb	 * entry.
414128930Sjhb	 */
415167814Sjkim	trig = interrupt_trigger(intr->IntiFlags, intr->SourceIrq);
416167814Sjkim	pol = interrupt_polarity(intr->IntiFlags, intr->SourceIrq);
417128930Sjhb
418128930Sjhb	/*
419125048Sjhb	 * If the SCI is identity mapped but has edge trigger and
420128329Sjhb	 * active-hi polarity or the force_sci_lo tunable is set,
421128329Sjhb	 * force it to use level/lo.
422125048Sjhb	 */
423167814Sjkim	if (intr->SourceIrq == AcpiGbl_FADT.SciInterrupt) {
424128930Sjhb		madt_found_sci_override = 1;
425128930Sjhb		if (getenv_string("hw.acpi.sci.trigger", buf, sizeof(buf))) {
426128930Sjhb			if (tolower(buf[0]) == 'e')
427128930Sjhb				trig = INTR_TRIGGER_EDGE;
428128930Sjhb			else if (tolower(buf[0]) == 'l')
429128930Sjhb				trig = INTR_TRIGGER_LEVEL;
430128930Sjhb			else
431128930Sjhb				panic(
432128930Sjhb				"Invalid trigger %s: must be 'edge' or 'level'",
433128930Sjhb				    buf);
434128930Sjhb			printf("MADT: Forcing SCI to %s trigger\n",
435128930Sjhb			    trig == INTR_TRIGGER_EDGE ? "edge" : "level");
436128930Sjhb		}
437128930Sjhb		if (getenv_string("hw.acpi.sci.polarity", buf, sizeof(buf))) {
438128930Sjhb			if (tolower(buf[0]) == 'h')
439128930Sjhb				pol = INTR_POLARITY_HIGH;
440128930Sjhb			else if (tolower(buf[0]) == 'l')
441128930Sjhb				pol = INTR_POLARITY_LOW;
442128930Sjhb			else
443128930Sjhb				panic(
444128930Sjhb				"Invalid polarity %s: must be 'high' or 'low'",
445128930Sjhb				    buf);
446128930Sjhb			printf("MADT: Forcing SCI to active %s polarity\n",
447128930Sjhb			    pol == INTR_POLARITY_HIGH ? "high" : "low");
448128930Sjhb		}
449128930Sjhb	}
450125048Sjhb
451128930Sjhb	/* Remap the IRQ if it is mapped to a different interrupt vector. */
452167814Sjkim	if (intr->SourceIrq != intr->GlobalIrq) {
453125048Sjhb		/*
454125048Sjhb		 * If the SCI is remapped to a non-ISA global interrupt,
455125048Sjhb		 * then override the vector we use to setup and allocate
456125048Sjhb		 * the interrupt.
457125048Sjhb		 */
458167814Sjkim		if (intr->GlobalIrq > 15 &&
459167814Sjkim		    intr->SourceIrq == AcpiGbl_FADT.SciInterrupt)
460167814Sjkim			acpi_OverrideInterruptLevel(intr->GlobalIrq);
461122502Sjhb		else
462167814Sjkim			ioapic_remap_vector(new_ioapic, new_pin,
463167814Sjkim			    intr->SourceIrq);
464167814Sjkim		if (madt_find_interrupt(intr->SourceIrq, &old_ioapic,
465122149Sjhb		    &old_pin) != 0)
466167814Sjkim			printf("MADT: Could not find APIC for source IRQ %u\n",
467167814Sjkim			    intr->SourceIrq);
468122172Sjhb		else if (ioapic_get_vector(old_ioapic, old_pin) ==
469167814Sjkim		    intr->SourceIrq)
470122149Sjhb			ioapic_disable_pin(old_ioapic, old_pin);
471122149Sjhb	}
472128930Sjhb
473128930Sjhb	/* Program the polarity and trigger mode. */
474128930Sjhb	ioapic_set_triggermode(new_ioapic, new_pin, trig);
475128930Sjhb	ioapic_set_polarity(new_ioapic, new_pin, pol);
476121992Sjhb}
477121992Sjhb
478121992Sjhb/*
479121992Sjhb * Parse an entry for an NMI routed to an IO APIC.
480121992Sjhb */
481121992Sjhbstatic void
482167814Sjkimmadt_parse_nmi(ACPI_MADT_NMI_SOURCE *nmi)
483121992Sjhb{
484121992Sjhb	void *ioapic;
485121992Sjhb	u_int pin;
486121992Sjhb
487167814Sjkim	if (madt_find_interrupt(nmi->GlobalIrq, &ioapic, &pin) != 0) {
488167814Sjkim		printf("MADT: Could not find APIC for vector %u\n",
489167814Sjkim		    nmi->GlobalIrq);
490121992Sjhb		return;
491121992Sjhb	}
492121992Sjhb
493121992Sjhb	ioapic_set_nmi(ioapic, pin);
494167814Sjkim	if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS))
495121992Sjhb		ioapic_set_triggermode(ioapic, pin,
496167814Sjkim		    interrupt_trigger(nmi->IntiFlags, 0));
497263794Stakawata	if (!(nmi->IntiFlags & ACPI_MADT_POLARITY_CONFORMS))
498121992Sjhb		ioapic_set_polarity(ioapic, pin,
499167814Sjkim		    interrupt_polarity(nmi->IntiFlags, 0));
500121992Sjhb}
501121992Sjhb
502121992Sjhb/*
503121992Sjhb * Parse an entry for an NMI routed to a local APIC LVT pin.
504121992Sjhb */
505121992Sjhbstatic void
506167814Sjkimmadt_parse_local_nmi(ACPI_MADT_LOCAL_APIC_NMI *nmi)
507121992Sjhb{
508121992Sjhb	u_int apic_id, pin;
509121992Sjhb
510123326Snjl	if (nmi->ProcessorId == 0xff)
511121992Sjhb		apic_id = APIC_ID_ALL;
512123326Snjl	else if (madt_find_cpu(nmi->ProcessorId, &apic_id) != 0) {
513121992Sjhb		if (bootverbose)
514167814Sjkim			printf("MADT: Ignoring local NMI routed to "
515167814Sjkim			    "ACPI CPU %u\n", nmi->ProcessorId);
516121992Sjhb		return;
517121992Sjhb	}
518123326Snjl	if (nmi->Lint == 0)
519259140Sjhb		pin = APIC_LVT_LINT0;
520121992Sjhb	else
521259140Sjhb		pin = APIC_LVT_LINT1;
522121992Sjhb	lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_NMI);
523167814Sjkim	if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS))
524121992Sjhb		lapic_set_lvt_triggermode(apic_id, pin,
525167814Sjkim		    interrupt_trigger(nmi->IntiFlags, 0));
526167814Sjkim	if (!(nmi->IntiFlags & ACPI_MADT_POLARITY_CONFORMS))
527121992Sjhb		lapic_set_lvt_polarity(apic_id, pin,
528167814Sjkim		    interrupt_polarity(nmi->IntiFlags, 0));
529121992Sjhb}
530121992Sjhb
531121992Sjhb/*
532121992Sjhb * Parse interrupt entries.
533121992Sjhb */
534121992Sjhbstatic void
535167814Sjkimmadt_parse_ints(ACPI_SUBTABLE_HEADER *entry, void *arg __unused)
536121992Sjhb{
537121992Sjhb
538121992Sjhb	switch (entry->Type) {
539167814Sjkim	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
540121992Sjhb		madt_parse_interrupt_override(
541167814Sjkim			(ACPI_MADT_INTERRUPT_OVERRIDE *)entry);
542121992Sjhb		break;
543167814Sjkim	case ACPI_MADT_TYPE_NMI_SOURCE:
544167814Sjkim		madt_parse_nmi((ACPI_MADT_NMI_SOURCE *)entry);
545121992Sjhb		break;
546167814Sjkim	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
547167814Sjkim		madt_parse_local_nmi((ACPI_MADT_LOCAL_APIC_NMI *)entry);
548121992Sjhb		break;
549121992Sjhb	}
550121992Sjhb}
551121992Sjhb
552121992Sjhb/*
553121992Sjhb * Setup per-CPU ACPI IDs.
554121992Sjhb */
555121992Sjhbstatic void
556121992Sjhbmadt_set_ids(void *dummy)
557121992Sjhb{
558129960Sjhb	struct lapic_info *la;
559121992Sjhb	struct pcpu *pc;
560129960Sjhb	u_int i;
561121992Sjhb
562121992Sjhb	if (madt == NULL)
563121992Sjhb		return;
564209059Sjhb	CPU_FOREACH(i) {
565121992Sjhb		pc = pcpu_find(i);
566167814Sjkim		KASSERT(pc != NULL, ("no pcpu data for CPU %u", i));
567129960Sjhb		la = &lapics[pc->pc_apic_id];
568130310Sjhb		if (!la->la_enabled)
569129960Sjhb			panic("APIC: CPU with APIC ID %u is not enabled",
570129960Sjhb			    pc->pc_apic_id);
571129960Sjhb		pc->pc_acpi_id = la->la_acpi_id;
572129960Sjhb		if (bootverbose)
573129960Sjhb			printf("APIC: CPU %u has ACPI ID %u\n", i,
574129960Sjhb			    la->la_acpi_id);
575121992Sjhb	}
576121992Sjhb}
577256073SgibbsSYSINIT(madt_set_ids, SI_SUB_CPU, SI_ORDER_MIDDLE, madt_set_ids, NULL);
578