1a800b45cSJohn Baldwin /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3a800b45cSJohn Baldwin * 4a800b45cSJohn Baldwin * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org> 5a800b45cSJohn Baldwin * 6a800b45cSJohn Baldwin * Redistribution and use in source and binary forms, with or without 7a800b45cSJohn Baldwin * modification, are permitted provided that the following conditions 8a800b45cSJohn Baldwin * are met: 9a800b45cSJohn Baldwin * 1. Redistributions of source code must retain the above copyright 10a800b45cSJohn Baldwin * notice, this list of conditions and the following disclaimer. 11a800b45cSJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 12a800b45cSJohn Baldwin * notice, this list of conditions and the following disclaimer in the 13a800b45cSJohn Baldwin * documentation and/or other materials provided with the distribution. 14a800b45cSJohn Baldwin * 15a800b45cSJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16a800b45cSJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17a800b45cSJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18a800b45cSJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19a800b45cSJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20a800b45cSJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21a800b45cSJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22a800b45cSJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23a800b45cSJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24a800b45cSJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25a800b45cSJohn Baldwin * SUCH DAMAGE. 26a800b45cSJohn Baldwin */ 27a800b45cSJohn Baldwin 28a800b45cSJohn Baldwin #ifndef __X86_INTR_MACHDEP_H__ 29a800b45cSJohn Baldwin #define __X86_INTR_MACHDEP_H__ 30a800b45cSJohn Baldwin 31a800b45cSJohn Baldwin #ifdef _KERNEL 32a800b45cSJohn Baldwin 33a800b45cSJohn Baldwin /* 34fd036deaSJohn Baldwin * Values used in determining the allocation of IRQ values among 35fd036deaSJohn Baldwin * different types of I/O interrupts. These values are used as 36fd036deaSJohn Baldwin * indices into a interrupt source array to map I/O interrupts to a 37fd036deaSJohn Baldwin * device interrupt source whether it be a pin on an interrupt 38fd036deaSJohn Baldwin * controller or an MSI interrupt. The 16 ISA IRQs are assigned fixed 39fd036deaSJohn Baldwin * IDT vectors, but all other device interrupts allocate IDT vectors 40fd036deaSJohn Baldwin * on demand. Currently we have 191 IDT vectors available for device 41fd036deaSJohn Baldwin * interrupts on each CPU. On many systems with I/O APICs, a lot of 42fd036deaSJohn Baldwin * the IRQs are not used, so the total number of IRQ values reserved 43fd036deaSJohn Baldwin * can exceed the number of available IDT slots. 44a800b45cSJohn Baldwin * 45fd036deaSJohn Baldwin * The first 16 IRQs (0 - 15) are reserved for ISA IRQs. Interrupt 46fd036deaSJohn Baldwin * pins on I/O APICs for non-ISA interrupts use IRQ values starting at 47fd036deaSJohn Baldwin * IRQ 17. This layout matches the GSI numbering used by ACPI so that 48fd036deaSJohn Baldwin * IRQ values returned by ACPI methods such as _CRS can be used 49fd036deaSJohn Baldwin * directly by the ACPI bus driver. 50fd036deaSJohn Baldwin * 51e13507f6SJohn Baldwin * MSI interrupts allocate a block of interrupts starting at the end 52e13507f6SJohn Baldwin * of the I/O APIC range. When running under the Xen Hypervisor, an 53e13507f6SJohn Baldwin * additional range of IRQ values are available for binding to event 54e13507f6SJohn Baldwin * channel events. 55a800b45cSJohn Baldwin */ 56fd036deaSJohn Baldwin extern u_int first_msi_irq; 57fd036deaSJohn Baldwin extern u_int num_io_irqs; 58b6b42932SJohn Baldwin extern u_int num_msi_irqs; 59a800b45cSJohn Baldwin 60a800b45cSJohn Baldwin /* 61a800b45cSJohn Baldwin * Default base address for MSI messages on x86 platforms. 62a800b45cSJohn Baldwin */ 63a800b45cSJohn Baldwin #define MSI_INTEL_ADDR_BASE 0xfee00000 64a800b45cSJohn Baldwin 65a800b45cSJohn Baldwin typedef void inthand_t(void); 66a800b45cSJohn Baldwin 67a800b45cSJohn Baldwin #define IDTVEC(name) __CONCAT(X,name) 68a800b45cSJohn Baldwin 69a800b45cSJohn Baldwin struct intsrc; 70a800b45cSJohn Baldwin 71a800b45cSJohn Baldwin /* 72a800b45cSJohn Baldwin * Methods that a PIC provides to mask/unmask a given interrupt source, 73a800b45cSJohn Baldwin * "turn on" the interrupt on the CPU side by setting up an IDT entry, and 74a800b45cSJohn Baldwin * return the vector associated with this source. 75a800b45cSJohn Baldwin */ 76a800b45cSJohn Baldwin struct pic { 77fd036deaSJohn Baldwin void (*pic_register_sources)(struct pic *); 78a800b45cSJohn Baldwin void (*pic_enable_source)(struct intsrc *); 79a800b45cSJohn Baldwin void (*pic_disable_source)(struct intsrc *, int); 80a800b45cSJohn Baldwin void (*pic_eoi_source)(struct intsrc *); 81a800b45cSJohn Baldwin void (*pic_enable_intr)(struct intsrc *); 82a800b45cSJohn Baldwin void (*pic_disable_intr)(struct intsrc *); 83a800b45cSJohn Baldwin int (*pic_vector)(struct intsrc *); 84a800b45cSJohn Baldwin int (*pic_source_pending)(struct intsrc *); 85a800b45cSJohn Baldwin void (*pic_suspend)(struct pic *); 86a800b45cSJohn Baldwin void (*pic_resume)(struct pic *, bool suspend_cancelled); 87a800b45cSJohn Baldwin int (*pic_config_intr)(struct intsrc *, enum intr_trigger, 88a800b45cSJohn Baldwin enum intr_polarity); 89a800b45cSJohn Baldwin int (*pic_assign_cpu)(struct intsrc *, u_int apic_id); 90a800b45cSJohn Baldwin void (*pic_reprogram_pin)(struct intsrc *); 91a800b45cSJohn Baldwin TAILQ_ENTRY(pic) pics; 92a800b45cSJohn Baldwin }; 93a800b45cSJohn Baldwin 94a800b45cSJohn Baldwin /* Flags for pic_disable_source() */ 95a800b45cSJohn Baldwin enum { 96a800b45cSJohn Baldwin PIC_EOI, 97a800b45cSJohn Baldwin PIC_NO_EOI, 98a800b45cSJohn Baldwin }; 99a800b45cSJohn Baldwin 100a800b45cSJohn Baldwin /* 101a800b45cSJohn Baldwin * An interrupt source. The upper-layer code uses the PIC methods to 102a800b45cSJohn Baldwin * control a given source. The lower-layer PIC drivers can store additional 103a800b45cSJohn Baldwin * private data in a given interrupt source such as an interrupt pin number 104a800b45cSJohn Baldwin * or an I/O APIC pointer. 105a800b45cSJohn Baldwin */ 106a800b45cSJohn Baldwin struct intsrc { 107a800b45cSJohn Baldwin struct pic *is_pic; 108a800b45cSJohn Baldwin struct intr_event *is_event; 109a800b45cSJohn Baldwin u_long *is_count; 110a800b45cSJohn Baldwin u_long *is_straycount; 111a800b45cSJohn Baldwin u_int is_index; 112a800b45cSJohn Baldwin u_int is_handlers; 113a800b45cSJohn Baldwin u_int is_domain; 114a800b45cSJohn Baldwin u_int is_cpu; 115a800b45cSJohn Baldwin }; 116a800b45cSJohn Baldwin 117a800b45cSJohn Baldwin struct trapframe; 118a800b45cSJohn Baldwin 119a800b45cSJohn Baldwin #ifdef SMP 120a800b45cSJohn Baldwin extern cpuset_t intr_cpus; 121a800b45cSJohn Baldwin #endif 122a800b45cSJohn Baldwin extern struct mtx icu_lock; 123a800b45cSJohn Baldwin extern int elcr_found; 124a800b45cSJohn Baldwin #ifdef SMP 125a800b45cSJohn Baldwin extern int msix_disable_migration; 126a800b45cSJohn Baldwin #endif 127a800b45cSJohn Baldwin 128a800b45cSJohn Baldwin #ifndef DEV_ATPIC 129a800b45cSJohn Baldwin void atpic_reset(void); 130a800b45cSJohn Baldwin #endif 131a800b45cSJohn Baldwin /* XXX: The elcr_* prototypes probably belong somewhere else. */ 132a800b45cSJohn Baldwin int elcr_probe(void); 133a800b45cSJohn Baldwin enum intr_trigger elcr_read_trigger(u_int irq); 134a800b45cSJohn Baldwin void elcr_resume(void); 135a800b45cSJohn Baldwin void elcr_write_trigger(u_int irq, enum intr_trigger trigger); 136a800b45cSJohn Baldwin #ifdef SMP 137a800b45cSJohn Baldwin void intr_add_cpu(u_int cpu); 138a800b45cSJohn Baldwin #endif 139*d9817976SElliott Mitchell int intr_add_handler(struct intsrc *isrc, const char *name, 140*d9817976SElliott Mitchell driver_filter_t filter, driver_intr_t handler, void *arg, 141*d9817976SElliott Mitchell enum intr_type flags, void **cookiep, int domain); 142*d9817976SElliott Mitchell int intr_config_intr(struct intsrc *isrc, enum intr_trigger trig, 143a800b45cSJohn Baldwin enum intr_polarity pol); 144*d9817976SElliott Mitchell int intr_describe(struct intsrc *isrc, void *ih, const char *descr); 145a800b45cSJohn Baldwin void intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame); 146a800b45cSJohn Baldwin u_int intr_next_cpu(int domain); 147a800b45cSJohn Baldwin struct intsrc *intr_lookup_source(int vector); 148a800b45cSJohn Baldwin int intr_register_pic(struct pic *pic); 149a800b45cSJohn Baldwin int intr_register_source(struct intsrc *isrc); 150a800b45cSJohn Baldwin int intr_remove_handler(void *cookie); 151a800b45cSJohn Baldwin void intr_resume(bool suspend_cancelled); 152a800b45cSJohn Baldwin void intr_suspend(void); 153a800b45cSJohn Baldwin void intr_reprogram(void); 154a800b45cSJohn Baldwin void intrcnt_add(const char *name, u_long **countp); 155a800b45cSJohn Baldwin void nexus_add_irq(u_long irq); 156a800b45cSJohn Baldwin int msi_alloc(device_t dev, int count, int maxcount, int *irqs); 157a800b45cSJohn Baldwin void msi_init(void); 158a800b45cSJohn Baldwin int msi_map(int irq, uint64_t *addr, uint32_t *data); 159a800b45cSJohn Baldwin int msi_release(int *irqs, int count); 160a800b45cSJohn Baldwin int msix_alloc(device_t dev, int *irq); 161a800b45cSJohn Baldwin int msix_release(int irq); 162fd036deaSJohn Baldwin #ifdef XENHVM 163fd036deaSJohn Baldwin void xen_intr_alloc_irqs(void); 164fd036deaSJohn Baldwin #endif 165a800b45cSJohn Baldwin 166a800b45cSJohn Baldwin #endif /* _KERNEL */ 167a800b45cSJohn Baldwin #endif /* !__X86_INTR_MACHDEP_H__ */ 168