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