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