1121986Sjhb/*- 2121986Sjhb * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org> 3121986Sjhb * All rights reserved. 4121986Sjhb * 5121986Sjhb * Redistribution and use in source and binary forms, with or without 6121986Sjhb * modification, are permitted provided that the following conditions 7121986Sjhb * are met: 8121986Sjhb * 1. Redistributions of source code must retain the above copyright 9121986Sjhb * notice, this list of conditions and the following disclaimer. 10121986Sjhb * 2. Redistributions in binary form must reproduce the above copyright 11121986Sjhb * notice, this list of conditions and the following disclaimer in the 12121986Sjhb * documentation and/or other materials provided with the distribution. 13121986Sjhb * 14121986Sjhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15121986Sjhb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16121986Sjhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17121986Sjhb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18121986Sjhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19121986Sjhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20121986Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21121986Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22121986Sjhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23121986Sjhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24121986Sjhb * SUCH DAMAGE. 25121986Sjhb * 26121986Sjhb * $FreeBSD: releng/10.3/sys/amd64/include/apicvar.h 283280 2015-05-22 09:03:55Z whu $ 27121986Sjhb */ 28121986Sjhb 29121986Sjhb#ifndef _MACHINE_APICVAR_H_ 30121986Sjhb#define _MACHINE_APICVAR_H_ 31121986Sjhb 32122849Speter#include <machine/segments.h> 33122849Speter 34121986Sjhb/* 35121986Sjhb * Local && I/O APIC variable definitions. 36121986Sjhb */ 37121986Sjhb 38121986Sjhb/* 39121986Sjhb * Layout of local APIC interrupt vectors: 40121986Sjhb * 41121986Sjhb * 0xff (255) +-------------+ 42122710Speter * | | 15 (Spurious / IPIs / Local Interrupts) 43121986Sjhb * 0xf0 (240) +-------------+ 44140555Speter * | | 14 (I/O Interrupts / Timer) 45121986Sjhb * 0xe0 (224) +-------------+ 46122690Sjhb * | | 13 (I/O Interrupts) 47121986Sjhb * 0xd0 (208) +-------------+ 48122690Sjhb * | | 12 (I/O Interrupts) 49121986Sjhb * 0xc0 (192) +-------------+ 50121986Sjhb * | | 11 (I/O Interrupts) 51121986Sjhb * 0xb0 (176) +-------------+ 52121986Sjhb * | | 10 (I/O Interrupts) 53121986Sjhb * 0xa0 (160) +-------------+ 54121986Sjhb * | | 9 (I/O Interrupts) 55121986Sjhb * 0x90 (144) +-------------+ 56121986Sjhb * | | 8 (I/O Interrupts / System Calls) 57121986Sjhb * 0x80 (128) +-------------+ 58121986Sjhb * | | 7 (I/O Interrupts) 59121986Sjhb * 0x70 (112) +-------------+ 60121986Sjhb * | | 6 (I/O Interrupts) 61121986Sjhb * 0x60 (96) +-------------+ 62121986Sjhb * | | 5 (I/O Interrupts) 63121986Sjhb * 0x50 (80) +-------------+ 64121986Sjhb * | | 4 (I/O Interrupts) 65121986Sjhb * 0x40 (64) +-------------+ 66121986Sjhb * | | 3 (I/O Interrupts) 67121986Sjhb * 0x30 (48) +-------------+ 68122690Sjhb * | | 2 (ATPIC Interrupts) 69121986Sjhb * 0x20 (32) +-------------+ 70121986Sjhb * | | 1 (Exceptions, traps, faults, etc.) 71121986Sjhb * 0x10 (16) +-------------+ 72121986Sjhb * | | 0 (Exceptions, traps, faults, etc.) 73121986Sjhb * 0x00 (0) +-------------+ 74121986Sjhb * 75121986Sjhb * Note: 0x80 needs to be handled specially and not allocated to an 76121986Sjhb * I/O device! 77121986Sjhb */ 78121986Sjhb 79169395Sjhb#define MAX_APIC_ID 0xfe 80121986Sjhb#define APIC_ID_ALL 0xff 81140555Speter 82140555Speter/* I/O Interrupts are used for external devices such as ISA, PCI, etc. */ 83122690Sjhb#define APIC_IO_INTS (IDT_IO_INTS + 16) 84140555Speter#define APIC_NUM_IOINTS 191 85121986Sjhb 86140555Speter/* The timer interrupt is used for clock handling and drives hardclock, etc. */ 87140555Speter#define APIC_TIMER_INT (APIC_IO_INTS + APIC_NUM_IOINTS) 88140555Speter 89140555Speter/* 90140555Speter ********************* !!! WARNING !!! ****************************** 91140555Speter * Each local apic has an interrupt receive fifo that is two entries deep 92140555Speter * for each interrupt priority class (higher 4 bits of interrupt vector). 93140555Speter * Once the fifo is full the APIC can no longer receive interrupts for this 94140555Speter * class and sending IPIs from other CPUs will be blocked. 95140555Speter * To avoid deadlocks there should be no more than two IPI interrupts 96140555Speter * pending at the same time. 97140555Speter * Currently this is guaranteed by dividing the IPIs in two groups that have 98140555Speter * each at most one IPI interrupt pending. The first group is protected by the 99140555Speter * smp_ipi_mtx and waits for the completion of the IPI (Only one IPI user 100140555Speter * at a time) The second group uses a single interrupt and a bitmap to avoid 101140555Speter * redundant IPI interrupts. 102140555Speter */ 103140555Speter 104140555Speter/* Interrupts for local APIC LVT entries other than the timer. */ 105122690Sjhb#define APIC_LOCAL_INTS 240 106140555Speter#define APIC_ERROR_INT APIC_LOCAL_INTS 107140555Speter#define APIC_THERMAL_INT (APIC_LOCAL_INTS + 1) 108208507Sjhb#define APIC_CMC_INT (APIC_LOCAL_INTS + 2) 109121986Sjhb 110208507Sjhb#define APIC_IPI_INTS (APIC_LOCAL_INTS + 3) 111140555Speter#define IPI_RENDEZVOUS (APIC_IPI_INTS) /* Inter-CPU rendezvous. */ 112121986Sjhb#define IPI_INVLTLB (APIC_IPI_INTS + 1) /* TLB Shootdown IPIs */ 113121986Sjhb#define IPI_INVLPG (APIC_IPI_INTS + 2) 114121986Sjhb#define IPI_INVLRNG (APIC_IPI_INTS + 3) 115158236Sjhb#define IPI_INVLCACHE (APIC_IPI_INTS + 4) 116140555Speter/* Vector to handle bitmap based IPIs */ 117158236Sjhb#define IPI_BITMAP_VECTOR (APIC_IPI_INTS + 6) 118121986Sjhb 119140555Speter/* IPIs handled by IPI_BITMAPED_VECTOR (XXX ups is there a better place?) */ 120140555Speter#define IPI_AST 0 /* Generate software trap. */ 121147181Sups#define IPI_PREEMPT 1 122191744Smav#define IPI_HARDCLOCK 2 123212541Smav#define IPI_BITMAP_LAST IPI_HARDCLOCK 124140555Speter#define IPI_IS_BITMAPED(x) ((x) <= IPI_BITMAP_LAST) 125140555Speter 126158236Sjhb#define IPI_STOP (APIC_IPI_INTS + 7) /* Stop CPU until restarted. */ 127189903Sjkim#define IPI_SUSPEND (APIC_IPI_INTS + 8) /* Suspend CPU until restarted. */ 128196196Sattilio#define IPI_STOP_HARD (APIC_IPI_INTS + 9) /* Stop CPU with a NMI. */ 129140555Speter 130140555Speter/* 131140555Speter * The spurious interrupt can share the priority class with the IPIs since 132140555Speter * it is not a normal interrupt. (Does not use the APIC's interrupt fifo) 133140555Speter */ 134121986Sjhb#define APIC_SPURIOUS_INT 255 135121986Sjhb 136121986Sjhb#ifndef LOCORE 137121986Sjhb 138121986Sjhb#define APIC_IPI_DEST_SELF -1 139121986Sjhb#define APIC_IPI_DEST_ALL -2 140121986Sjhb#define APIC_IPI_DEST_OTHERS -3 141121986Sjhb 142131778Speter#define APIC_BUS_UNKNOWN -1 143131778Speter#define APIC_BUS_ISA 0 144131778Speter#define APIC_BUS_EISA 1 145131778Speter#define APIC_BUS_PCI 2 146131778Speter#define APIC_BUS_MAX APIC_BUS_PCI 147131778Speter 148121986Sjhb/* 149121986Sjhb * An APIC enumerator is a psuedo bus driver that enumerates APIC's including 150121986Sjhb * CPU's and I/O APIC's. 151121986Sjhb */ 152121986Sjhbstruct apic_enumerator { 153121986Sjhb const char *apic_name; 154121986Sjhb int (*apic_probe)(void); 155121986Sjhb int (*apic_probe_cpus)(void); 156121986Sjhb int (*apic_setup_local)(void); 157121986Sjhb int (*apic_setup_io)(void); 158121986Sjhb SLIST_ENTRY(apic_enumerator) apic_next; 159121986Sjhb}; 160121986Sjhb 161121986Sjhbinthand_t 162121986Sjhb IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3), 163122690Sjhb IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6), 164208507Sjhb IDTVEC(apic_isr7), IDTVEC(cmcint), IDTVEC(errorint), 165208507Sjhb IDTVEC(spuriousint), IDTVEC(timerint); 166121986Sjhb 167167747Sjhbextern vm_paddr_t lapic_paddr; 168187880Sjeffextern int apic_cpuids[]; 169167747Sjhb 170187880Sjeffu_int apic_alloc_vector(u_int apic_id, u_int irq); 171187880Sjeffu_int apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count, 172187880Sjeff u_int align); 173187880Sjeffvoid apic_disable_vector(u_int apic_id, u_int vector); 174187880Sjeffvoid apic_enable_vector(u_int apic_id, u_int vector); 175187880Sjeffvoid apic_free_vector(u_int apic_id, u_int vector, u_int irq); 176187880Sjeffu_int apic_idt_to_irq(u_int apic_id, u_int vector); 177121986Sjhbvoid apic_register_enumerator(struct apic_enumerator *enumerator); 178187880Sjeffu_int apic_cpuid(u_int apic_id); 179167247Sjhbvoid *ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase); 180121986Sjhbint ioapic_disable_pin(void *cookie, u_int pin); 181121986Sjhbint ioapic_get_vector(void *cookie, u_int pin); 182121986Sjhbvoid ioapic_register(void *cookie); 183121986Sjhbint ioapic_remap_vector(void *cookie, u_int pin, int vector); 184131778Speterint ioapic_set_bus(void *cookie, u_int pin, int bus_type); 185121986Sjhbint ioapic_set_extint(void *cookie, u_int pin); 186121986Sjhbint ioapic_set_nmi(void *cookie, u_int pin); 187129284Speterint ioapic_set_polarity(void *cookie, u_int pin, enum intr_polarity pol); 188129284Speterint ioapic_set_triggermode(void *cookie, u_int pin, 189129284Speter enum intr_trigger trigger); 190121986Sjhbint ioapic_set_smi(void *cookie, u_int pin); 191121986Sjhbvoid lapic_create(u_int apic_id, int boot_cpu); 192121986Sjhbvoid lapic_disable(void); 193196224Sjhbvoid lapic_disable_pmc(void); 194121986Sjhbvoid lapic_dump(const char *str); 195208507Sjhbvoid lapic_enable_cmc(void); 196196224Sjhbint lapic_enable_pmc(void); 197122572Sjhbvoid lapic_eoi(void); 198121986Sjhbint lapic_id(void); 199167247Sjhbvoid lapic_init(vm_paddr_t addr); 200121986Sjhbint lapic_intr_pending(u_int vector); 201121986Sjhbvoid lapic_ipi_raw(register_t icrlo, u_int dest); 202121986Sjhbvoid lapic_ipi_vectored(u_int vector, int dest); 203121986Sjhbint lapic_ipi_wait(int delay); 204208507Sjhbvoid lapic_handle_cmc(void); 205205851Sjhbvoid lapic_handle_error(void); 206165303Skmacyvoid lapic_handle_intr(int vector, struct trapframe *frame); 207165303Skmacyvoid lapic_handle_timer(struct trapframe *frame); 208196224Sjhbvoid lapic_reenable_pmc(void); 209121986Sjhbvoid lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id); 210121986Sjhbint lapic_set_lvt_mask(u_int apic_id, u_int lvt, u_char masked); 211121986Sjhbint lapic_set_lvt_mode(u_int apic_id, u_int lvt, u_int32_t mode); 212129284Speterint lapic_set_lvt_polarity(u_int apic_id, u_int lvt, 213129284Speter enum intr_polarity pol); 214129284Speterint lapic_set_lvt_triggermode(u_int apic_id, u_int lvt, 215129284Speter enum intr_trigger trigger); 216140555Spetervoid lapic_set_tpr(u_int vector); 217163219Sjhbvoid lapic_setup(int boot); 218255040Sgibbsvoid xen_intr_handle_upcall(struct trapframe *frame); 219283280Swhuvoid hv_vector_handler(struct trapframe *frame); 220121986Sjhb 221121986Sjhb#endif /* !LOCORE */ 222121986Sjhb#endif /* _MACHINE_APICVAR_H_ */ 223