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