madt.c revision 256073
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/x86/acpica/madt.c 256073 2013-10-05 23:11:01Z gibbs $"); 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 42214631Sjhb#include <x86/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. */ 53233623Sjhbstatic struct { 54121992Sjhb void *io_apic; 55121992Sjhb UINT32 io_vector; 56233623Sjhb} *ioapics; 57121992Sjhb 58233623Sjhbstatic struct lapic_info { 59121992Sjhb u_int la_enabled:1; 60129960Sjhb u_int la_acpi_id:8; 61233623Sjhb} 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 68227293Sedstatic MALLOC_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 * Look for an ACPI Multiple APIC Description Table ("APIC") 100121992Sjhb */ 101121992Sjhbstatic int 102121992Sjhbmadt_probe(void) 103121992Sjhb{ 104121992Sjhb 105197439Sjhb madt_physaddr = acpi_find_table(ACPI_SIG_MADT); 106197439Sjhb if (madt_physaddr == 0) 107121992Sjhb return (ENXIO); 108121992Sjhb return (0); 109121992Sjhb} 110121992Sjhb 111121992Sjhb/* 112121992Sjhb * Run through the MP table enumerating CPUs. 113121992Sjhb */ 114121992Sjhbstatic int 115121992Sjhbmadt_probe_cpus(void) 116121992Sjhb{ 117121992Sjhb 118197439Sjhb madt = acpi_map_table(madt_physaddr, ACPI_SIG_MADT); 119197439Sjhb madt_length = madt->Header.Length; 120121992Sjhb KASSERT(madt != NULL, ("Unable to re-map MADT")); 121121992Sjhb madt_walk_table(madt_probe_cpus_handler, NULL); 122197439Sjhb acpi_unmap_table(madt); 123121992Sjhb madt = NULL; 124121992Sjhb return (0); 125121992Sjhb} 126121992Sjhb 127121992Sjhb/* 128121992Sjhb * Initialize the local APIC on the BSP. 129121992Sjhb */ 130121992Sjhbstatic int 131121992Sjhbmadt_setup_local(void) 132121992Sjhb{ 133121992Sjhb 134161223Sjhb madt = pmap_mapbios(madt_physaddr, madt_length); 135167814Sjkim lapic_init(madt->Address); 136121992Sjhb printf("ACPI APIC Table: <%.*s %.*s>\n", 137167814Sjkim (int)sizeof(madt->Header.OemId), madt->Header.OemId, 138167814Sjkim (int)sizeof(madt->Header.OemTableId), madt->Header.OemTableId); 139121992Sjhb 140121992Sjhb /* 141121992Sjhb * We ignore 64-bit local APIC override entries. Should we 142121992Sjhb * perhaps emit a warning here if we find one? 143121992Sjhb */ 144121992Sjhb return (0); 145121992Sjhb} 146121992Sjhb 147121992Sjhb/* 148125048Sjhb * Enumerate I/O APICs and setup interrupt sources. 149121992Sjhb */ 150121992Sjhbstatic int 151121992Sjhbmadt_setup_io(void) 152121992Sjhb{ 153128930Sjhb void *ioapic; 154128930Sjhb u_int pin; 155121992Sjhb int i; 156121992Sjhb 157125048Sjhb /* Try to initialize ACPI so that we can access the FADT. */ 158125048Sjhb i = acpi_Startup(); 159125048Sjhb if (ACPI_FAILURE(i)) { 160125048Sjhb printf("MADT: ACPI Startup failed with %s\n", 161125048Sjhb AcpiFormatException(i)); 162125048Sjhb printf("Try disabling either ACPI or apic support.\n"); 163125048Sjhb panic("Using MADT but ACPI doesn't work"); 164125048Sjhb } 165233623Sjhb 166233623Sjhb ioapics = malloc(sizeof(*ioapics) * (MAX_APIC_ID + 1), M_MADT, 167233623Sjhb M_WAITOK | M_ZERO); 168233623Sjhb 169121992Sjhb /* First, we run through adding I/O APIC's. */ 170121992Sjhb madt_walk_table(madt_parse_apics, NULL); 171121992Sjhb 172121992Sjhb /* Second, we run through the table tweaking interrupt sources. */ 173121992Sjhb madt_walk_table(madt_parse_ints, NULL); 174121992Sjhb 175128930Sjhb /* 176128930Sjhb * If there was not an explicit override entry for the SCI, 177128930Sjhb * force it to use level trigger and active-low polarity. 178128930Sjhb */ 179128930Sjhb if (!madt_found_sci_override) { 180167814Sjkim if (madt_find_interrupt(AcpiGbl_FADT.SciInterrupt, &ioapic, 181167814Sjkim &pin) != 0) 182167814Sjkim printf("MADT: Could not find APIC for SCI IRQ %u\n", 183167814Sjkim AcpiGbl_FADT.SciInterrupt); 184128930Sjhb else { 185128930Sjhb printf( 186128930Sjhb "MADT: Forcing active-low polarity and level trigger for SCI\n"); 187128930Sjhb ioapic_set_polarity(ioapic, pin, INTR_POLARITY_LOW); 188128930Sjhb ioapic_set_triggermode(ioapic, pin, INTR_TRIGGER_LEVEL); 189128930Sjhb } 190128930Sjhb } 191128930Sjhb 192121992Sjhb /* Third, we register all the I/O APIC's. */ 193169395Sjhb for (i = 0; i <= MAX_APIC_ID; i++) 194121992Sjhb if (ioapics[i].io_apic != NULL) 195121992Sjhb ioapic_register(ioapics[i].io_apic); 196121992Sjhb 197121992Sjhb /* Finally, we throw the switch to enable the I/O APIC's. */ 198121992Sjhb acpi_SetDefaultIntrModel(ACPI_INTR_APIC); 199121992Sjhb 200233623Sjhb free(ioapics, M_MADT); 201233623Sjhb ioapics = NULL; 202233623Sjhb 203121992Sjhb return (0); 204121992Sjhb} 205121992Sjhb 206121992Sjhbstatic void 207121992Sjhbmadt_register(void *dummy __unused) 208121992Sjhb{ 209121992Sjhb 210121992Sjhb apic_register_enumerator(&madt_enumerator); 211121992Sjhb} 212215009SjhbSYSINIT(madt_register, SI_SUB_TUNABLES - 1, SI_ORDER_FIRST, madt_register, NULL); 213121992Sjhb 214121992Sjhb/* 215121992Sjhb * Call the handler routine for each entry in the MADT table. 216121992Sjhb */ 217121992Sjhbstatic void 218197439Sjhbmadt_walk_table(acpi_subtable_handler *handler, void *arg) 219121992Sjhb{ 220121992Sjhb 221197439Sjhb acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, 222197439Sjhb handler, arg); 223121992Sjhb} 224121992Sjhb 225121992Sjhbstatic void 226167814Sjkimmadt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg) 227121992Sjhb{ 228167814Sjkim ACPI_MADT_LOCAL_APIC *proc; 229121992Sjhb struct lapic_info *la; 230121992Sjhb 231121992Sjhb switch (entry->Type) { 232167814Sjkim case ACPI_MADT_TYPE_LOCAL_APIC: 233121992Sjhb /* 234121992Sjhb * The MADT does not include a BSP flag, so we have to 235121992Sjhb * let the MP code figure out which CPU is the BSP on 236121992Sjhb * its own. 237121992Sjhb */ 238167814Sjkim proc = (ACPI_MADT_LOCAL_APIC *)entry; 239121992Sjhb if (bootverbose) 240167814Sjkim printf("MADT: Found CPU APIC ID %u ACPI ID %u: %s\n", 241167814Sjkim proc->Id, proc->ProcessorId, 242167814Sjkim (proc->LapicFlags & ACPI_MADT_ENABLED) ? 243167814Sjkim "enabled" : "disabled"); 244167814Sjkim if (!(proc->LapicFlags & ACPI_MADT_ENABLED)) 245130310Sjhb break; 246169395Sjhb if (proc->Id > MAX_APIC_ID) 247167814Sjkim panic("%s: CPU ID %u too high", __func__, proc->Id); 248167814Sjkim la = &lapics[proc->Id]; 249130310Sjhb KASSERT(la->la_enabled == 0, 250167814Sjkim ("Duplicate local APIC ID %u", proc->Id)); 251130310Sjhb la->la_enabled = 1; 252129960Sjhb la->la_acpi_id = proc->ProcessorId; 253167814Sjkim lapic_create(proc->Id, 0); 254121992Sjhb break; 255121992Sjhb } 256121992Sjhb} 257121992Sjhb 258121992Sjhb 259121992Sjhb/* 260121992Sjhb * Add an I/O APIC from an entry in the table. 261121992Sjhb */ 262121992Sjhbstatic void 263167814Sjkimmadt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg __unused) 264121992Sjhb{ 265167814Sjkim ACPI_MADT_IO_APIC *apic; 266121992Sjhb 267121992Sjhb switch (entry->Type) { 268167814Sjkim case ACPI_MADT_TYPE_IO_APIC: 269167814Sjkim apic = (ACPI_MADT_IO_APIC *)entry; 270121992Sjhb if (bootverbose) 271167814Sjkim printf( 272167814Sjkim "MADT: Found IO APIC ID %u, Interrupt %u at %p\n", 273167814Sjkim apic->Id, apic->GlobalIrqBase, 274123326Snjl (void *)(uintptr_t)apic->Address); 275169395Sjhb if (apic->Id > MAX_APIC_ID) 276167814Sjkim panic("%s: I/O APIC ID %u too high", __func__, 277167814Sjkim apic->Id); 278167814Sjkim if (ioapics[apic->Id].io_apic != NULL) 279167814Sjkim panic("%s: Double APIC ID %u", __func__, apic->Id); 280189404Sjhb if (apic->GlobalIrqBase >= FIRST_MSI_INT) { 281189404Sjhb printf("MADT: Ignoring bogus I/O APIC ID %u", apic->Id); 282189404Sjhb break; 283189404Sjhb } 284167814Sjkim ioapics[apic->Id].io_apic = ioapic_create(apic->Address, 285167814Sjkim apic->Id, apic->GlobalIrqBase); 286167814Sjkim ioapics[apic->Id].io_vector = apic->GlobalIrqBase; 287121992Sjhb break; 288121992Sjhb default: 289121992Sjhb break; 290121992Sjhb } 291121992Sjhb} 292121992Sjhb 293121992Sjhb/* 294129128Sjhb * Determine properties of an interrupt source. Note that for ACPI these 295129128Sjhb * functions are only used for ISA interrupts, so we assume ISA bus values 296128930Sjhb * (Active Hi, Edge Triggered) for conforming values except for the ACPI 297129128Sjhb * SCI for which we use Active Lo, Level Triggered. 298121992Sjhb */ 299128930Sjhbstatic enum intr_polarity 300167814Sjkiminterrupt_polarity(UINT16 IntiFlags, UINT8 Source) 301121992Sjhb{ 302121992Sjhb 303167814Sjkim switch (IntiFlags & ACPI_MADT_POLARITY_MASK) { 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: 312128930Sjhb return (INTR_POLARITY_LOW); 313121992Sjhb default: 314121992Sjhb panic("Bogus Interrupt Polarity"); 315121992Sjhb } 316121992Sjhb} 317121992Sjhb 318128930Sjhbstatic enum intr_trigger 319167814Sjkiminterrupt_trigger(UINT16 IntiFlags, UINT8 Source) 320121992Sjhb{ 321121992Sjhb 322167814Sjkim switch (IntiFlags & ACPI_MADT_TRIGGER_MASK) { 323167814Sjkim case ACPI_MADT_TRIGGER_CONFORMS: 324167814Sjkim if (Source == AcpiGbl_FADT.SciInterrupt) 325128930Sjhb return (INTR_TRIGGER_LEVEL); 326128930Sjhb else 327128930Sjhb return (INTR_TRIGGER_EDGE); 328167814Sjkim case ACPI_MADT_TRIGGER_EDGE: 329128930Sjhb return (INTR_TRIGGER_EDGE); 330167814Sjkim case ACPI_MADT_TRIGGER_LEVEL: 331128930Sjhb return (INTR_TRIGGER_LEVEL); 332121992Sjhb default: 333121992Sjhb panic("Bogus Interrupt Trigger Mode"); 334121992Sjhb } 335121992Sjhb} 336121992Sjhb 337121992Sjhb/* 338121992Sjhb * Find the local APIC ID associated with a given ACPI Processor ID. 339121992Sjhb */ 340121992Sjhbstatic int 341121992Sjhbmadt_find_cpu(u_int acpi_id, u_int *apic_id) 342121992Sjhb{ 343129960Sjhb int i; 344121992Sjhb 345169395Sjhb for (i = 0; i <= MAX_APIC_ID; i++) { 346130310Sjhb if (!lapics[i].la_enabled) 347129960Sjhb continue; 348129960Sjhb if (lapics[i].la_acpi_id != acpi_id) 349129960Sjhb continue; 350129960Sjhb *apic_id = i; 351130310Sjhb return (0); 352129960Sjhb } 353129960Sjhb return (ENOENT); 354121992Sjhb} 355121992Sjhb 356121992Sjhb/* 357121992Sjhb * Find the IO APIC and pin on that APIC associated with a given global 358121992Sjhb * interrupt. 359121992Sjhb */ 360121992Sjhbstatic int 361121992Sjhbmadt_find_interrupt(int intr, void **apic, u_int *pin) 362121992Sjhb{ 363121992Sjhb int i, best; 364121992Sjhb 365121992Sjhb best = -1; 366169395Sjhb for (i = 0; i <= MAX_APIC_ID; i++) { 367121992Sjhb if (ioapics[i].io_apic == NULL || 368121992Sjhb ioapics[i].io_vector > intr) 369121992Sjhb continue; 370121992Sjhb if (best == -1 || 371121992Sjhb ioapics[best].io_vector < ioapics[i].io_vector) 372121992Sjhb best = i; 373121992Sjhb } 374121992Sjhb if (best == -1) 375121992Sjhb return (ENOENT); 376121992Sjhb *apic = ioapics[best].io_apic; 377121992Sjhb *pin = intr - ioapics[best].io_vector; 378121992Sjhb if (*pin > 32) 379121992Sjhb printf("WARNING: Found intpin of %u for vector %d\n", *pin, 380121992Sjhb intr); 381121992Sjhb return (0); 382121992Sjhb} 383121992Sjhb 384121992Sjhb/* 385121992Sjhb * Parse an interrupt source override for an ISA interrupt. 386121992Sjhb */ 387121992Sjhbstatic void 388167814Sjkimmadt_parse_interrupt_override(ACPI_MADT_INTERRUPT_OVERRIDE *intr) 389121992Sjhb{ 390122149Sjhb void *new_ioapic, *old_ioapic; 391122149Sjhb u_int new_pin, old_pin; 392128930Sjhb enum intr_trigger trig; 393128930Sjhb enum intr_polarity pol; 394128930Sjhb char buf[64]; 395121992Sjhb 396167814Sjkim if (acpi_quirks & ACPI_Q_MADT_IRQ0 && intr->SourceIrq == 0 && 397167814Sjkim intr->GlobalIrq == 2) { 398142257Sjhb if (bootverbose) 399142257Sjhb printf("MADT: Skipping timer override\n"); 400142257Sjhb return; 401142257Sjhb } 402121992Sjhb if (bootverbose) 403142257Sjhb printf("MADT: Interrupt override: source %u, irq %u\n", 404167814Sjkim intr->SourceIrq, intr->GlobalIrq); 405121992Sjhb KASSERT(intr->Bus == 0, ("bus for interrupt overrides must be zero")); 406167814Sjkim if (madt_find_interrupt(intr->GlobalIrq, &new_ioapic, &new_pin) != 0) { 407167814Sjkim printf("MADT: Could not find APIC for vector %u (IRQ %u)\n", 408167814Sjkim intr->GlobalIrq, intr->SourceIrq); 409121992Sjhb return; 410121992Sjhb } 411121992Sjhb 412125048Sjhb /* 413128930Sjhb * Lookup the appropriate trigger and polarity modes for this 414128930Sjhb * entry. 415128930Sjhb */ 416167814Sjkim trig = interrupt_trigger(intr->IntiFlags, intr->SourceIrq); 417167814Sjkim pol = interrupt_polarity(intr->IntiFlags, intr->SourceIrq); 418128930Sjhb 419128930Sjhb /* 420125048Sjhb * If the SCI is identity mapped but has edge trigger and 421128329Sjhb * active-hi polarity or the force_sci_lo tunable is set, 422128329Sjhb * force it to use level/lo. 423125048Sjhb */ 424167814Sjkim if (intr->SourceIrq == AcpiGbl_FADT.SciInterrupt) { 425128930Sjhb madt_found_sci_override = 1; 426128930Sjhb if (getenv_string("hw.acpi.sci.trigger", buf, sizeof(buf))) { 427128930Sjhb if (tolower(buf[0]) == 'e') 428128930Sjhb trig = INTR_TRIGGER_EDGE; 429128930Sjhb else if (tolower(buf[0]) == 'l') 430128930Sjhb trig = INTR_TRIGGER_LEVEL; 431128930Sjhb else 432128930Sjhb panic( 433128930Sjhb "Invalid trigger %s: must be 'edge' or 'level'", 434128930Sjhb buf); 435128930Sjhb printf("MADT: Forcing SCI to %s trigger\n", 436128930Sjhb trig == INTR_TRIGGER_EDGE ? "edge" : "level"); 437128930Sjhb } 438128930Sjhb if (getenv_string("hw.acpi.sci.polarity", buf, sizeof(buf))) { 439128930Sjhb if (tolower(buf[0]) == 'h') 440128930Sjhb pol = INTR_POLARITY_HIGH; 441128930Sjhb else if (tolower(buf[0]) == 'l') 442128930Sjhb pol = INTR_POLARITY_LOW; 443128930Sjhb else 444128930Sjhb panic( 445128930Sjhb "Invalid polarity %s: must be 'high' or 'low'", 446128930Sjhb buf); 447128930Sjhb printf("MADT: Forcing SCI to active %s polarity\n", 448128930Sjhb pol == INTR_POLARITY_HIGH ? "high" : "low"); 449128930Sjhb } 450128930Sjhb } 451125048Sjhb 452128930Sjhb /* Remap the IRQ if it is mapped to a different interrupt vector. */ 453167814Sjkim if (intr->SourceIrq != intr->GlobalIrq) { 454125048Sjhb /* 455125048Sjhb * If the SCI is remapped to a non-ISA global interrupt, 456125048Sjhb * then override the vector we use to setup and allocate 457125048Sjhb * the interrupt. 458125048Sjhb */ 459167814Sjkim if (intr->GlobalIrq > 15 && 460167814Sjkim intr->SourceIrq == AcpiGbl_FADT.SciInterrupt) 461167814Sjkim acpi_OverrideInterruptLevel(intr->GlobalIrq); 462122502Sjhb else 463167814Sjkim ioapic_remap_vector(new_ioapic, new_pin, 464167814Sjkim intr->SourceIrq); 465167814Sjkim if (madt_find_interrupt(intr->SourceIrq, &old_ioapic, 466122149Sjhb &old_pin) != 0) 467167814Sjkim printf("MADT: Could not find APIC for source IRQ %u\n", 468167814Sjkim intr->SourceIrq); 469122172Sjhb else if (ioapic_get_vector(old_ioapic, old_pin) == 470167814Sjkim intr->SourceIrq) 471122149Sjhb ioapic_disable_pin(old_ioapic, old_pin); 472122149Sjhb } 473128930Sjhb 474128930Sjhb /* Program the polarity and trigger mode. */ 475128930Sjhb ioapic_set_triggermode(new_ioapic, new_pin, trig); 476128930Sjhb ioapic_set_polarity(new_ioapic, new_pin, pol); 477121992Sjhb} 478121992Sjhb 479121992Sjhb/* 480121992Sjhb * Parse an entry for an NMI routed to an IO APIC. 481121992Sjhb */ 482121992Sjhbstatic void 483167814Sjkimmadt_parse_nmi(ACPI_MADT_NMI_SOURCE *nmi) 484121992Sjhb{ 485121992Sjhb void *ioapic; 486121992Sjhb u_int pin; 487121992Sjhb 488167814Sjkim if (madt_find_interrupt(nmi->GlobalIrq, &ioapic, &pin) != 0) { 489167814Sjkim printf("MADT: Could not find APIC for vector %u\n", 490167814Sjkim nmi->GlobalIrq); 491121992Sjhb return; 492121992Sjhb } 493121992Sjhb 494121992Sjhb ioapic_set_nmi(ioapic, pin); 495167814Sjkim if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS)) 496121992Sjhb ioapic_set_triggermode(ioapic, pin, 497167814Sjkim interrupt_trigger(nmi->IntiFlags, 0)); 498167814Sjkim if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS)) 499121992Sjhb ioapic_set_polarity(ioapic, pin, 500167814Sjkim interrupt_polarity(nmi->IntiFlags, 0)); 501121992Sjhb} 502121992Sjhb 503121992Sjhb/* 504121992Sjhb * Parse an entry for an NMI routed to a local APIC LVT pin. 505121992Sjhb */ 506121992Sjhbstatic void 507167814Sjkimmadt_parse_local_nmi(ACPI_MADT_LOCAL_APIC_NMI *nmi) 508121992Sjhb{ 509121992Sjhb u_int apic_id, pin; 510121992Sjhb 511123326Snjl if (nmi->ProcessorId == 0xff) 512121992Sjhb apic_id = APIC_ID_ALL; 513123326Snjl else if (madt_find_cpu(nmi->ProcessorId, &apic_id) != 0) { 514121992Sjhb if (bootverbose) 515167814Sjkim printf("MADT: Ignoring local NMI routed to " 516167814Sjkim "ACPI CPU %u\n", nmi->ProcessorId); 517121992Sjhb return; 518121992Sjhb } 519123326Snjl if (nmi->Lint == 0) 520121992Sjhb pin = LVT_LINT0; 521121992Sjhb else 522121992Sjhb pin = LVT_LINT1; 523121992Sjhb lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_NMI); 524167814Sjkim if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS)) 525121992Sjhb lapic_set_lvt_triggermode(apic_id, pin, 526167814Sjkim interrupt_trigger(nmi->IntiFlags, 0)); 527167814Sjkim if (!(nmi->IntiFlags & ACPI_MADT_POLARITY_CONFORMS)) 528121992Sjhb lapic_set_lvt_polarity(apic_id, pin, 529167814Sjkim interrupt_polarity(nmi->IntiFlags, 0)); 530121992Sjhb} 531121992Sjhb 532121992Sjhb/* 533121992Sjhb * Parse interrupt entries. 534121992Sjhb */ 535121992Sjhbstatic void 536167814Sjkimmadt_parse_ints(ACPI_SUBTABLE_HEADER *entry, void *arg __unused) 537121992Sjhb{ 538121992Sjhb 539121992Sjhb switch (entry->Type) { 540167814Sjkim case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 541121992Sjhb madt_parse_interrupt_override( 542167814Sjkim (ACPI_MADT_INTERRUPT_OVERRIDE *)entry); 543121992Sjhb break; 544167814Sjkim case ACPI_MADT_TYPE_NMI_SOURCE: 545167814Sjkim madt_parse_nmi((ACPI_MADT_NMI_SOURCE *)entry); 546121992Sjhb break; 547167814Sjkim case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 548167814Sjkim madt_parse_local_nmi((ACPI_MADT_LOCAL_APIC_NMI *)entry); 549121992Sjhb break; 550121992Sjhb } 551121992Sjhb} 552121992Sjhb 553121992Sjhb/* 554121992Sjhb * Setup per-CPU ACPI IDs. 555121992Sjhb */ 556121992Sjhbstatic void 557121992Sjhbmadt_set_ids(void *dummy) 558121992Sjhb{ 559129960Sjhb struct lapic_info *la; 560121992Sjhb struct pcpu *pc; 561129960Sjhb u_int i; 562121992Sjhb 563121992Sjhb if (madt == NULL) 564121992Sjhb return; 565209059Sjhb CPU_FOREACH(i) { 566121992Sjhb pc = pcpu_find(i); 567167814Sjkim KASSERT(pc != NULL, ("no pcpu data for CPU %u", i)); 568129960Sjhb la = &lapics[pc->pc_apic_id]; 569130310Sjhb if (!la->la_enabled) 570129960Sjhb panic("APIC: CPU with APIC ID %u is not enabled", 571129960Sjhb pc->pc_apic_id); 572129960Sjhb pc->pc_acpi_id = la->la_acpi_id; 573129960Sjhb if (bootverbose) 574129960Sjhb printf("APIC: CPU %u has ACPI ID %u\n", i, 575129960Sjhb la->la_acpi_id); 576121992Sjhb } 577121992Sjhb} 578256073SgibbsSYSINIT(madt_set_ids, SI_SUB_CPU, SI_ORDER_MIDDLE, madt_set_ids, NULL); 579