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