intr_machdep.h revision 302895
120253Sjoerg/*-
220302Sjoerg * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org>
320302Sjoerg * All rights reserved.
420253Sjoerg *
520253Sjoerg * Redistribution and use in source and binary forms, with or without
620253Sjoerg * modification, are permitted provided that the following conditions
720253Sjoerg * are met:
820253Sjoerg * 1. Redistributions of source code must retain the above copyright
920302Sjoerg *    notice, this list of conditions and the following disclaimer.
1020253Sjoerg * 2. Redistributions in binary form must reproduce the above copyright
1120253Sjoerg *    notice, this list of conditions and the following disclaimer in the
1220253Sjoerg *    documentation and/or other materials provided with the distribution.
1320253Sjoerg *
1420302Sjoerg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1520253Sjoerg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1620253Sjoerg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1720302Sjoerg * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1820253Sjoerg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1920253Sjoerg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2020253Sjoerg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2120253Sjoerg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2220253Sjoerg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2320253Sjoerg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2420253Sjoerg * SUCH DAMAGE.
2544229Sdavidn *
2620253Sjoerg * $FreeBSD: stable/11/sys/amd64/include/intr_machdep.h 302895 2016-07-15 09:44:48Z royger $
2720253Sjoerg */
2830259Scharnier
2930259Scharnier#ifndef __MACHINE_INTR_MACHDEP_H__
3050479Speter#define	__MACHINE_INTR_MACHDEP_H__
3130259Scharnier
3230259Scharnier#ifdef _KERNEL
3330259Scharnier
3430259Scharnier/*
3520253Sjoerg * The maximum number of I/O interrupts we allow.  This number is rather
3620253Sjoerg * arbitrary as it is just the maximum IRQ resource value.  The interrupt
3720253Sjoerg * source for a given IRQ maps that I/O interrupt to device interrupt
3830259Scharnier * source whether it be a pin on an interrupt controller or an MSI interrupt.
3920253Sjoerg * The 16 ISA IRQs are assigned fixed IDT vectors, but all other device
4020555Sdavidn * interrupts allocate IDT vectors on demand.  Currently we have 191 IDT
4120555Sdavidn * vectors available for device interrupts.  On many systems with I/O APICs,
4220555Sdavidn * a lot of the IRQs are not used, so this number can be much larger than
4364918Sgreen * 191 and still be safe since only interrupt sources in actual use will
44242349Sbapt * allocate IDT vectors.
45242349Sbapt *
46242349Sbapt * The first 255 IRQs (0 - 254) are reserved for ISA IRQs and PCI intline IRQs.
4720253Sjoerg * IRQ values from 256 to 767 are used by MSI.  When running under the Xen
4820253Sjoerg * Hypervisor, IRQ values from 768 to 4863 are available for binding to
4920253Sjoerg * event channel events.  We leave 255 unused to avoid confusion since 255 is
5023318Sache * used in PCI to indicate an invalid IRQ.
5122394Sdavidn */
5252512Sdavidn#define	NUM_MSI_INTS	512
5324214Sache#define	FIRST_MSI_INT	256
5444386Sdavidn#ifdef XENHVM
5520253Sjoerg#include <xen/xen-os.h>
5620253Sjoerg#include <xen/interface/event_channel.h>
5720253Sjoerg#define	NUM_EVTCHN_INTS	NR_EVENT_CHANNELS
5820253Sjoerg#define	FIRST_EVTCHN_INT \
5920253Sjoerg    (FIRST_MSI_INT + NUM_MSI_INTS)
6020253Sjoerg#define	LAST_EVTCHN_INT \
6120253Sjoerg    (FIRST_EVTCHN_INT + NUM_EVTCHN_INTS - 1)
6220253Sjoerg#else
6320253Sjoerg#define	NUM_EVTCHN_INTS	0
6485145Sache#endif
6520253Sjoerg#define	NUM_IO_INTS	(FIRST_MSI_INT + NUM_MSI_INTS + NUM_EVTCHN_INTS)
6620253Sjoerg
6720253Sjoerg/*
6820253Sjoerg * Default base address for MSI messages on x86 platforms.
6920253Sjoerg */
7020253Sjoerg#define	MSI_INTEL_ADDR_BASE		0xfee00000
7120253Sjoerg
7220253Sjoerg/*
7320253Sjoerg * - 1 ??? dummy counter.
7420253Sjoerg * - 2 counters for each I/O interrupt.
7520253Sjoerg * - 1 counter for each CPU for lapic timer.
7620253Sjoerg * - 8 counters for each CPU for IPI counters for SMP.
7720253Sjoerg */
7820253Sjoerg#ifdef SMP
7920253Sjoerg#define	INTRCNT_COUNT	(1 + NUM_IO_INTS * 2 + (1 + 8) * MAXCPU)
8020253Sjoerg#else
8120253Sjoerg#define	INTRCNT_COUNT	(1 + NUM_IO_INTS * 2 + 1)
8220253Sjoerg#endif
83124382Siedowse
8420253Sjoerg#ifndef LOCORE
8520253Sjoerg
8620253Sjoergtypedef void inthand_t(void);
8720253Sjoerg
8820253Sjoerg#define	IDTVEC(name)	__CONCAT(X,name)
8920253Sjoerg
9020253Sjoergstruct intsrc;
9120253Sjoerg
9220253Sjoerg/*
9320253Sjoerg * Methods that a PIC provides to mask/unmask a given interrupt source,
9420253Sjoerg * "turn on" the interrupt on the CPU side by setting up an IDT entry, and
9520253Sjoerg * return the vector associated with this source.
9620253Sjoerg */
9720253Sjoergstruct pic {
9820253Sjoerg	void (*pic_enable_source)(struct intsrc *);
9920253Sjoerg	void (*pic_disable_source)(struct intsrc *, int);
10020253Sjoerg	void (*pic_eoi_source)(struct intsrc *);
10152527Sdavidn	void (*pic_enable_intr)(struct intsrc *);
10220253Sjoerg	void (*pic_disable_intr)(struct intsrc *);
10352512Sdavidn	int (*pic_vector)(struct intsrc *);
10420253Sjoerg	int (*pic_source_pending)(struct intsrc *);
10520253Sjoerg	void (*pic_suspend)(struct pic *);
10620253Sjoerg	void (*pic_resume)(struct pic *, bool suspend_cancelled);
10720253Sjoerg	int (*pic_config_intr)(struct intsrc *, enum intr_trigger,
10820253Sjoerg	    enum intr_polarity);
10920253Sjoerg	int (*pic_assign_cpu)(struct intsrc *, u_int apic_id);
11020747Sdavidn	void (*pic_reprogram_pin)(struct intsrc *);
11182868Sdd	TAILQ_ENTRY(pic) pics;
112167919Sle};
113167919Sle
11420253Sjoerg/* Flags for pic_disable_source() */
11520253Sjoergenum {
11620253Sjoerg	PIC_EOI,
11720253Sjoerg	PIC_NO_EOI,
11820253Sjoerg};
11920253Sjoerg
12020253Sjoerg/*
12120253Sjoerg * An interrupt source.  The upper-layer code uses the PIC methods to
12220253Sjoerg * control a given source.  The lower-layer PIC drivers can store additional
12320253Sjoerg * private data in a given interrupt source such as an interrupt pin number
12456000Sdavidn * or an I/O APIC pointer.
12520253Sjoerg */
12620253Sjoergstruct intsrc {
12756000Sdavidn	struct pic *is_pic;
12856000Sdavidn	struct intr_event *is_event;
12956000Sdavidn	u_long *is_count;
13020253Sjoerg	u_long *is_straycount;
13120253Sjoerg	u_int is_index;
13252512Sdavidn	u_int is_handlers;
13320253Sjoerg};
13420267Sjoerg
13520267Sjoergstruct trapframe;
13620267Sjoerg
13720267Sjoerg/*
13820267Sjoerg * The following data structure holds per-cpu data, and is placed just
13920267Sjoerg * above the top of the space used for the NMI stack.
14020267Sjoerg */
14120267Sjoergstruct nmi_pcpu {
14220267Sjoerg	register_t	np_pcpu;
14320267Sjoerg	register_t	__padding;	/* pad to 16 bytes */
14420267Sjoerg};
14520267Sjoerg
14620267Sjoerg#ifdef SMP
14720267Sjoergextern cpuset_t intr_cpus;
14820253Sjoerg#endif
14920253Sjoergextern struct mtx icu_lock;
15020253Sjoergextern int elcr_found;
15120253Sjoerg
15220267Sjoergextern int msix_disable_migration;
15320253Sjoerg
15421052Sdavidn#ifndef DEV_ATPIC
155167919Slevoid	atpic_reset(void);
156167919Sle#endif
157167919Sle/* XXX: The elcr_* prototypes probably belong somewhere else. */
158167919Sleint	elcr_probe(void);
159167919Sleenum intr_trigger elcr_read_trigger(u_int irq);
160219408Sjkimvoid	elcr_resume(void);
161167919Slevoid	elcr_write_trigger(u_int irq, enum intr_trigger trigger);
162168044Sle#ifdef SMP
163167919Slevoid	intr_add_cpu(u_int cpu);
16421052Sdavidn#endif
16521052Sdavidnint	intr_add_handler(const char *name, int vector, driver_filter_t filter,
16621052Sdavidn			 driver_intr_t handler, void *arg, enum intr_type flags,
16721052Sdavidn			 void **cookiep);
168224535Sdelphij#ifdef SMP
16921052Sdavidnint	intr_bind(u_int vector, u_char cpu);
17021052Sdavidn#endif
17121052Sdavidnint	intr_config_intr(int vector, enum intr_trigger trig,
17221052Sdavidn    enum intr_polarity pol);
17321052Sdavidnint	intr_describe(u_int vector, void *ih, const char *descr);
17421052Sdavidnvoid	intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame);
17530259Scharnieru_int	intr_next_cpu(void);
17621052Sdavidnstruct intsrc *intr_lookup_source(int vector);
17721052Sdavidnint	intr_register_pic(struct pic *pic);
17821052Sdavidnint	intr_register_source(struct intsrc *isrc);
17921052Sdavidnint	intr_remove_handler(void *cookie);
18021242Sdavidnvoid	intr_resume(bool suspend_cancelled);
18121242Sdavidnvoid	intr_suspend(void);
18221242Sdavidnvoid	intr_reprogram(void);
18321242Sdavidnvoid	intrcnt_add(const char *name, u_long **countp);
18421242Sdavidnvoid	nexus_add_irq(u_long irq);
18521242Sdavidnint	msi_alloc(device_t dev, int count, int maxcount, int *irqs);
18621242Sdavidnvoid	msi_init(void);
187282683Sbaptint	msi_map(int irq, uint64_t *addr, uint32_t *data);
188219408Sjkimint	msi_release(int *irqs, int count);
18921242Sdavidnint	msix_alloc(device_t dev, int *irq);
190148584Spjdint	msix_release(int irq);
191148584Spjd
192148584Spjd#endif	/* !LOCORE */
193148584Spjd#endif	/* _KERNEL */
194148584Spjd#endif	/* !__MACHINE_INTR_MACHDEP_H__ */
19521242Sdavidn