1/*- 2 * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: stable/10/sys/x86/x86/io_apic.c 330959 2018-03-14 23:59:52Z marius $"); 29 30#include "opt_isa.h" 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/bus.h> 35#include <sys/kernel.h> 36#include <sys/lock.h> 37#include <sys/malloc.h> 38#include <sys/module.h> 39#include <sys/mutex.h> 40#include <sys/sysctl.h> 41 42#include <dev/pci/pcireg.h> 43#include <dev/pci/pcivar.h> 44 45#include <vm/vm.h> 46#include <vm/pmap.h> 47 48#include <x86/apicreg.h> 49#include <machine/frame.h> 50#include <machine/intr_machdep.h> 51#include <machine/apicvar.h> 52#include <machine/resource.h> 53#include <machine/segments.h> 54 55#define IOAPIC_ISA_INTS 16 56#define IOAPIC_MEM_REGION 32 57#define IOAPIC_REDTBL_LO(i) (IOAPIC_REDTBL + (i) * 2) 58#define IOAPIC_REDTBL_HI(i) (IOAPIC_REDTBL_LO(i) + 1) 59 60#define IRQ_EXTINT (NUM_IO_INTS + 1) 61#define IRQ_NMI (NUM_IO_INTS + 2) 62#define IRQ_SMI (NUM_IO_INTS + 3) 63#define IRQ_DISABLED (NUM_IO_INTS + 4) 64 65static MALLOC_DEFINE(M_IOAPIC, "io_apic", "I/O APIC structures"); 66 67/* 68 * I/O APIC interrupt source driver. Each pin is assigned an IRQ cookie 69 * as laid out in the ACPI System Interrupt number model where each I/O 70 * APIC has a contiguous chunk of the System Interrupt address space. 71 * We assume that IRQs 1 - 15 behave like ISA IRQs and that all other 72 * IRQs behave as PCI IRQs by default. We also assume that the pin for 73 * IRQ 0 is actually an ExtINT pin. The apic enumerators override the 74 * configuration of individual pins as indicated by their tables. 75 * 76 * Documentation for the I/O APIC: "82093AA I/O Advanced Programmable 77 * Interrupt Controller (IOAPIC)", May 1996, Intel Corp. 78 * ftp://download.intel.com/design/chipsets/datashts/29056601.pdf 79 */ 80 81struct ioapic_intsrc { 82 struct intsrc io_intsrc; 83 u_int io_irq; 84 u_int io_intpin:8; 85 u_int io_vector:8; 86 u_int io_cpu:8; 87 u_int io_activehi:1; 88 u_int io_edgetrigger:1; 89 u_int io_masked:1; 90 int io_bus:4; 91 uint32_t io_lowreg; 92}; 93 94struct ioapic { 95 struct pic io_pic; 96 u_int io_id:8; /* logical ID */ 97 u_int io_apic_id:4; 98 u_int io_intbase:8; /* System Interrupt base */ 99 u_int io_numintr:8; 100 volatile ioapic_t *io_addr; /* XXX: should use bus_space */ 101 vm_paddr_t io_paddr; 102 STAILQ_ENTRY(ioapic) io_next; 103 struct ioapic_intsrc io_pins[0]; 104}; 105 106static u_int ioapic_read(volatile ioapic_t *apic, int reg); 107static void ioapic_write(volatile ioapic_t *apic, int reg, u_int val); 108static const char *ioapic_bus_string(int bus_type); 109static void ioapic_print_irq(struct ioapic_intsrc *intpin); 110static void ioapic_enable_source(struct intsrc *isrc); 111static void ioapic_disable_source(struct intsrc *isrc, int eoi); 112static void ioapic_eoi_source(struct intsrc *isrc); 113static void ioapic_enable_intr(struct intsrc *isrc); 114static void ioapic_disable_intr(struct intsrc *isrc); 115static int ioapic_vector(struct intsrc *isrc); 116static int ioapic_source_pending(struct intsrc *isrc); 117static int ioapic_config_intr(struct intsrc *isrc, enum intr_trigger trig, 118 enum intr_polarity pol); 119static void ioapic_resume(struct pic *pic, bool suspend_cancelled); 120static int ioapic_assign_cpu(struct intsrc *isrc, u_int apic_id); 121static void ioapic_program_intpin(struct ioapic_intsrc *intpin); 122 123static STAILQ_HEAD(,ioapic) ioapic_list = STAILQ_HEAD_INITIALIZER(ioapic_list); 124struct pic ioapic_template = { ioapic_enable_source, ioapic_disable_source, 125 ioapic_eoi_source, ioapic_enable_intr, 126 ioapic_disable_intr, ioapic_vector, 127 ioapic_source_pending, NULL, ioapic_resume, 128 ioapic_config_intr, ioapic_assign_cpu }; 129 130static int next_ioapic_base; 131static u_int next_id; 132 133static SYSCTL_NODE(_hw, OID_AUTO, apic, CTLFLAG_RD, 0, "APIC options"); 134static int enable_extint; 135SYSCTL_INT(_hw_apic, OID_AUTO, enable_extint, CTLFLAG_RDTUN, &enable_extint, 0, 136 "Enable the ExtINT pin in the first I/O APIC"); 137TUNABLE_INT("hw.apic.enable_extint", &enable_extint); 138 139static __inline void 140_ioapic_eoi_source(struct intsrc *isrc) 141{ 142 lapic_eoi(); 143} 144 145static u_int 146ioapic_read(volatile ioapic_t *apic, int reg) 147{ 148 149 mtx_assert(&icu_lock, MA_OWNED); 150 apic->ioregsel = reg; 151 return (apic->iowin); 152} 153 154static void 155ioapic_write(volatile ioapic_t *apic, int reg, u_int val) 156{ 157 158 mtx_assert(&icu_lock, MA_OWNED); 159 apic->ioregsel = reg; 160 apic->iowin = val; 161} 162 163static const char * 164ioapic_bus_string(int bus_type) 165{ 166 167 switch (bus_type) { 168 case APIC_BUS_ISA: 169 return ("ISA"); 170 case APIC_BUS_EISA: 171 return ("EISA"); 172 case APIC_BUS_PCI: 173 return ("PCI"); 174 default: 175 return ("unknown"); 176 } 177} 178 179static void 180ioapic_print_irq(struct ioapic_intsrc *intpin) 181{ 182 183 switch (intpin->io_irq) { 184 case IRQ_DISABLED: 185 printf("disabled"); 186 break; 187 case IRQ_EXTINT: 188 printf("ExtINT"); 189 break; 190 case IRQ_NMI: 191 printf("NMI"); 192 break; 193 case IRQ_SMI: 194 printf("SMI"); 195 break; 196 default: 197 printf("%s IRQ %u", ioapic_bus_string(intpin->io_bus), 198 intpin->io_irq); 199 } 200} 201 202static void 203ioapic_enable_source(struct intsrc *isrc) 204{ 205 struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc; 206 struct ioapic *io = (struct ioapic *)isrc->is_pic; 207 uint32_t flags; 208 209 mtx_lock_spin(&icu_lock); 210 if (intpin->io_masked) { 211 flags = intpin->io_lowreg & ~IOART_INTMASK; 212 ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), 213 flags); 214 intpin->io_masked = 0; 215 } 216 mtx_unlock_spin(&icu_lock); 217} 218 219static void 220ioapic_disable_source(struct intsrc *isrc, int eoi) 221{ 222 struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc; 223 struct ioapic *io = (struct ioapic *)isrc->is_pic; 224 uint32_t flags; 225 226 mtx_lock_spin(&icu_lock); 227 if (!intpin->io_masked && !intpin->io_edgetrigger) { 228 flags = intpin->io_lowreg | IOART_INTMSET; 229 ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), 230 flags); 231 intpin->io_masked = 1; 232 } 233 234 if (eoi == PIC_EOI) 235 _ioapic_eoi_source(isrc); 236 237 mtx_unlock_spin(&icu_lock); 238} 239 240static void 241ioapic_eoi_source(struct intsrc *isrc) 242{ 243 244 _ioapic_eoi_source(isrc); 245} 246 247/* 248 * Completely program an intpin based on the data in its interrupt source 249 * structure. 250 */ 251static void 252ioapic_program_intpin(struct ioapic_intsrc *intpin) 253{ 254 struct ioapic *io = (struct ioapic *)intpin->io_intsrc.is_pic; 255 uint32_t low, high; 256 257 /* 258 * If a pin is completely invalid or if it is valid but hasn't 259 * been enabled yet, just ensure that the pin is masked. 260 */ 261 mtx_assert(&icu_lock, MA_OWNED); 262 if (intpin->io_irq == IRQ_DISABLED || (intpin->io_irq < NUM_IO_INTS && 263 intpin->io_vector == 0)) { 264 low = ioapic_read(io->io_addr, 265 IOAPIC_REDTBL_LO(intpin->io_intpin)); 266 if ((low & IOART_INTMASK) == IOART_INTMCLR) 267 ioapic_write(io->io_addr, 268 IOAPIC_REDTBL_LO(intpin->io_intpin), 269 low | IOART_INTMSET); 270 return; 271 } 272 273 /* 274 * Set the destination. Note that with Intel interrupt remapping, 275 * the previously reserved bits 55:48 now have a purpose so ensure 276 * these are zero. 277 */ 278 low = IOART_DESTPHY; 279 high = intpin->io_cpu << APIC_ID_SHIFT; 280 281 /* Program the rest of the low word. */ 282 if (intpin->io_edgetrigger) 283 low |= IOART_TRGREDG; 284 else 285 low |= IOART_TRGRLVL; 286 if (intpin->io_activehi) 287 low |= IOART_INTAHI; 288 else 289 low |= IOART_INTALO; 290 if (intpin->io_masked) 291 low |= IOART_INTMSET; 292 switch (intpin->io_irq) { 293 case IRQ_EXTINT: 294 KASSERT(intpin->io_edgetrigger, 295 ("ExtINT not edge triggered")); 296 low |= IOART_DELEXINT; 297 break; 298 case IRQ_NMI: 299 KASSERT(intpin->io_edgetrigger, 300 ("NMI not edge triggered")); 301 low |= IOART_DELNMI; 302 break; 303 case IRQ_SMI: 304 KASSERT(intpin->io_edgetrigger, 305 ("SMI not edge triggered")); 306 low |= IOART_DELSMI; 307 break; 308 default: 309 KASSERT(intpin->io_vector != 0, ("No vector for IRQ %u", 310 intpin->io_irq)); 311 low |= IOART_DELFIXED | intpin->io_vector; 312 } 313 314 /* Write the values to the APIC. */ 315 ioapic_write(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin), high); 316 intpin->io_lowreg = low; 317 ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low); 318} 319 320static int 321ioapic_assign_cpu(struct intsrc *isrc, u_int apic_id) 322{ 323 struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc; 324 struct ioapic *io = (struct ioapic *)isrc->is_pic; 325 u_int old_vector, new_vector; 326 u_int old_id; 327 328 /* 329 * On Hyper-V: 330 * - Stick to the first cpu for all I/O APIC pins. 331 * - And don't allow destination cpu changes. 332 */ 333 if (vm_guest == VM_GUEST_HV) { 334 if (intpin->io_vector) 335 return (EINVAL); 336 else 337 apic_id = 0; 338 } 339 340 /* 341 * keep 1st core as the destination for NMI 342 */ 343 if (intpin->io_irq == IRQ_NMI) 344 apic_id = 0; 345 346 /* 347 * Set us up to free the old irq. 348 */ 349 old_vector = intpin->io_vector; 350 old_id = intpin->io_cpu; 351 if (old_vector && apic_id == old_id) 352 return (0); 353 354 /* 355 * Allocate an APIC vector for this interrupt pin. Once 356 * we have a vector we program the interrupt pin. 357 */ 358 new_vector = apic_alloc_vector(apic_id, intpin->io_irq); 359 if (new_vector == 0) 360 return (ENOSPC); 361 362 /* 363 * Mask the old intpin if it is enabled while it is migrated. 364 * 365 * At least some level-triggered interrupts seem to need the 366 * extra DELAY() to avoid being stuck in a non-EOI'd state. 367 */ 368 mtx_lock_spin(&icu_lock); 369 if (!intpin->io_masked && !intpin->io_edgetrigger) { 370 ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), 371 intpin->io_lowreg | IOART_INTMSET); 372 mtx_unlock_spin(&icu_lock); 373 DELAY(100); 374 mtx_lock_spin(&icu_lock); 375 } 376 377 intpin->io_cpu = apic_id; 378 intpin->io_vector = new_vector; 379 if (isrc->is_handlers > 0) 380 apic_enable_vector(intpin->io_cpu, intpin->io_vector); 381 if (bootverbose) { 382 printf("ioapic%u: routing intpin %u (", io->io_id, 383 intpin->io_intpin); 384 ioapic_print_irq(intpin); 385 printf(") to lapic %u vector %u\n", intpin->io_cpu, 386 intpin->io_vector); 387 } 388 ioapic_program_intpin(intpin); 389 mtx_unlock_spin(&icu_lock); 390 391 /* 392 * Free the old vector after the new one is established. This is done 393 * to prevent races where we could miss an interrupt. 394 */ 395 if (old_vector) { 396 if (isrc->is_handlers > 0) 397 apic_disable_vector(old_id, old_vector); 398 apic_free_vector(old_id, old_vector, intpin->io_irq); 399 } 400 return (0); 401} 402 403static void 404ioapic_enable_intr(struct intsrc *isrc) 405{ 406 struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc; 407 408 if (intpin->io_vector == 0) 409 if (ioapic_assign_cpu(isrc, intr_next_cpu()) != 0) 410 panic("Couldn't find an APIC vector for IRQ %d", 411 intpin->io_irq); 412 apic_enable_vector(intpin->io_cpu, intpin->io_vector); 413} 414 415 416static void 417ioapic_disable_intr(struct intsrc *isrc) 418{ 419 struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc; 420 u_int vector; 421 422 if (intpin->io_vector != 0) { 423 /* Mask this interrupt pin and free its APIC vector. */ 424 vector = intpin->io_vector; 425 apic_disable_vector(intpin->io_cpu, vector); 426 mtx_lock_spin(&icu_lock); 427 intpin->io_masked = 1; 428 intpin->io_vector = 0; 429 ioapic_program_intpin(intpin); 430 mtx_unlock_spin(&icu_lock); 431 apic_free_vector(intpin->io_cpu, vector, intpin->io_irq); 432 } 433} 434 435static int 436ioapic_vector(struct intsrc *isrc) 437{ 438 struct ioapic_intsrc *pin; 439 440 pin = (struct ioapic_intsrc *)isrc; 441 return (pin->io_irq); 442} 443 444static int 445ioapic_source_pending(struct intsrc *isrc) 446{ 447 struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc; 448 449 if (intpin->io_vector == 0) 450 return 0; 451 return (lapic_intr_pending(intpin->io_vector)); 452} 453 454static int 455ioapic_config_intr(struct intsrc *isrc, enum intr_trigger trig, 456 enum intr_polarity pol) 457{ 458 struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc; 459 struct ioapic *io = (struct ioapic *)isrc->is_pic; 460 int changed; 461 462 KASSERT(!(trig == INTR_TRIGGER_CONFORM || pol == INTR_POLARITY_CONFORM), 463 ("%s: Conforming trigger or polarity\n", __func__)); 464 465 /* 466 * EISA interrupts always use active high polarity, so don't allow 467 * them to be set to active low. 468 * 469 * XXX: Should we write to the ELCR if the trigger mode changes for 470 * an EISA IRQ or an ISA IRQ with the ELCR present? 471 */ 472 mtx_lock_spin(&icu_lock); 473 if (intpin->io_bus == APIC_BUS_EISA) 474 pol = INTR_POLARITY_HIGH; 475 changed = 0; 476 if (intpin->io_edgetrigger != (trig == INTR_TRIGGER_EDGE)) { 477 if (bootverbose) 478 printf("ioapic%u: Changing trigger for pin %u to %s\n", 479 io->io_id, intpin->io_intpin, 480 trig == INTR_TRIGGER_EDGE ? "edge" : "level"); 481 intpin->io_edgetrigger = (trig == INTR_TRIGGER_EDGE); 482 changed++; 483 } 484 if (intpin->io_activehi != (pol == INTR_POLARITY_HIGH)) { 485 if (bootverbose) 486 printf("ioapic%u: Changing polarity for pin %u to %s\n", 487 io->io_id, intpin->io_intpin, 488 pol == INTR_POLARITY_HIGH ? "high" : "low"); 489 intpin->io_activehi = (pol == INTR_POLARITY_HIGH); 490 changed++; 491 } 492 if (changed) 493 ioapic_program_intpin(intpin); 494 mtx_unlock_spin(&icu_lock); 495 return (0); 496} 497 498static void 499ioapic_resume(struct pic *pic, bool suspend_cancelled) 500{ 501 struct ioapic *io = (struct ioapic *)pic; 502 int i; 503 504 mtx_lock_spin(&icu_lock); 505 for (i = 0; i < io->io_numintr; i++) 506 ioapic_program_intpin(&io->io_pins[i]); 507 mtx_unlock_spin(&icu_lock); 508} 509 510/* 511 * Create a plain I/O APIC object. 512 */ 513void * 514ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase) 515{ 516 struct ioapic *io; 517 struct ioapic_intsrc *intpin; 518 volatile ioapic_t *apic; 519 u_int numintr, i; 520 uint32_t value; 521 522 /* Map the register window so we can access the device. */ 523 apic = pmap_mapdev(addr, IOAPIC_MEM_REGION); 524 mtx_lock_spin(&icu_lock); 525 value = ioapic_read(apic, IOAPIC_VER); 526 mtx_unlock_spin(&icu_lock); 527 528 /* If it's version register doesn't seem to work, punt. */ 529 if (value == 0xffffffff) { 530 pmap_unmapdev((vm_offset_t)apic, IOAPIC_MEM_REGION); 531 return (NULL); 532 } 533 534 /* Determine the number of vectors and set the APIC ID. */ 535 numintr = ((value & IOART_VER_MAXREDIR) >> MAXREDIRSHIFT) + 1; 536 io = malloc(sizeof(struct ioapic) + 537 numintr * sizeof(struct ioapic_intsrc), M_IOAPIC, M_WAITOK); 538 io->io_pic = ioapic_template; 539 mtx_lock_spin(&icu_lock); 540 io->io_id = next_id++; 541 io->io_apic_id = ioapic_read(apic, IOAPIC_ID) >> APIC_ID_SHIFT; 542 if (apic_id != -1 && io->io_apic_id != apic_id) { 543 ioapic_write(apic, IOAPIC_ID, apic_id << APIC_ID_SHIFT); 544 mtx_unlock_spin(&icu_lock); 545 io->io_apic_id = apic_id; 546 printf("ioapic%u: Changing APIC ID to %d\n", io->io_id, 547 apic_id); 548 } else 549 mtx_unlock_spin(&icu_lock); 550 if (intbase == -1) { 551 intbase = next_ioapic_base; 552 printf("ioapic%u: Assuming intbase of %d\n", io->io_id, 553 intbase); 554 } else if (intbase != next_ioapic_base && bootverbose) 555 printf("ioapic%u: WARNING: intbase %d != expected base %d\n", 556 io->io_id, intbase, next_ioapic_base); 557 io->io_intbase = intbase; 558 next_ioapic_base = intbase + numintr; 559 io->io_numintr = numintr; 560 io->io_addr = apic; 561 io->io_paddr = addr; 562 563 /* 564 * Initialize pins. Start off with interrupts disabled. Default 565 * to active-hi and edge-triggered for ISA interrupts and active-lo 566 * and level-triggered for all others. 567 */ 568 bzero(io->io_pins, sizeof(struct ioapic_intsrc) * numintr); 569 mtx_lock_spin(&icu_lock); 570 for (i = 0, intpin = io->io_pins; i < numintr; i++, intpin++) { 571 intpin->io_intsrc.is_pic = (struct pic *)io; 572 intpin->io_intpin = i; 573 intpin->io_irq = intbase + i; 574 575 /* 576 * Assume that pin 0 on the first I/O APIC is an ExtINT pin. 577 * Assume that pins 1-15 are ISA interrupts and that all 578 * other pins are PCI interrupts. 579 */ 580 if (intpin->io_irq == 0) 581 ioapic_set_extint(io, i); 582 else if (intpin->io_irq < IOAPIC_ISA_INTS) { 583 intpin->io_bus = APIC_BUS_ISA; 584 intpin->io_activehi = 1; 585 intpin->io_edgetrigger = 1; 586 intpin->io_masked = 1; 587 } else { 588 intpin->io_bus = APIC_BUS_PCI; 589 intpin->io_activehi = 0; 590 intpin->io_edgetrigger = 0; 591 intpin->io_masked = 1; 592 } 593 594 /* 595 * Route interrupts to the BSP by default. Interrupts may 596 * be routed to other CPUs later after they are enabled. 597 */ 598 intpin->io_cpu = PCPU_GET(apic_id); 599 value = ioapic_read(apic, IOAPIC_REDTBL_LO(i)); 600 ioapic_write(apic, IOAPIC_REDTBL_LO(i), value | IOART_INTMSET); 601 } 602 mtx_unlock_spin(&icu_lock); 603 604 return (io); 605} 606 607int 608ioapic_get_vector(void *cookie, u_int pin) 609{ 610 struct ioapic *io; 611 612 io = (struct ioapic *)cookie; 613 if (pin >= io->io_numintr) 614 return (-1); 615 return (io->io_pins[pin].io_irq); 616} 617 618int 619ioapic_disable_pin(void *cookie, u_int pin) 620{ 621 struct ioapic *io; 622 623 io = (struct ioapic *)cookie; 624 if (pin >= io->io_numintr) 625 return (EINVAL); 626 if (io->io_pins[pin].io_irq == IRQ_DISABLED) 627 return (EINVAL); 628 io->io_pins[pin].io_irq = IRQ_DISABLED; 629 if (bootverbose) 630 printf("ioapic%u: intpin %d disabled\n", io->io_id, pin); 631 return (0); 632} 633 634int 635ioapic_remap_vector(void *cookie, u_int pin, int vector) 636{ 637 struct ioapic *io; 638 639 io = (struct ioapic *)cookie; 640 if (pin >= io->io_numintr || vector < 0) 641 return (EINVAL); 642 if (io->io_pins[pin].io_irq >= NUM_IO_INTS) 643 return (EINVAL); 644 io->io_pins[pin].io_irq = vector; 645 if (bootverbose) 646 printf("ioapic%u: Routing IRQ %d -> intpin %d\n", io->io_id, 647 vector, pin); 648 return (0); 649} 650 651int 652ioapic_set_bus(void *cookie, u_int pin, int bus_type) 653{ 654 struct ioapic *io; 655 656 if (bus_type < 0 || bus_type > APIC_BUS_MAX) 657 return (EINVAL); 658 io = (struct ioapic *)cookie; 659 if (pin >= io->io_numintr) 660 return (EINVAL); 661 if (io->io_pins[pin].io_irq >= NUM_IO_INTS) 662 return (EINVAL); 663 if (io->io_pins[pin].io_bus == bus_type) 664 return (0); 665 io->io_pins[pin].io_bus = bus_type; 666 if (bootverbose) 667 printf("ioapic%u: intpin %d bus %s\n", io->io_id, pin, 668 ioapic_bus_string(bus_type)); 669 return (0); 670} 671 672int 673ioapic_set_nmi(void *cookie, u_int pin) 674{ 675 struct ioapic *io; 676 677 io = (struct ioapic *)cookie; 678 if (pin >= io->io_numintr) 679 return (EINVAL); 680 if (io->io_pins[pin].io_irq == IRQ_NMI) 681 return (0); 682 if (io->io_pins[pin].io_irq >= NUM_IO_INTS) 683 return (EINVAL); 684 io->io_pins[pin].io_bus = APIC_BUS_UNKNOWN; 685 io->io_pins[pin].io_irq = IRQ_NMI; 686 io->io_pins[pin].io_masked = 0; 687 io->io_pins[pin].io_edgetrigger = 1; 688 io->io_pins[pin].io_activehi = 1; 689 if (bootverbose) 690 printf("ioapic%u: Routing NMI -> intpin %d\n", 691 io->io_id, pin); 692 return (0); 693} 694 695int 696ioapic_set_smi(void *cookie, u_int pin) 697{ 698 struct ioapic *io; 699 700 io = (struct ioapic *)cookie; 701 if (pin >= io->io_numintr) 702 return (EINVAL); 703 if (io->io_pins[pin].io_irq == IRQ_SMI) 704 return (0); 705 if (io->io_pins[pin].io_irq >= NUM_IO_INTS) 706 return (EINVAL); 707 io->io_pins[pin].io_bus = APIC_BUS_UNKNOWN; 708 io->io_pins[pin].io_irq = IRQ_SMI; 709 io->io_pins[pin].io_masked = 0; 710 io->io_pins[pin].io_edgetrigger = 1; 711 io->io_pins[pin].io_activehi = 1; 712 if (bootverbose) 713 printf("ioapic%u: Routing SMI -> intpin %d\n", 714 io->io_id, pin); 715 return (0); 716} 717 718int 719ioapic_set_extint(void *cookie, u_int pin) 720{ 721 struct ioapic *io; 722 723 io = (struct ioapic *)cookie; 724 if (pin >= io->io_numintr) 725 return (EINVAL); 726 if (io->io_pins[pin].io_irq == IRQ_EXTINT) 727 return (0); 728 if (io->io_pins[pin].io_irq >= NUM_IO_INTS) 729 return (EINVAL); 730 io->io_pins[pin].io_bus = APIC_BUS_UNKNOWN; 731 io->io_pins[pin].io_irq = IRQ_EXTINT; 732 if (enable_extint) 733 io->io_pins[pin].io_masked = 0; 734 else 735 io->io_pins[pin].io_masked = 1; 736 io->io_pins[pin].io_edgetrigger = 1; 737 io->io_pins[pin].io_activehi = 1; 738 if (bootverbose) 739 printf("ioapic%u: Routing external 8259A's -> intpin %d\n", 740 io->io_id, pin); 741 return (0); 742} 743 744int 745ioapic_set_polarity(void *cookie, u_int pin, enum intr_polarity pol) 746{ 747 struct ioapic *io; 748 int activehi; 749 750 io = (struct ioapic *)cookie; 751 if (pin >= io->io_numintr || pol == INTR_POLARITY_CONFORM) 752 return (EINVAL); 753 if (io->io_pins[pin].io_irq >= NUM_IO_INTS) 754 return (EINVAL); 755 activehi = (pol == INTR_POLARITY_HIGH); 756 if (io->io_pins[pin].io_activehi == activehi) 757 return (0); 758 io->io_pins[pin].io_activehi = activehi; 759 if (bootverbose) 760 printf("ioapic%u: intpin %d polarity: %s\n", io->io_id, pin, 761 pol == INTR_POLARITY_HIGH ? "high" : "low"); 762 return (0); 763} 764 765int 766ioapic_set_triggermode(void *cookie, u_int pin, enum intr_trigger trigger) 767{ 768 struct ioapic *io; 769 int edgetrigger; 770 771 io = (struct ioapic *)cookie; 772 if (pin >= io->io_numintr || trigger == INTR_TRIGGER_CONFORM) 773 return (EINVAL); 774 if (io->io_pins[pin].io_irq >= NUM_IO_INTS) 775 return (EINVAL); 776 edgetrigger = (trigger == INTR_TRIGGER_EDGE); 777 if (io->io_pins[pin].io_edgetrigger == edgetrigger) 778 return (0); 779 io->io_pins[pin].io_edgetrigger = edgetrigger; 780 if (bootverbose) 781 printf("ioapic%u: intpin %d trigger: %s\n", io->io_id, pin, 782 trigger == INTR_TRIGGER_EDGE ? "edge" : "level"); 783 return (0); 784} 785 786/* 787 * Register a complete I/O APIC object with the interrupt subsystem. 788 */ 789void 790ioapic_register(void *cookie) 791{ 792 struct ioapic_intsrc *pin; 793 struct ioapic *io; 794 volatile ioapic_t *apic; 795 uint32_t flags; 796 int i; 797 798 io = (struct ioapic *)cookie; 799 apic = io->io_addr; 800 mtx_lock_spin(&icu_lock); 801 flags = ioapic_read(apic, IOAPIC_VER) & IOART_VER_VERSION; 802 STAILQ_INSERT_TAIL(&ioapic_list, io, io_next); 803 mtx_unlock_spin(&icu_lock); 804 printf("ioapic%u <Version %u.%u> irqs %u-%u on motherboard\n", 805 io->io_id, flags >> 4, flags & 0xf, io->io_intbase, 806 io->io_intbase + io->io_numintr - 1); 807 808 /* 809 * Reprogram pins to handle special case pins (such as NMI and 810 * SMI) and register valid pins as interrupt sources. 811 */ 812 intr_register_pic(&io->io_pic); 813 for (i = 0, pin = io->io_pins; i < io->io_numintr; i++, pin++) { 814 mtx_lock_spin(&icu_lock); 815 ioapic_program_intpin(pin); 816 mtx_unlock_spin(&icu_lock); 817 if (pin->io_irq < NUM_IO_INTS) 818 intr_register_source(&pin->io_intsrc); 819 } 820} 821 822/* A simple new-bus driver to consume PCI I/O APIC devices. */ 823static int 824ioapic_pci_probe(device_t dev) 825{ 826 827 if (pci_get_class(dev) == PCIC_BASEPERIPH && 828 pci_get_subclass(dev) == PCIS_BASEPERIPH_PIC) { 829 switch (pci_get_progif(dev)) { 830 case PCIP_BASEPERIPH_PIC_IO_APIC: 831 device_set_desc(dev, "IO APIC"); 832 break; 833 case PCIP_BASEPERIPH_PIC_IOX_APIC: 834 device_set_desc(dev, "IO(x) APIC"); 835 break; 836 default: 837 return (ENXIO); 838 } 839 device_quiet(dev); 840 return (-10000); 841 } 842 return (ENXIO); 843} 844 845static int 846ioapic_pci_attach(device_t dev) 847{ 848 849 return (0); 850} 851 852static device_method_t ioapic_pci_methods[] = { 853 /* Device interface */ 854 DEVMETHOD(device_probe, ioapic_pci_probe), 855 DEVMETHOD(device_attach, ioapic_pci_attach), 856 857 { 0, 0 } 858}; 859 860DEFINE_CLASS_0(ioapic, ioapic_pci_driver, ioapic_pci_methods, 0); 861 862static devclass_t ioapic_devclass; 863DRIVER_MODULE(ioapic, pci, ioapic_pci_driver, ioapic_devclass, 0, 0); 864 865/* 866 * A new-bus driver to consume the memory resources associated with 867 * the APICs in the system. On some systems ACPI or PnPBIOS system 868 * resource devices may already claim these resources. To keep from 869 * breaking those devices, we attach ourself to the nexus device after 870 * legacy0 and acpi0 and ignore any allocation failures. 871 */ 872static void 873apic_identify(driver_t *driver, device_t parent) 874{ 875 876 /* 877 * Add at order 12. acpi0 is probed at order 10 and legacy0 878 * is probed at order 11. 879 */ 880 if (lapic_paddr != 0) 881 BUS_ADD_CHILD(parent, 12, "apic", 0); 882} 883 884static int 885apic_probe(device_t dev) 886{ 887 888 device_set_desc(dev, "APIC resources"); 889 device_quiet(dev); 890 return (0); 891} 892 893static void 894apic_add_resource(device_t dev, int rid, vm_paddr_t base, size_t length) 895{ 896 int error; 897 898#ifdef PAE 899 /* 900 * Resources use long's to track resources, so we can't 901 * include memory regions above 4GB. 902 */ 903 if (base >= ~0ul) 904 return; 905#endif 906 error = bus_set_resource(dev, SYS_RES_MEMORY, rid, base, length); 907 if (error) 908 panic("apic_add_resource: resource %d failed set with %d", rid, 909 error); 910 bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0); 911} 912 913static int 914apic_attach(device_t dev) 915{ 916 struct ioapic *io; 917 int i; 918 919 /* Reserve the local APIC. */ 920 apic_add_resource(dev, 0, lapic_paddr, sizeof(lapic_t)); 921 i = 1; 922 STAILQ_FOREACH(io, &ioapic_list, io_next) { 923 apic_add_resource(dev, i, io->io_paddr, IOAPIC_MEM_REGION); 924 i++; 925 } 926 return (0); 927} 928 929static device_method_t apic_methods[] = { 930 /* Device interface */ 931 DEVMETHOD(device_identify, apic_identify), 932 DEVMETHOD(device_probe, apic_probe), 933 DEVMETHOD(device_attach, apic_attach), 934 935 { 0, 0 } 936}; 937 938DEFINE_CLASS_0(apic, apic_driver, apic_methods, 0); 939 940static devclass_t apic_devclass; 941DRIVER_MODULE(apic, nexus, apic_driver, apic_devclass, 0, 0); 942 943#include "opt_ddb.h" 944 945#ifdef DDB 946#include <ddb/ddb.h> 947 948static const char * 949ioapic_delivery_mode(uint32_t mode) 950{ 951 952 switch (mode) { 953 case IOART_DELFIXED: 954 return ("fixed"); 955 case IOART_DELLOPRI: 956 return ("lowestpri"); 957 case IOART_DELSMI: 958 return ("SMI"); 959 case IOART_DELRSV1: 960 return ("rsrvd1"); 961 case IOART_DELNMI: 962 return ("NMI"); 963 case IOART_DELINIT: 964 return ("INIT"); 965 case IOART_DELRSV2: 966 return ("rsrvd2"); 967 case IOART_DELEXINT: 968 return ("ExtINT"); 969 default: 970 return (""); 971 } 972} 973 974static u_int 975db_ioapic_read(volatile ioapic_t *apic, int reg) 976{ 977 978 apic->ioregsel = reg; 979 return (apic->iowin); 980} 981 982static void 983db_show_ioapic_one(volatile ioapic_t *io_addr) 984{ 985 uint32_t r, lo, hi; 986 int mre, i; 987 988 r = db_ioapic_read(io_addr, IOAPIC_VER); 989 mre = (r & IOART_VER_MAXREDIR) >> MAXREDIRSHIFT; 990 db_printf("Id 0x%08x Ver 0x%02x MRE %d\n", 991 db_ioapic_read(io_addr, IOAPIC_ID), r & IOART_VER_VERSION, mre); 992 for (i = 0; i < mre; i++) { 993 lo = db_ioapic_read(io_addr, IOAPIC_REDTBL_LO(i)); 994 hi = db_ioapic_read(io_addr, IOAPIC_REDTBL_HI(i)); 995 db_printf(" pin %d Dest %s/%x %smasked Trig %s RemoteIRR %d " 996 "Polarity %s Status %s DeliveryMode %s Vec %d\n", i, 997 (lo & IOART_DESTMOD) == IOART_DESTLOG ? "log" : "phy", 998 (hi & IOART_DEST) >> 24, 999 (lo & IOART_INTMASK) == IOART_INTMSET ? "" : "not", 1000 (lo & IOART_TRGRMOD) == IOART_TRGRLVL ? "lvl" : "edge", 1001 (lo & IOART_REM_IRR) == IOART_REM_IRR ? 1 : 0, 1002 (lo & IOART_INTPOL) == IOART_INTALO ? "low" : "high", 1003 (lo & IOART_DELIVS) == IOART_DELIVS ? "pend" : "idle", 1004 ioapic_delivery_mode(lo & IOART_DELMOD), 1005 (lo & IOART_INTVEC)); 1006 } 1007} 1008 1009DB_SHOW_COMMAND(ioapic, db_show_ioapic) 1010{ 1011 struct ioapic *ioapic; 1012 int idx, i; 1013 1014 if (!have_addr) { 1015 db_printf("usage: show ioapic index\n"); 1016 return; 1017 } 1018 1019 idx = (int)addr; 1020 i = 0; 1021 STAILQ_FOREACH(ioapic, &ioapic_list, io_next) { 1022 if (idx == i) { 1023 db_show_ioapic_one(ioapic->io_addr); 1024 break; 1025 } 1026 i++; 1027 } 1028} 1029 1030DB_SHOW_ALL_COMMAND(ioapics, db_show_all_ioapics) 1031{ 1032 struct ioapic *ioapic; 1033 1034 STAILQ_FOREACH(ioapic, &ioapic_list, io_next) 1035 db_show_ioapic_one(ioapic->io_addr); 1036} 1037#endif 1038