1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 /* 29 * PIC driver for the 8259A Master and Slave PICs in PC/AT machines. 30 */ 31 32 #include <sys/cdefs.h> 33 __FBSDID("$FreeBSD$"); 34 35 #include "opt_auto_eoi.h" 36 #include "opt_isa.h" 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/bus.h> 41 #include <sys/interrupt.h> 42 #include <sys/kernel.h> 43 #include <sys/lock.h> 44 #include <sys/module.h> 45 46 #include <machine/cpufunc.h> 47 #include <machine/frame.h> 48 #include <machine/intr_machdep.h> 49 #include <machine/md_var.h> 50 #include <machine/resource.h> 51 #include <machine/segments.h> 52 53 #include <dev/ic/i8259.h> 54 #include <x86/isa/icu.h> 55 #include <isa/isareg.h> 56 #include <isa/isavar.h> 57 58 #ifdef __amd64__ 59 #define SDT_ATPIC SDT_SYSIGT 60 #define GSEL_ATPIC 0 61 #else 62 #define SDT_ATPIC SDT_SYS386IGT 63 #define GSEL_ATPIC GSEL(GCODE_SEL, SEL_KPL) 64 #endif 65 66 #define MASTER 0 67 #define SLAVE 1 68 69 #define IMEN_MASK(ai) (IRQ_MASK((ai)->at_irq)) 70 71 #define NUM_ISA_IRQS 16 72 73 static void atpic_init(void *dummy); 74 75 inthand_t 76 IDTVEC(atpic_intr0), IDTVEC(atpic_intr1), IDTVEC(atpic_intr2), 77 IDTVEC(atpic_intr3), IDTVEC(atpic_intr4), IDTVEC(atpic_intr5), 78 IDTVEC(atpic_intr6), IDTVEC(atpic_intr7), IDTVEC(atpic_intr8), 79 IDTVEC(atpic_intr9), IDTVEC(atpic_intr10), IDTVEC(atpic_intr11), 80 IDTVEC(atpic_intr12), IDTVEC(atpic_intr13), IDTVEC(atpic_intr14), 81 IDTVEC(atpic_intr15); 82 /* XXXKIB i386 uses stubs until pti comes */ 83 inthand_t 84 IDTVEC(atpic_intr0_pti), IDTVEC(atpic_intr1_pti), 85 IDTVEC(atpic_intr2_pti), IDTVEC(atpic_intr3_pti), 86 IDTVEC(atpic_intr4_pti), IDTVEC(atpic_intr5_pti), 87 IDTVEC(atpic_intr6_pti), IDTVEC(atpic_intr7_pti), 88 IDTVEC(atpic_intr8_pti), IDTVEC(atpic_intr9_pti), 89 IDTVEC(atpic_intr10_pti), IDTVEC(atpic_intr11_pti), 90 IDTVEC(atpic_intr12_pti), IDTVEC(atpic_intr13_pti), 91 IDTVEC(atpic_intr14_pti), IDTVEC(atpic_intr15_pti); 92 93 #define IRQ(ap, ai) ((ap)->at_irqbase + (ai)->at_irq) 94 95 #define ATPIC(io, base, eoi) { \ 96 .at_pic = { \ 97 .pic_register_sources = atpic_register_sources, \ 98 .pic_enable_source = atpic_enable_source, \ 99 .pic_disable_source = atpic_disable_source, \ 100 .pic_eoi_source = (eoi), \ 101 .pic_enable_intr = atpic_enable_intr, \ 102 .pic_disable_intr = atpic_disable_intr, \ 103 .pic_vector = atpic_vector, \ 104 .pic_source_pending = atpic_source_pending, \ 105 .pic_resume = atpic_resume, \ 106 .pic_config_intr = atpic_config_intr, \ 107 .pic_assign_cpu = atpic_assign_cpu \ 108 }, \ 109 .at_ioaddr = (io), \ 110 .at_irqbase = (base), \ 111 .at_intbase = IDT_IO_INTS + (base), \ 112 .at_imen = 0xff, \ 113 } 114 115 #define INTSRC(irq) \ 116 { { &atpics[(irq) / 8].at_pic }, IDTVEC(atpic_intr ## irq ), \ 117 IDTVEC(atpic_intr ## irq ## _pti), (irq) % 8 } 118 119 struct atpic { 120 struct pic at_pic; 121 int at_ioaddr; 122 int at_irqbase; 123 uint8_t at_intbase; 124 uint8_t at_imen; 125 }; 126 127 struct atpic_intsrc { 128 struct intsrc at_intsrc; 129 inthand_t *at_intr, *at_intr_pti; 130 int at_irq; /* Relative to PIC base. */ 131 enum intr_trigger at_trigger; 132 u_long at_count; 133 u_long at_straycount; 134 }; 135 136 static void atpic_register_sources(struct pic *pic); 137 static void atpic_enable_source(struct intsrc *isrc); 138 static void atpic_disable_source(struct intsrc *isrc, int eoi); 139 static void atpic_eoi_master(struct intsrc *isrc); 140 static void atpic_eoi_slave(struct intsrc *isrc); 141 static void atpic_enable_intr(struct intsrc *isrc); 142 static void atpic_disable_intr(struct intsrc *isrc); 143 static int atpic_vector(struct intsrc *isrc); 144 static void atpic_resume(struct pic *pic, bool suspend_cancelled); 145 static int atpic_source_pending(struct intsrc *isrc); 146 static int atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig, 147 enum intr_polarity pol); 148 static int atpic_assign_cpu(struct intsrc *isrc, u_int apic_id); 149 static void i8259_init(struct atpic *pic, int slave); 150 151 static struct atpic atpics[] = { 152 ATPIC(IO_ICU1, 0, atpic_eoi_master), 153 ATPIC(IO_ICU2, 8, atpic_eoi_slave) 154 }; 155 156 static struct atpic_intsrc atintrs[] = { 157 INTSRC(0), 158 INTSRC(1), 159 INTSRC(2), 160 INTSRC(3), 161 INTSRC(4), 162 INTSRC(5), 163 INTSRC(6), 164 INTSRC(7), 165 INTSRC(8), 166 INTSRC(9), 167 INTSRC(10), 168 INTSRC(11), 169 INTSRC(12), 170 INTSRC(13), 171 INTSRC(14), 172 INTSRC(15), 173 }; 174 175 CTASSERT(nitems(atintrs) == NUM_ISA_IRQS); 176 177 static __inline void 178 _atpic_eoi_master(struct intsrc *isrc) 179 { 180 181 KASSERT(isrc->is_pic == &atpics[MASTER].at_pic, 182 ("%s: mismatched pic", __func__)); 183 #ifndef AUTO_EOI_1 184 outb(atpics[MASTER].at_ioaddr, OCW2_EOI); 185 #endif 186 } 187 188 /* 189 * The data sheet says no auto-EOI on slave, but it sometimes works. 190 * So, if AUTO_EOI_2 is enabled, we use it. 191 */ 192 static __inline void 193 _atpic_eoi_slave(struct intsrc *isrc) 194 { 195 196 KASSERT(isrc->is_pic == &atpics[SLAVE].at_pic, 197 ("%s: mismatched pic", __func__)); 198 #ifndef AUTO_EOI_2 199 outb(atpics[SLAVE].at_ioaddr, OCW2_EOI); 200 #ifndef AUTO_EOI_1 201 outb(atpics[MASTER].at_ioaddr, OCW2_EOI); 202 #endif 203 #endif 204 } 205 206 static void 207 atpic_register_sources(struct pic *pic) 208 { 209 struct atpic *ap = (struct atpic *)pic; 210 struct atpic_intsrc *ai; 211 int i; 212 213 /* 214 * If any of the ISA IRQs have an interrupt source already, then 215 * assume that the I/O APICs are being used and don't register any 216 * of our interrupt sources. This makes sure we don't accidentally 217 * use mixed mode. The "accidental" use could otherwise occur on 218 * machines that route the ACPI SCI interrupt to a different ISA 219 * IRQ (at least one machine routes it to IRQ 13) thus disabling 220 * that APIC ISA routing and allowing the ATPIC source for that IRQ 221 * to leak through. We used to depend on this feature for routing 222 * IRQ0 via mixed mode, but now we don't use mixed mode at all. 223 * 224 * To avoid the slave not register sources after the master 225 * registers its sources, register all IRQs when this function is 226 * called on the master. 227 */ 228 if (ap != &atpics[MASTER]) 229 return; 230 for (i = 0; i < NUM_ISA_IRQS; i++) 231 if (intr_lookup_source(i) != NULL) 232 return; 233 234 /* Loop through all interrupt sources and add them. */ 235 for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) { 236 if (i == ICU_SLAVEID) 237 continue; 238 intr_register_source(&ai->at_intsrc); 239 } 240 } 241 242 static void 243 atpic_enable_source(struct intsrc *isrc) 244 { 245 struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc; 246 struct atpic *ap = (struct atpic *)isrc->is_pic; 247 248 spinlock_enter(); 249 if (ap->at_imen & IMEN_MASK(ai)) { 250 ap->at_imen &= ~IMEN_MASK(ai); 251 outb(ap->at_ioaddr + ICU_IMR_OFFSET, ap->at_imen); 252 } 253 spinlock_exit(); 254 } 255 256 static void 257 atpic_disable_source(struct intsrc *isrc, int eoi) 258 { 259 struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc; 260 struct atpic *ap = (struct atpic *)isrc->is_pic; 261 262 spinlock_enter(); 263 if (ai->at_trigger != INTR_TRIGGER_EDGE) { 264 ap->at_imen |= IMEN_MASK(ai); 265 outb(ap->at_ioaddr + ICU_IMR_OFFSET, ap->at_imen); 266 } 267 268 /* 269 * Take care to call these functions directly instead of through 270 * a function pointer. All of the referenced variables should 271 * still be hot in the cache. 272 */ 273 if (eoi == PIC_EOI) { 274 if (isrc->is_pic == &atpics[MASTER].at_pic) 275 _atpic_eoi_master(isrc); 276 else 277 _atpic_eoi_slave(isrc); 278 } 279 280 spinlock_exit(); 281 } 282 283 static void 284 atpic_eoi_master(struct intsrc *isrc) 285 { 286 #ifndef AUTO_EOI_1 287 spinlock_enter(); 288 _atpic_eoi_master(isrc); 289 spinlock_exit(); 290 #endif 291 } 292 293 static void 294 atpic_eoi_slave(struct intsrc *isrc) 295 { 296 #ifndef AUTO_EOI_2 297 spinlock_enter(); 298 _atpic_eoi_slave(isrc); 299 spinlock_exit(); 300 #endif 301 } 302 303 static void 304 atpic_enable_intr(struct intsrc *isrc) 305 { 306 } 307 308 static void 309 atpic_disable_intr(struct intsrc *isrc) 310 { 311 } 312 313 314 static int 315 atpic_vector(struct intsrc *isrc) 316 { 317 struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc; 318 struct atpic *ap = (struct atpic *)isrc->is_pic; 319 320 return (IRQ(ap, ai)); 321 } 322 323 static int 324 atpic_source_pending(struct intsrc *isrc) 325 { 326 struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc; 327 struct atpic *ap = (struct atpic *)isrc->is_pic; 328 329 return (inb(ap->at_ioaddr) & IMEN_MASK(ai)); 330 } 331 332 static void 333 atpic_resume(struct pic *pic, bool suspend_cancelled) 334 { 335 struct atpic *ap = (struct atpic *)pic; 336 337 i8259_init(ap, ap == &atpics[SLAVE]); 338 if (ap == &atpics[SLAVE] && elcr_found) 339 elcr_resume(); 340 } 341 342 static int 343 atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig, 344 enum intr_polarity pol) 345 { 346 struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc; 347 u_int vector; 348 349 /* Map conforming values to edge/hi and sanity check the values. */ 350 if (trig == INTR_TRIGGER_CONFORM) 351 trig = INTR_TRIGGER_EDGE; 352 if (pol == INTR_POLARITY_CONFORM) 353 pol = INTR_POLARITY_HIGH; 354 vector = atpic_vector(isrc); 355 if ((trig == INTR_TRIGGER_EDGE && pol == INTR_POLARITY_LOW) || 356 (trig == INTR_TRIGGER_LEVEL && pol == INTR_POLARITY_HIGH)) { 357 printf( 358 "atpic: Mismatched config for IRQ%u: trigger %s, polarity %s\n", 359 vector, trig == INTR_TRIGGER_EDGE ? "edge" : "level", 360 pol == INTR_POLARITY_HIGH ? "high" : "low"); 361 return (EINVAL); 362 } 363 364 /* If there is no change, just return. */ 365 if (ai->at_trigger == trig) 366 return (0); 367 368 /* 369 * Certain IRQs can never be level/lo, so don't try to set them 370 * that way if asked. At least some ELCR registers ignore setting 371 * these bits as well. 372 */ 373 if ((vector == 0 || vector == 1 || vector == 2 || vector == 13) && 374 trig == INTR_TRIGGER_LEVEL) { 375 if (bootverbose) 376 printf( 377 "atpic: Ignoring invalid level/low configuration for IRQ%u\n", 378 vector); 379 return (EINVAL); 380 } 381 if (!elcr_found) { 382 if (bootverbose) 383 printf("atpic: No ELCR to configure IRQ%u as %s\n", 384 vector, trig == INTR_TRIGGER_EDGE ? "edge/high" : 385 "level/low"); 386 return (ENXIO); 387 } 388 if (bootverbose) 389 printf("atpic: Programming IRQ%u as %s\n", vector, 390 trig == INTR_TRIGGER_EDGE ? "edge/high" : "level/low"); 391 spinlock_enter(); 392 elcr_write_trigger(atpic_vector(isrc), trig); 393 ai->at_trigger = trig; 394 spinlock_exit(); 395 return (0); 396 } 397 398 static int 399 atpic_assign_cpu(struct intsrc *isrc, u_int apic_id) 400 { 401 402 /* 403 * 8259A's are only used in UP in which case all interrupts always 404 * go to the sole CPU and this function shouldn't even be called. 405 */ 406 panic("%s: bad cookie", __func__); 407 } 408 409 static void 410 i8259_init(struct atpic *pic, int slave) 411 { 412 int imr_addr; 413 414 /* Reset the PIC and program with next four bytes. */ 415 spinlock_enter(); 416 outb(pic->at_ioaddr, ICW1_RESET | ICW1_IC4); 417 imr_addr = pic->at_ioaddr + ICU_IMR_OFFSET; 418 419 /* Start vector. */ 420 outb(imr_addr, pic->at_intbase); 421 422 /* 423 * Setup slave links. For the master pic, indicate what line 424 * the slave is configured on. For the slave indicate 425 * which line on the master we are connected to. 426 */ 427 if (slave) 428 outb(imr_addr, ICU_SLAVEID); 429 else 430 outb(imr_addr, IRQ_MASK(ICU_SLAVEID)); 431 432 /* Set mode. */ 433 if (slave) 434 outb(imr_addr, SLAVE_MODE); 435 else 436 outb(imr_addr, MASTER_MODE); 437 438 /* Set interrupt enable mask. */ 439 outb(imr_addr, pic->at_imen); 440 441 /* Reset is finished, default to IRR on read. */ 442 outb(pic->at_ioaddr, OCW3_SEL | OCW3_RR); 443 444 /* OCW2_L1 sets priority order to 3-7, 0-2 (com2 first). */ 445 if (!slave) 446 outb(pic->at_ioaddr, OCW2_R | OCW2_SL | OCW2_L1); 447 448 spinlock_exit(); 449 } 450 451 void 452 atpic_startup(void) 453 { 454 struct atpic_intsrc *ai; 455 int i; 456 457 /* Start off with all interrupts disabled. */ 458 i8259_init(&atpics[MASTER], 0); 459 i8259_init(&atpics[SLAVE], 1); 460 atpic_enable_source((struct intsrc *)&atintrs[ICU_SLAVEID]); 461 462 /* Install low-level interrupt handlers for all of our IRQs. */ 463 for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) { 464 if (i == ICU_SLAVEID) 465 continue; 466 ai->at_intsrc.is_count = &ai->at_count; 467 ai->at_intsrc.is_straycount = &ai->at_straycount; 468 setidt(((struct atpic *)ai->at_intsrc.is_pic)->at_intbase + 469 ai->at_irq, pti ? ai->at_intr_pti : ai->at_intr, SDT_ATPIC, 470 SEL_KPL, GSEL_ATPIC); 471 } 472 473 /* 474 * Look for an ELCR. If we find one, update the trigger modes. 475 * If we don't find one, assume that IRQs 0, 1, 2, and 13 are 476 * edge triggered and that everything else is level triggered. 477 * We only use the trigger information to reprogram the ELCR if 478 * we have one and as an optimization to avoid masking edge 479 * triggered interrupts. For the case that we don't have an ELCR, 480 * it doesn't hurt to mask an edge triggered interrupt, so we 481 * assume level trigger for any interrupt that we aren't sure is 482 * edge triggered. 483 */ 484 if (elcr_found) { 485 for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) 486 ai->at_trigger = elcr_read_trigger(i); 487 } else { 488 for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) 489 switch (i) { 490 case 0: 491 case 1: 492 case 2: 493 case 8: 494 case 13: 495 ai->at_trigger = INTR_TRIGGER_EDGE; 496 break; 497 default: 498 ai->at_trigger = INTR_TRIGGER_LEVEL; 499 break; 500 } 501 } 502 } 503 504 static void 505 atpic_init(void *dummy __unused) 506 { 507 508 /* 509 * Register our PICs, even if we aren't going to use any of their 510 * pins so that they are suspended and resumed. 511 */ 512 if (intr_register_pic(&atpics[0].at_pic) != 0 || 513 intr_register_pic(&atpics[1].at_pic) != 0) 514 panic("Unable to register ATPICs"); 515 516 if (num_io_irqs == 0) 517 num_io_irqs = NUM_ISA_IRQS; 518 } 519 SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_FOURTH, atpic_init, NULL); 520 521 void 522 atpic_handle_intr(u_int vector, struct trapframe *frame) 523 { 524 struct intsrc *isrc; 525 526 KASSERT(vector < NUM_ISA_IRQS, ("unknown int %u\n", vector)); 527 isrc = &atintrs[vector].at_intsrc; 528 529 /* 530 * If we don't have an event, see if this is a spurious 531 * interrupt. 532 */ 533 if (isrc->is_event == NULL && (vector == 7 || vector == 15)) { 534 int port, isr; 535 536 /* 537 * Read the ISR register to see if IRQ 7/15 is really 538 * pending. Reset read register back to IRR when done. 539 */ 540 port = ((struct atpic *)isrc->is_pic)->at_ioaddr; 541 spinlock_enter(); 542 outb(port, OCW3_SEL | OCW3_RR | OCW3_RIS); 543 isr = inb(port); 544 outb(port, OCW3_SEL | OCW3_RR); 545 spinlock_exit(); 546 if ((isr & IRQ_MASK(7)) == 0) 547 return; 548 } 549 intr_execute_handlers(isrc, frame); 550 } 551 552 #ifdef DEV_ISA 553 /* 554 * Bus attachment for the ISA PIC. 555 */ 556 static struct isa_pnp_id atpic_ids[] = { 557 { 0x0000d041 /* PNP0000 */, "AT interrupt controller" }, 558 { 0 } 559 }; 560 561 static int 562 atpic_probe(device_t dev) 563 { 564 int result; 565 566 result = ISA_PNP_PROBE(device_get_parent(dev), dev, atpic_ids); 567 if (result <= 0) 568 device_quiet(dev); 569 return (result); 570 } 571 572 /* 573 * We might be granted IRQ 2, as this is typically consumed by chaining 574 * between the two PIC components. If we're using the APIC, however, 575 * this may not be the case, and as such we should free the resource. 576 * (XXX untested) 577 * 578 * The generic ISA attachment code will handle allocating any other resources 579 * that we don't explicitly claim here. 580 */ 581 static int 582 atpic_attach(device_t dev) 583 { 584 struct resource *res; 585 int rid; 586 587 /* Try to allocate our IRQ and then free it. */ 588 rid = 0; 589 res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 0); 590 if (res != NULL) 591 bus_release_resource(dev, SYS_RES_IRQ, rid, res); 592 return (0); 593 } 594 595 /* 596 * Return a bitmap of the current interrupt requests. This is 8259-specific 597 * and is only suitable for use at probe time. 598 */ 599 intrmask_t 600 isa_irq_pending(void) 601 { 602 u_char irr1; 603 u_char irr2; 604 605 irr1 = inb(IO_ICU1); 606 irr2 = inb(IO_ICU2); 607 return ((irr2 << 8) | irr1); 608 } 609 610 static device_method_t atpic_methods[] = { 611 /* Device interface */ 612 DEVMETHOD(device_probe, atpic_probe), 613 DEVMETHOD(device_attach, atpic_attach), 614 DEVMETHOD(device_detach, bus_generic_detach), 615 DEVMETHOD(device_shutdown, bus_generic_shutdown), 616 DEVMETHOD(device_suspend, bus_generic_suspend), 617 DEVMETHOD(device_resume, bus_generic_resume), 618 { 0, 0 } 619 }; 620 621 static driver_t atpic_driver = { 622 "atpic", 623 atpic_methods, 624 1, /* no softc */ 625 }; 626 627 static devclass_t atpic_devclass; 628 629 DRIVER_MODULE(atpic, isa, atpic_driver, atpic_devclass, 0, 0); 630 DRIVER_MODULE(atpic, acpi, atpic_driver, atpic_devclass, 0, 0); 631 ISA_PNP_INFO(atpic_ids); 632 #endif /* DEV_ISA */ 633