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