madt.c revision 263794
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 263794 2014-03-27 06:08:07Z 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) {
301167814Sjkim	case ACPI_MADT_POLARITY_CONFORMS:
302167814Sjkim		if (Source == AcpiGbl_FADT.SciInterrupt)
303128930Sjhb			return (INTR_POLARITY_LOW);
304128930Sjhb		else
305128930Sjhb			return (INTR_POLARITY_HIGH);
306167814Sjkim	case ACPI_MADT_POLARITY_ACTIVE_HIGH:
307128930Sjhb		return (INTR_POLARITY_HIGH);
308167814Sjkim	case ACPI_MADT_POLARITY_ACTIVE_LOW:
309128930Sjhb		return (INTR_POLARITY_LOW);
310121992Sjhb	default:
311121992Sjhb		panic("Bogus Interrupt Polarity");
312121992Sjhb	}
313121992Sjhb}
314121992Sjhb
315128930Sjhbstatic enum intr_trigger
316167814Sjkiminterrupt_trigger(UINT16 IntiFlags, UINT8 Source)
317121992Sjhb{
318121992Sjhb
319167814Sjkim	switch (IntiFlags & ACPI_MADT_TRIGGER_MASK) {
320167814Sjkim	case ACPI_MADT_TRIGGER_CONFORMS:
321167814Sjkim		if (Source == AcpiGbl_FADT.SciInterrupt)
322128930Sjhb			return (INTR_TRIGGER_LEVEL);
323128930Sjhb		else
324128930Sjhb			return (INTR_TRIGGER_EDGE);
325167814Sjkim	case ACPI_MADT_TRIGGER_EDGE:
326128930Sjhb		return (INTR_TRIGGER_EDGE);
327167814Sjkim	case ACPI_MADT_TRIGGER_LEVEL:
328128930Sjhb		return (INTR_TRIGGER_LEVEL);
329121992Sjhb	default:
330121992Sjhb		panic("Bogus Interrupt Trigger Mode");
331121992Sjhb	}
332121992Sjhb}
333121992Sjhb
334121992Sjhb/*
335121992Sjhb * Find the local APIC ID associated with a given ACPI Processor ID.
336121992Sjhb */
337121992Sjhbstatic int
338121992Sjhbmadt_find_cpu(u_int acpi_id, u_int *apic_id)
339121992Sjhb{
340129960Sjhb	int i;
341121992Sjhb
342169395Sjhb	for (i = 0; i <= MAX_APIC_ID; i++) {
343130310Sjhb		if (!lapics[i].la_enabled)
344129960Sjhb			continue;
345129960Sjhb		if (lapics[i].la_acpi_id != acpi_id)
346129960Sjhb			continue;
347129960Sjhb		*apic_id = i;
348130310Sjhb		return (0);
349129960Sjhb	}
350129960Sjhb	return (ENOENT);
351121992Sjhb}
352121992Sjhb
353121992Sjhb/*
354121992Sjhb * Find the IO APIC and pin on that APIC associated with a given global
355121992Sjhb * interrupt.
356121992Sjhb */
357121992Sjhbstatic int
358121992Sjhbmadt_find_interrupt(int intr, void **apic, u_int *pin)
359121992Sjhb{
360121992Sjhb	int i, best;
361121992Sjhb
362121992Sjhb	best = -1;
363169395Sjhb	for (i = 0; i <= MAX_APIC_ID; i++) {
364121992Sjhb		if (ioapics[i].io_apic == NULL ||
365121992Sjhb		    ioapics[i].io_vector > intr)
366121992Sjhb			continue;
367121992Sjhb		if (best == -1 ||
368121992Sjhb		    ioapics[best].io_vector < ioapics[i].io_vector)
369121992Sjhb			best = i;
370121992Sjhb	}
371121992Sjhb	if (best == -1)
372121992Sjhb		return (ENOENT);
373121992Sjhb	*apic = ioapics[best].io_apic;
374121992Sjhb	*pin = intr - ioapics[best].io_vector;
375121992Sjhb	if (*pin > 32)
376121992Sjhb		printf("WARNING: Found intpin of %u for vector %d\n", *pin,
377121992Sjhb		    intr);
378121992Sjhb	return (0);
379121992Sjhb}
380121992Sjhb
381121992Sjhb/*
382121992Sjhb * Parse an interrupt source override for an ISA interrupt.
383121992Sjhb */
384121992Sjhbstatic void
385167814Sjkimmadt_parse_interrupt_override(ACPI_MADT_INTERRUPT_OVERRIDE *intr)
386121992Sjhb{
387122149Sjhb	void *new_ioapic, *old_ioapic;
388122149Sjhb	u_int new_pin, old_pin;
389128930Sjhb	enum intr_trigger trig;
390128930Sjhb	enum intr_polarity pol;
391128930Sjhb	char buf[64];
392121992Sjhb
393167814Sjkim	if (acpi_quirks & ACPI_Q_MADT_IRQ0 && intr->SourceIrq == 0 &&
394167814Sjkim	    intr->GlobalIrq == 2) {
395142257Sjhb		if (bootverbose)
396142257Sjhb			printf("MADT: Skipping timer override\n");
397142257Sjhb		return;
398142257Sjhb	}
399121992Sjhb	if (bootverbose)
400142257Sjhb		printf("MADT: Interrupt override: source %u, irq %u\n",
401167814Sjkim		    intr->SourceIrq, intr->GlobalIrq);
402121992Sjhb	KASSERT(intr->Bus == 0, ("bus for interrupt overrides must be zero"));
403167814Sjkim	if (madt_find_interrupt(intr->GlobalIrq, &new_ioapic, &new_pin) != 0) {
404167814Sjkim		printf("MADT: Could not find APIC for vector %u (IRQ %u)\n",
405167814Sjkim		    intr->GlobalIrq, intr->SourceIrq);
406121992Sjhb		return;
407121992Sjhb	}
408121992Sjhb
409125048Sjhb	/*
410128930Sjhb	 * Lookup the appropriate trigger and polarity modes for this
411128930Sjhb	 * entry.
412128930Sjhb	 */
413167814Sjkim	trig = interrupt_trigger(intr->IntiFlags, intr->SourceIrq);
414167814Sjkim	pol = interrupt_polarity(intr->IntiFlags, intr->SourceIrq);
415128930Sjhb
416128930Sjhb	/*
417125048Sjhb	 * If the SCI is identity mapped but has edge trigger and
418128329Sjhb	 * active-hi polarity or the force_sci_lo tunable is set,
419128329Sjhb	 * force it to use level/lo.
420125048Sjhb	 */
421167814Sjkim	if (intr->SourceIrq == AcpiGbl_FADT.SciInterrupt) {
422128930Sjhb		madt_found_sci_override = 1;
423128930Sjhb		if (getenv_string("hw.acpi.sci.trigger", buf, sizeof(buf))) {
424128930Sjhb			if (tolower(buf[0]) == 'e')
425128930Sjhb				trig = INTR_TRIGGER_EDGE;
426128930Sjhb			else if (tolower(buf[0]) == 'l')
427128930Sjhb				trig = INTR_TRIGGER_LEVEL;
428128930Sjhb			else
429128930Sjhb				panic(
430128930Sjhb				"Invalid trigger %s: must be 'edge' or 'level'",
431128930Sjhb				    buf);
432128930Sjhb			printf("MADT: Forcing SCI to %s trigger\n",
433128930Sjhb			    trig == INTR_TRIGGER_EDGE ? "edge" : "level");
434128930Sjhb		}
435128930Sjhb		if (getenv_string("hw.acpi.sci.polarity", buf, sizeof(buf))) {
436128930Sjhb			if (tolower(buf[0]) == 'h')
437128930Sjhb				pol = INTR_POLARITY_HIGH;
438128930Sjhb			else if (tolower(buf[0]) == 'l')
439128930Sjhb				pol = INTR_POLARITY_LOW;
440128930Sjhb			else
441128930Sjhb				panic(
442128930Sjhb				"Invalid polarity %s: must be 'high' or 'low'",
443128930Sjhb				    buf);
444128930Sjhb			printf("MADT: Forcing SCI to active %s polarity\n",
445128930Sjhb			    pol == INTR_POLARITY_HIGH ? "high" : "low");
446128930Sjhb		}
447128930Sjhb	}
448125048Sjhb
449128930Sjhb	/* Remap the IRQ if it is mapped to a different interrupt vector. */
450167814Sjkim	if (intr->SourceIrq != intr->GlobalIrq) {
451125048Sjhb		/*
452125048Sjhb		 * If the SCI is remapped to a non-ISA global interrupt,
453125048Sjhb		 * then override the vector we use to setup and allocate
454125048Sjhb		 * the interrupt.
455125048Sjhb		 */
456167814Sjkim		if (intr->GlobalIrq > 15 &&
457167814Sjkim		    intr->SourceIrq == AcpiGbl_FADT.SciInterrupt)
458167814Sjkim			acpi_OverrideInterruptLevel(intr->GlobalIrq);
459122502Sjhb		else
460167814Sjkim			ioapic_remap_vector(new_ioapic, new_pin,
461167814Sjkim			    intr->SourceIrq);
462167814Sjkim		if (madt_find_interrupt(intr->SourceIrq, &old_ioapic,
463122149Sjhb		    &old_pin) != 0)
464167814Sjkim			printf("MADT: Could not find APIC for source IRQ %u\n",
465167814Sjkim			    intr->SourceIrq);
466122172Sjhb		else if (ioapic_get_vector(old_ioapic, old_pin) ==
467167814Sjkim		    intr->SourceIrq)
468122149Sjhb			ioapic_disable_pin(old_ioapic, old_pin);
469122149Sjhb	}
470128930Sjhb
471128930Sjhb	/* Program the polarity and trigger mode. */
472128930Sjhb	ioapic_set_triggermode(new_ioapic, new_pin, trig);
473128930Sjhb	ioapic_set_polarity(new_ioapic, new_pin, pol);
474121992Sjhb}
475121992Sjhb
476121992Sjhb/*
477121992Sjhb * Parse an entry for an NMI routed to an IO APIC.
478121992Sjhb */
479121992Sjhbstatic void
480167814Sjkimmadt_parse_nmi(ACPI_MADT_NMI_SOURCE *nmi)
481121992Sjhb{
482121992Sjhb	void *ioapic;
483121992Sjhb	u_int pin;
484121992Sjhb
485167814Sjkim	if (madt_find_interrupt(nmi->GlobalIrq, &ioapic, &pin) != 0) {
486167814Sjkim		printf("MADT: Could not find APIC for vector %u\n",
487167814Sjkim		    nmi->GlobalIrq);
488121992Sjhb		return;
489121992Sjhb	}
490121992Sjhb
491121992Sjhb	ioapic_set_nmi(ioapic, pin);
492167814Sjkim	if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS))
493121992Sjhb		ioapic_set_triggermode(ioapic, pin,
494167814Sjkim		    interrupt_trigger(nmi->IntiFlags, 0));
495263794Stakawata	if (!(nmi->IntiFlags & ACPI_MADT_POLARITY_CONFORMS))
496121992Sjhb		ioapic_set_polarity(ioapic, pin,
497167814Sjkim		    interrupt_polarity(nmi->IntiFlags, 0));
498121992Sjhb}
499121992Sjhb
500121992Sjhb/*
501121992Sjhb * Parse an entry for an NMI routed to a local APIC LVT pin.
502121992Sjhb */
503121992Sjhbstatic void
504167814Sjkimmadt_parse_local_nmi(ACPI_MADT_LOCAL_APIC_NMI *nmi)
505121992Sjhb{
506121992Sjhb	u_int apic_id, pin;
507121992Sjhb
508123326Snjl	if (nmi->ProcessorId == 0xff)
509121992Sjhb		apic_id = APIC_ID_ALL;
510123326Snjl	else if (madt_find_cpu(nmi->ProcessorId, &apic_id) != 0) {
511121992Sjhb		if (bootverbose)
512167814Sjkim			printf("MADT: Ignoring local NMI routed to "
513167814Sjkim			    "ACPI CPU %u\n", nmi->ProcessorId);
514121992Sjhb		return;
515121992Sjhb	}
516123326Snjl	if (nmi->Lint == 0)
517259140Sjhb		pin = APIC_LVT_LINT0;
518121992Sjhb	else
519259140Sjhb		pin = APIC_LVT_LINT1;
520121992Sjhb	lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_NMI);
521167814Sjkim	if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS))
522121992Sjhb		lapic_set_lvt_triggermode(apic_id, pin,
523167814Sjkim		    interrupt_trigger(nmi->IntiFlags, 0));
524167814Sjkim	if (!(nmi->IntiFlags & ACPI_MADT_POLARITY_CONFORMS))
525121992Sjhb		lapic_set_lvt_polarity(apic_id, pin,
526167814Sjkim		    interrupt_polarity(nmi->IntiFlags, 0));
527121992Sjhb}
528121992Sjhb
529121992Sjhb/*
530121992Sjhb * Parse interrupt entries.
531121992Sjhb */
532121992Sjhbstatic void
533167814Sjkimmadt_parse_ints(ACPI_SUBTABLE_HEADER *entry, void *arg __unused)
534121992Sjhb{
535121992Sjhb
536121992Sjhb	switch (entry->Type) {
537167814Sjkim	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
538121992Sjhb		madt_parse_interrupt_override(
539167814Sjkim			(ACPI_MADT_INTERRUPT_OVERRIDE *)entry);
540121992Sjhb		break;
541167814Sjkim	case ACPI_MADT_TYPE_NMI_SOURCE:
542167814Sjkim		madt_parse_nmi((ACPI_MADT_NMI_SOURCE *)entry);
543121992Sjhb		break;
544167814Sjkim	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
545167814Sjkim		madt_parse_local_nmi((ACPI_MADT_LOCAL_APIC_NMI *)entry);
546121992Sjhb		break;
547121992Sjhb	}
548121992Sjhb}
549121992Sjhb
550121992Sjhb/*
551121992Sjhb * Setup per-CPU ACPI IDs.
552121992Sjhb */
553121992Sjhbstatic void
554121992Sjhbmadt_set_ids(void *dummy)
555121992Sjhb{
556129960Sjhb	struct lapic_info *la;
557121992Sjhb	struct pcpu *pc;
558129960Sjhb	u_int i;
559121992Sjhb
560121992Sjhb	if (madt == NULL)
561121992Sjhb		return;
562209059Sjhb	CPU_FOREACH(i) {
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}
575256073SgibbsSYSINIT(madt_set_ids, SI_SUB_CPU, SI_ORDER_MIDDLE, madt_set_ids, NULL);
576