1 /* 2 * Copyright (c) 2009 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Sepherosa Ziehau <sepherosa@gmail.com> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include <sys/param.h> 36 #include <sys/bus.h> 37 #include <sys/kernel.h> 38 #include <sys/systm.h> 39 40 #include <machine_base/isa/isa_intr.h> 41 #include <machine_base/apic/lapic.h> 42 #include <machine_base/apic/ioapic.h> 43 #include <machine_base/apic/apicvar.h> 44 #include <machine_base/acpica/acpi_md_cpu.h> 45 46 #include <contrib/dev/acpica/source/include/acpi.h> 47 48 #include "acpi_sdt_var.h" 49 #include "acpi_sci_var.h" 50 51 extern int naps; 52 53 #define MADT_VPRINTF(fmt, arg...) \ 54 do { \ 55 if (bootverbose) \ 56 kprintf("ACPI MADT: " fmt , ##arg); \ 57 } while (0) 58 59 #define MADT_INT_BUS_ISA 0 60 61 typedef int (*madt_iter_t)(void *, 62 const ACPI_SUBTABLE_HEADER *); 63 64 static int madt_check(vm_paddr_t); 65 static int madt_iterate_entries(ACPI_TABLE_MADT *, 66 madt_iter_t, void *); 67 68 static vm_paddr_t madt_lapic_pass1(void); 69 static int madt_lapic_pass2(int); 70 71 static int madt_lapic_enumerate(struct lapic_enumerator *); 72 static int madt_lapic_probe(struct lapic_enumerator *); 73 74 static void madt_ioapic_enumerate( 75 struct ioapic_enumerator *); 76 static int madt_ioapic_probe(struct ioapic_enumerator *); 77 78 static vm_paddr_t madt_phyaddr; 79 80 static boolean_t madt_use_x2apic = FALSE; 81 82 u_int cpu_id_to_acpi_id[NAPICID]; 83 84 static void 85 madt_probe(void) 86 { 87 vm_paddr_t madt_paddr; 88 int i; 89 90 for (i = 0; i < NAPICID; ++i) 91 CPUID_TO_ACPIID(i) = (u_int)-1; 92 93 KKASSERT(madt_phyaddr == 0); 94 95 madt_paddr = sdt_search(ACPI_SIG_MADT); 96 if (madt_paddr == 0) { 97 kprintf("madt_probe: can't locate MADT\n"); 98 return; 99 } 100 101 /* Preliminary checks */ 102 if (madt_check(madt_paddr)) { 103 kprintf("madt_probe: madt_check failed\n"); 104 return; 105 } 106 107 madt_phyaddr = madt_paddr; 108 } 109 SYSINIT(madt_probe, SI_BOOT2_PRESMP, SI_ORDER_SECOND, madt_probe, 0); 110 111 static int 112 madt_check(vm_paddr_t madt_paddr) 113 { 114 ACPI_TABLE_MADT *madt; 115 int error = 0; 116 117 KKASSERT(madt_paddr != 0); 118 119 madt = sdt_sdth_map(madt_paddr); 120 KKASSERT(madt != NULL); 121 122 /* 123 * MADT in ACPI specification 1.0 - 5.0 124 */ 125 if (madt->Header.Revision < 1 || madt->Header.Revision > 3) { 126 kprintf("madt_check: unknown MADT revision %d\n", 127 madt->Header.Revision); 128 } 129 130 if (madt->Header.Length < sizeof(*madt)) { 131 kprintf("madt_check: invalid MADT length %u\n", 132 madt->Header.Length); 133 error = EINVAL; 134 goto back; 135 } 136 back: 137 sdt_sdth_unmap(&madt->Header); 138 return error; 139 } 140 141 static int 142 madt_iterate_entries(ACPI_TABLE_MADT *madt, madt_iter_t func, void *arg) 143 { 144 int size, cur, error; 145 146 size = madt->Header.Length - sizeof(*madt); 147 cur = 0; 148 error = 0; 149 150 while (size - cur > sizeof(ACPI_SUBTABLE_HEADER)) { 151 const ACPI_SUBTABLE_HEADER *ent; 152 153 ent = (const ACPI_SUBTABLE_HEADER *) 154 ((char *)madt + sizeof(*madt) + cur); 155 if (ent->Length < sizeof(*ent)) { 156 kprintf("madt_iterate_entries: invalid MADT " 157 "entry len %d\n", ent->Length); 158 error = EINVAL; 159 break; 160 } 161 if (ent->Length > (size - cur)) { 162 kprintf("madt_iterate_entries: invalid MADT " 163 "entry len %d, > table length\n", ent->Length); 164 error = EINVAL; 165 break; 166 } 167 168 cur += ent->Length; 169 170 /* 171 * Only Local APIC, I/O APIC and Interrupt Source Override 172 * are defined in ACPI specification 1.0 - 5.0 173 */ 174 switch (ent->Type) { 175 case ACPI_MADT_TYPE_LOCAL_APIC: 176 if (ent->Length < sizeof(ACPI_MADT_LOCAL_APIC)) { 177 kprintf("madt_iterate_entries: invalid MADT " 178 "lapic entry len %d\n", ent->Length); 179 error = EINVAL; 180 } 181 break; 182 183 case ACPI_MADT_TYPE_LOCAL_X2APIC: 184 if (ent->Length < sizeof(ACPI_MADT_LOCAL_X2APIC)) { 185 kprintf("madt_iterate_entries: invalid MADT " 186 "x2apic entry len %d\n", ent->Length); 187 error = EINVAL; 188 } 189 break; 190 191 case ACPI_MADT_TYPE_IO_APIC: 192 if (ent->Length < sizeof(ACPI_MADT_IO_APIC)) { 193 kprintf("madt_iterate_entries: invalid MADT " 194 "ioapic entry len %d\n", ent->Length); 195 error = EINVAL; 196 } 197 break; 198 199 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 200 if (ent->Length < sizeof(ACPI_MADT_INTERRUPT_OVERRIDE)) { 201 kprintf("madt_iterate_entries: invalid MADT " 202 "intsrc entry len %d\n", 203 ent->Length); 204 error = EINVAL; 205 } 206 break; 207 } 208 if (error) 209 break; 210 211 error = func(arg, ent); 212 if (error) 213 break; 214 215 ent = ACPI_ADD_PTR(ACPI_SUBTABLE_HEADER, ent, ent->Length); 216 } 217 return error; 218 } 219 220 static int 221 madt_lapic_pass1_callback(void *xarg, const ACPI_SUBTABLE_HEADER *ent) 222 { 223 const ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_addr_ent; 224 uint64_t *addr64 = xarg; 225 226 if (ent->Type != ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE) 227 return 0; 228 if (ent->Length < sizeof(*lapic_addr_ent)) { 229 kprintf("madt_lapic_pass1: " 230 "invalid LAPIC address override length\n"); 231 return 0; 232 } 233 lapic_addr_ent = (const ACPI_MADT_LOCAL_APIC_OVERRIDE *)ent; 234 235 *addr64 = lapic_addr_ent->Address; 236 return 0; 237 } 238 239 static vm_paddr_t 240 madt_lapic_pass1(void) 241 { 242 ACPI_TABLE_MADT *madt; 243 vm_paddr_t lapic_addr; 244 uint64_t lapic_addr64; 245 int error; 246 247 KKASSERT(madt_phyaddr != 0); 248 249 madt = sdt_sdth_map(madt_phyaddr); 250 KKASSERT(madt != NULL); 251 252 MADT_VPRINTF("LAPIC address 0x%x, flags %#x\n", 253 madt->Address, madt->Flags); 254 lapic_addr = madt->Address; 255 256 lapic_addr64 = 0; 257 error = madt_iterate_entries(madt, madt_lapic_pass1_callback, 258 &lapic_addr64); 259 if (error) 260 panic("madt_iterate_entries(pass1) failed"); 261 262 if (lapic_addr64 != 0) { 263 kprintf("ACPI MADT: 64bits lapic address 0x%lx\n", 264 lapic_addr64); 265 lapic_addr = lapic_addr64; 266 } 267 268 sdt_sdth_unmap(&madt->Header); 269 270 return lapic_addr; 271 } 272 273 struct madt_lapic_pass2_cbarg { 274 int cpu; 275 int bsp_found; 276 int bsp_apic_id; 277 }; 278 279 static int 280 madt_lapic_pass2_callback(void *xarg, const ACPI_SUBTABLE_HEADER *ent) 281 { 282 const ACPI_MADT_LOCAL_APIC *lapic_ent; 283 struct madt_lapic_pass2_cbarg *arg = xarg; 284 285 if (ent->Type != ACPI_MADT_TYPE_LOCAL_APIC) 286 return 0; 287 288 lapic_ent = (const ACPI_MADT_LOCAL_APIC *)ent; 289 if (lapic_ent->LapicFlags & ACPI_MADT_ENABLED) { 290 int cpu; 291 292 if (lapic_ent->Id == arg->bsp_apic_id) { 293 cpu = 0; 294 arg->bsp_found = 1; 295 } else { 296 cpu = arg->cpu; 297 arg->cpu++; 298 } 299 MADT_VPRINTF("cpu id %d, acpi id %d, apic id %d\n", 300 cpu, lapic_ent->ProcessorId, lapic_ent->Id); 301 lapic_set_cpuid(cpu, lapic_ent->Id); 302 CPUID_TO_ACPIID(cpu) = lapic_ent->ProcessorId; 303 } 304 return 0; 305 } 306 307 static int 308 madt_x2apic_pass2_callback(void *xarg, const ACPI_SUBTABLE_HEADER *ent) 309 { 310 const ACPI_MADT_LOCAL_X2APIC *x2apic_ent; 311 struct madt_lapic_pass2_cbarg *arg = xarg; 312 313 if (ent->Type != ACPI_MADT_TYPE_LOCAL_X2APIC) 314 return 0; 315 316 x2apic_ent = (const ACPI_MADT_LOCAL_X2APIC *)ent; 317 if (x2apic_ent->LapicFlags & ACPI_MADT_ENABLED) { 318 int cpu; 319 320 if (x2apic_ent->LocalApicId == arg->bsp_apic_id) { 321 cpu = 0; 322 arg->bsp_found = 1; 323 } else { 324 cpu = arg->cpu; 325 arg->cpu++; 326 } 327 MADT_VPRINTF("cpu id %d, acpi uid %u, apic id %d\n", 328 cpu, x2apic_ent->Uid, x2apic_ent->LocalApicId); 329 lapic_set_cpuid(cpu, x2apic_ent->LocalApicId); 330 CPUID_TO_ACPIID(cpu) = x2apic_ent->Uid; 331 } 332 return 0; 333 } 334 335 static int 336 madt_lapic_pass2(int bsp_apic_id) 337 { 338 ACPI_TABLE_MADT *madt; 339 struct madt_lapic_pass2_cbarg arg; 340 madt_iter_t func; 341 int error; 342 343 MADT_VPRINTF("BSP apic id %d\n", bsp_apic_id); 344 345 KKASSERT(madt_phyaddr != 0); 346 347 madt = sdt_sdth_map(madt_phyaddr); 348 KKASSERT(madt != NULL); 349 350 bzero(&arg, sizeof(arg)); 351 arg.cpu = 1; 352 arg.bsp_apic_id = bsp_apic_id; 353 354 if (madt_use_x2apic) 355 func = madt_x2apic_pass2_callback; 356 else 357 func = madt_lapic_pass2_callback; 358 error = madt_iterate_entries(madt, func, &arg); 359 if (error) 360 panic("madt_iterate_entries(pass2) failed"); 361 362 KKASSERT(arg.bsp_found); 363 naps = arg.cpu - 1; /* exclude BSP */ 364 365 sdt_sdth_unmap(&madt->Header); 366 367 return 0; 368 } 369 370 struct madt_lapic_probe_cbarg { 371 int x2apic_count; 372 int lapic_count; 373 vm_paddr_t lapic_addr; 374 }; 375 376 static int 377 madt_lapic_probe_callback(void *xarg, const ACPI_SUBTABLE_HEADER *ent) 378 { 379 struct madt_lapic_probe_cbarg *arg = xarg; 380 381 if (ent->Type == ACPI_MADT_TYPE_LOCAL_APIC) { 382 const ACPI_MADT_LOCAL_APIC *lapic_ent; 383 384 lapic_ent = (const ACPI_MADT_LOCAL_APIC *)ent; 385 if (lapic_ent->LapicFlags & ACPI_MADT_ENABLED) { 386 arg->lapic_count++; 387 if (lapic_ent->Id == APICID_MAX) { 388 kprintf("madt_lapic_probe: " 389 "invalid LAPIC apic id %d\n", 390 lapic_ent->Id); 391 return EINVAL; 392 } 393 } 394 } else if (ent->Type == ACPI_MADT_TYPE_LOCAL_X2APIC) { 395 const ACPI_MADT_LOCAL_X2APIC *x2apic_ent; 396 397 x2apic_ent = (const ACPI_MADT_LOCAL_X2APIC *)ent; 398 if (x2apic_ent->LapicFlags & ACPI_MADT_ENABLED) { 399 if (x2apic_ent->LocalApicId < APICID_MAX) { 400 /* 401 * XXX we only support APIC ID 0~254 at 402 * the moment. 403 */ 404 arg->x2apic_count++; 405 } 406 } 407 } else if (ent->Type == ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE) { 408 const ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_addr_ent; 409 410 if (ent->Length < sizeof(*lapic_addr_ent)) { 411 kprintf("madt_lapic_probe: " 412 "invalid LAPIC address override length\n"); 413 return 0; 414 } 415 lapic_addr_ent = (const ACPI_MADT_LOCAL_APIC_OVERRIDE *)ent; 416 417 if (lapic_addr_ent->Address != 0) 418 arg->lapic_addr = lapic_addr_ent->Address; 419 } 420 return 0; 421 } 422 423 static int 424 madt_lapic_probe(struct lapic_enumerator *e) 425 { 426 struct madt_lapic_probe_cbarg arg; 427 ACPI_TABLE_MADT *madt; 428 int error; 429 430 if (madt_phyaddr == 0) 431 return ENXIO; 432 433 madt = sdt_sdth_map(madt_phyaddr); 434 KKASSERT(madt != NULL); 435 436 bzero(&arg, sizeof(arg)); 437 arg.lapic_addr = madt->Address; 438 439 error = madt_iterate_entries(madt, madt_lapic_probe_callback, &arg); 440 if (!error) { 441 if (arg.lapic_count == 0 && arg.x2apic_count == 0) { 442 kprintf("madt_lapic_probe: no CPU is found\n"); 443 error = EOPNOTSUPP; 444 } else if (arg.lapic_count == 0) { 445 /* 446 * ACPI 5.1 says that LOCAL_X2APIC entry should 447 * be used only if APIC ID > 255. While ACPI 6.2 448 * removes that constraint, which means that 449 * LOCAL_X2APIC entry could be used for any APIC 450 * ID. 451 * 452 * XXX 453 * In DragonFlyBSD, we don't support APIC ID >= 454 * 255, so LOCAL_X2APIC entries should be ignored, 455 * if LOCAL_X2APIC entries are mixed with 456 * LOCAL_APIC entries. LOCAL_X2APIC entries are 457 * used, iff only LOCAL_X2APIC entries exist. 458 */ 459 madt_use_x2apic = TRUE; 460 kprintf("MADT: use X2APIC entries\n"); 461 } 462 463 if (arg.lapic_addr == 0) { 464 /* 465 * XXX x2apic mode. 466 */ 467 kprintf("madt_lapic_probe: zero LAPIC address\n"); 468 error = EOPNOTSUPP; 469 } 470 } 471 472 sdt_sdth_unmap(&madt->Header); 473 return error; 474 } 475 476 static int 477 madt_lapic_enumerate(struct lapic_enumerator *e) 478 { 479 vm_paddr_t lapic_addr; 480 int bsp_apic_id; 481 482 KKASSERT(madt_phyaddr != 0); 483 484 lapic_addr = madt_lapic_pass1(); 485 if (lapic_addr == 0) 486 panic("madt_lapic_enumerate: no local apic"); 487 488 lapic_map(lapic_addr); 489 490 bsp_apic_id = APIC_ID(lapic->id); 491 if (bsp_apic_id == APICID_MAX) { 492 /* 493 * XXX 494 * Some old brain dead BIOS will set BSP's LAPIC apic id 495 * to 255, though all LAPIC entries in MADT are valid. 496 */ 497 kprintf("%s invalid BSP LAPIC apic id %d\n", __func__, 498 bsp_apic_id); 499 return EINVAL; 500 } 501 502 if (madt_lapic_pass2(bsp_apic_id)) 503 panic("madt_lapic_enumerate: madt_lapic_pass2 failed"); 504 505 return 0; 506 } 507 508 static struct lapic_enumerator madt_lapic_enumerator = { 509 .lapic_prio = LAPIC_ENUM_PRIO_MADT, 510 .lapic_probe = madt_lapic_probe, 511 .lapic_enumerate = madt_lapic_enumerate 512 }; 513 514 static void 515 madt_lapic_enum_register(void) 516 { 517 int prio; 518 519 prio = LAPIC_ENUM_PRIO_MADT; 520 kgetenv_int("hw.madt_lapic_prio", &prio); 521 madt_lapic_enumerator.lapic_prio = prio; 522 523 lapic_enumerator_register(&madt_lapic_enumerator); 524 } 525 SYSINIT(madt_lapic, SI_BOOT2_PRESMP, SI_ORDER_ANY, madt_lapic_enum_register, 0); 526 527 struct madt_ioapic_probe_cbarg { 528 int ioapic_cnt; 529 int gsi_base0; 530 }; 531 532 static int 533 madt_ioapic_probe_callback(void *xarg, const ACPI_SUBTABLE_HEADER *ent) 534 { 535 struct madt_ioapic_probe_cbarg *arg = xarg; 536 537 if (ent->Type == ACPI_MADT_TYPE_INTERRUPT_OVERRIDE) { 538 const ACPI_MADT_INTERRUPT_OVERRIDE *intsrc_ent; 539 int trig, pola; 540 541 intsrc_ent = (const ACPI_MADT_INTERRUPT_OVERRIDE *)ent; 542 543 if (intsrc_ent->SourceIrq >= ISA_IRQ_CNT) { 544 kprintf("madt_ioapic_probe: invalid intsrc irq (%d)\n", 545 intsrc_ent->SourceIrq); 546 return EINVAL; 547 } 548 549 if (intsrc_ent->Bus != MADT_INT_BUS_ISA) { 550 kprintf("ACPI MADT: warning intsrc irq %d " 551 "bus is not ISA (%d)\n", 552 intsrc_ent->SourceIrq, intsrc_ent->Bus); 553 } 554 555 trig = intsrc_ent->IntiFlags & ACPI_MADT_TRIGGER_MASK; 556 if (trig == ACPI_MADT_TRIGGER_RESERVED) { 557 kprintf("ACPI MADT: warning invalid intsrc irq %d " 558 "trig, reserved\n", intsrc_ent->SourceIrq); 559 } else if (trig == ACPI_MADT_TRIGGER_LEVEL) { 560 MADT_VPRINTF("warning invalid intsrc irq %d " 561 "trig, level\n", intsrc_ent->SourceIrq); 562 } 563 564 pola = intsrc_ent->IntiFlags & ACPI_MADT_POLARITY_MASK; 565 if (pola == ACPI_MADT_POLARITY_RESERVED) { 566 kprintf("ACPI MADT: warning invalid intsrc irq %d " 567 "pola, reserved\n", intsrc_ent->SourceIrq); 568 } else if (pola == ACPI_MADT_POLARITY_ACTIVE_LOW) { 569 MADT_VPRINTF("warning invalid intsrc irq %d " 570 "pola, low\n", intsrc_ent->SourceIrq); 571 } 572 } else if (ent->Type == ACPI_MADT_TYPE_IO_APIC) { 573 const ACPI_MADT_IO_APIC *ioapic_ent; 574 575 ioapic_ent = (const ACPI_MADT_IO_APIC *)ent; 576 if (ioapic_ent->Address == 0) { 577 kprintf("madt_ioapic_probe: zero IOAPIC address\n"); 578 return EINVAL; 579 } 580 if (ioapic_ent->Id == APICID_MAX) { 581 kprintf("madt_ioapic_probe: " 582 "invalid IOAPIC apic id %d\n", 583 ioapic_ent->Id); 584 return EINVAL; 585 } 586 587 arg->ioapic_cnt++; 588 if (ioapic_ent->GlobalIrqBase == 0) 589 arg->gsi_base0 = 1; 590 } 591 return 0; 592 } 593 594 static int 595 madt_ioapic_probe(struct ioapic_enumerator *e) 596 { 597 struct madt_ioapic_probe_cbarg arg; 598 ACPI_TABLE_MADT *madt; 599 int error; 600 601 if (madt_phyaddr == 0) 602 return ENXIO; 603 604 madt = sdt_sdth_map(madt_phyaddr); 605 KKASSERT(madt != NULL); 606 607 bzero(&arg, sizeof(arg)); 608 609 error = madt_iterate_entries(madt, madt_ioapic_probe_callback, &arg); 610 if (!error) { 611 if (arg.ioapic_cnt == 0) { 612 kprintf("madt_ioapic_probe: no IOAPIC\n"); 613 error = ENXIO; 614 } 615 if (!arg.gsi_base0) { 616 kprintf("madt_ioapic_probe: no GSI base 0\n"); 617 error = EINVAL; 618 } 619 } 620 621 sdt_sdth_unmap(&madt->Header); 622 return error; 623 } 624 625 static int 626 madt_ioapic_enum_callback(void *xarg, const ACPI_SUBTABLE_HEADER *ent) 627 { 628 if (ent->Type == ACPI_MADT_TYPE_INTERRUPT_OVERRIDE) { 629 const ACPI_MADT_INTERRUPT_OVERRIDE *intsrc_ent; 630 enum intr_trigger trig; 631 enum intr_polarity pola; 632 int ent_trig, ent_pola; 633 634 intsrc_ent = (const ACPI_MADT_INTERRUPT_OVERRIDE *)ent; 635 636 KKASSERT(intsrc_ent->SourceIrq < ISA_IRQ_CNT); 637 if (intsrc_ent->Bus != MADT_INT_BUS_ISA) 638 return 0; 639 640 ent_trig = intsrc_ent->IntiFlags & ACPI_MADT_TRIGGER_MASK; 641 if (ent_trig == ACPI_MADT_TRIGGER_RESERVED) 642 return 0; 643 else if (ent_trig == ACPI_MADT_TRIGGER_LEVEL) 644 trig = INTR_TRIGGER_LEVEL; 645 else 646 trig = INTR_TRIGGER_EDGE; 647 648 ent_pola = intsrc_ent->IntiFlags & ACPI_MADT_POLARITY_MASK; 649 if (ent_pola == ACPI_MADT_POLARITY_RESERVED) 650 return 0; 651 else if (ent_pola == ACPI_MADT_POLARITY_ACTIVE_LOW) 652 pola = INTR_POLARITY_LOW; 653 else 654 pola = INTR_POLARITY_HIGH; 655 656 if (intsrc_ent->SourceIrq == acpi_sci_irqno()) { 657 acpi_sci_setmode1(trig, pola); 658 MADT_VPRINTF("SCI irq %d, first test %s/%s\n", 659 intsrc_ent->SourceIrq, 660 intr_str_trigger(trig), intr_str_polarity(pola)); 661 } 662 663 /* 664 * We ignore the polarity and trigger changes, since 665 * most of them are wrong or useless at best. 666 */ 667 if (intsrc_ent->SourceIrq == intsrc_ent->GlobalIrq) { 668 /* Nothing changed */ 669 return 0; 670 } 671 trig = INTR_TRIGGER_EDGE; 672 pola = INTR_POLARITY_HIGH; 673 674 MADT_VPRINTF("INTSRC irq %d -> gsi %u %s/%s\n", 675 intsrc_ent->SourceIrq, intsrc_ent->GlobalIrq, 676 intr_str_trigger(trig), intr_str_polarity(pola)); 677 ioapic_intsrc(intsrc_ent->SourceIrq, intsrc_ent->GlobalIrq, 678 trig, pola); 679 } else if (ent->Type == ACPI_MADT_TYPE_IO_APIC) { 680 const ACPI_MADT_IO_APIC *ioapic_ent; 681 uint32_t ver; 682 void *addr; 683 int npin; 684 685 ioapic_ent = (const ACPI_MADT_IO_APIC *)ent; 686 MADT_VPRINTF("IOAPIC addr 0x%08x, apic id %d, gsi base %u\n", 687 ioapic_ent->Address, ioapic_ent->Id, 688 ioapic_ent->GlobalIrqBase); 689 690 addr = ioapic_map(ioapic_ent->Address); 691 692 ver = ioapic_read(addr, IOAPIC_VER); 693 npin = ((ver & IOART_VER_MAXREDIR) >> MAXREDIRSHIFT) + 1; 694 695 ioapic_add(addr, ioapic_ent->GlobalIrqBase, npin); 696 } 697 return 0; 698 } 699 700 static void 701 madt_ioapic_enumerate(struct ioapic_enumerator *e) 702 { 703 ACPI_TABLE_MADT *madt; 704 int error; 705 706 KKASSERT(madt_phyaddr != 0); 707 708 madt = sdt_sdth_map(madt_phyaddr); 709 KKASSERT(madt != NULL); 710 711 error = madt_iterate_entries(madt, madt_ioapic_enum_callback, NULL); 712 if (error) 713 panic("madt_ioapic_enumerate failed"); 714 715 sdt_sdth_unmap(&madt->Header); 716 } 717 718 static struct ioapic_enumerator madt_ioapic_enumerator = { 719 .ioapic_prio = IOAPIC_ENUM_PRIO_MADT, 720 .ioapic_probe = madt_ioapic_probe, 721 .ioapic_enumerate = madt_ioapic_enumerate 722 }; 723 724 static void 725 madt_ioapic_enum_register(void) 726 { 727 int prio; 728 729 prio = IOAPIC_ENUM_PRIO_MADT; 730 kgetenv_int("hw.madt_ioapic_prio", &prio); 731 madt_ioapic_enumerator.ioapic_prio = prio; 732 733 ioapic_enumerator_register(&madt_ioapic_enumerator); 734 } 735 SYSINIT(madt_ioapic, SI_BOOT2_PRESMP, SI_ORDER_ANY, 736 madt_ioapic_enum_register, 0); 737