1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 /*
  27  * evtchn.h (renamed to evtchn_impl.h)
  28  *
  29  * Communication via Xen event channels.
  30  * Also definitions for the device that demuxes notifications to userspace.
  31  *
  32  * Copyright (c) 2004-2005, K A Fraser
  33  *
  34  * This file may be distributed separately from the Linux kernel, or
  35  * incorporated into other software packages, subject to the following license:
  36  *
  37  * Permission is hereby granted, free of charge, to any person obtaining a copy
  38  * of this source file (the "Software"), to deal in the Software without
  39  * restriction, including without limitation the rights to use, copy, modify,
  40  * merge, publish, distribute, sublicense, and/or sell copies of the Software,
  41  * and to permit persons to whom the Software is furnished to do so, subject to
  42  * the following conditions:
  43  *
  44  * The above copyright notice and this permission notice shall be included in
  45  * all copies or substantial portions of the Software.
  46  *
  47  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  48  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  49  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  50  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  51  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  52  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  53  * IN THE SOFTWARE.
  54  */
  55 
  56 #ifndef _SYS_EVTCHN_H
  57 #define _SYS_EVTCHN_H
  58 
  59 #ifdef __cplusplus
  60 extern "C" {
  61 #endif
  62 
  63 #include <sys/types.h>
  64 #include <sys/privregs.h>
  65 #include <sys/systm.h>
  66 #include <sys/traptrace.h>
  67 #include <sys/ddi_intr.h>
  68 #include <sys/ddi_intr_impl.h>
  69 #include <sys/avintr.h>
  70 #include <sys/cpuvar.h>
  71 #include <sys/hypervisor.h>
  72 
  73 /* evtchn binding types */
  74 #define IRQT_UNBOUND    0       /* unassigned irq */
  75 #define IRQT_PIRQ       1       /* IRQ from phys hdw device */
  76 #define IRQT_VIRQ       2       /* Virtual IRQ from Xen */
  77 #define IRQT_IPI        3       /* Inter VCPU interrupt IRQ */
  78 #define IRQT_EVTCHN     4       /* Virtual device IRQ */
  79 #define IRQT_DEV_EVTCHN 5       /* Special evtchn device IRQ */
  80 
  81 #define SET_EVTCHN_BIT(bit, arrayp) \
  82         ((arrayp)[bit >> EVTCHN_SHIFT] |= \
  83         (1ul << ((bit) & ((1ul << EVTCHN_SHIFT) - 1))))
  84 #define CLEAR_EVTCHN_BIT(bit, arrayp) \
  85         ((arrayp)[bit >> EVTCHN_SHIFT] &= \
  86                 ~((1ul << ((bit) & ((1ul << EVTCHN_SHIFT) - 1)))))
  87 #define TEST_EVTCHN_BIT(bit, arrayp) \
  88         ((arrayp)[bit >> EVTCHN_SHIFT] & \
  89                 (1ul << ((bit) & ((1ul << EVTCHN_SHIFT) - 1))))
  90 
  91 /* Xen will never allocate port zero for any purpose. */
  92 #define INVALID_EVTCHN  0
  93 
  94 /* XXPV - should these defines be somewhere else? xenos.h perhaps? */
  95 
  96 #define IPL_DEBUG       15      /* domain debug interrupt */
  97 #define IPL_CONS        9
  98 #define IPL_VIF         6
  99 #define IPL_VBD         5
 100 #define IPL_EVTCHN      1
 101 
 102 #define PIRQ_BASE       0       /* base of pirq range */
 103 #define NR_PIRQS        256     /* Number of supported physical irqs */
 104 #define DYNIRQ_BASE     (PIRQ_BASE + NR_PIRQS) /* base of dynamic irq range */
 105 #define NR_DYNIRQS      256     /* Number of dynamic irqs */
 106 #define NR_IRQS         (NR_PIRQS + NR_DYNIRQS) /* total irq count */
 107 
 108 #define PIRQ_TO_IRQ(pirq)       ((pirq) + PIRQ_BASE)
 109 #define IRQ_TO_PIRQ(irq)        ((irq) - PIRQ_BASE)
 110 
 111 #define DYNIRQ_TO_IRQ(dirq)     ((dirq) + DYNIRQ_BASE)
 112 #define IRQ_TO_DYNIRQ(irq)      ((irq) - DYNIRQ_BASE)
 113 
 114 #if defined(_LP64)
 115 #define EVTCHN_SHIFT    6       /* log2(NBBY * sizeof (ulong_t)) */
 116 #else
 117 #define EVTCHN_SHIFT    5       /* log2(NBBY * sizeof (ulong_t)) */
 118 #endif
 119 
 120 #define INVALID_IRQ -1
 121 
 122 extern int ec_dev_irq;
 123 extern kmutex_t ec_lock;
 124 
 125 typedef struct mec_info {
 126         ushort_t mi_evtchns[NCPU];      /* event channels for this IRQ */
 127         short mi_irq;                   /* the IRQ, or INVALID_IRQ */
 128         char mi_shared;                 /* one evtchn for all CPUs? */
 129 } mec_info_t;
 130 
 131 /*
 132  * Careful: ii_ipl is /only/ set if there's a handler for this IRQ.
 133  */
 134 typedef struct irq_info {
 135         union {
 136                 ushort_t evtchn;        /* event channel */
 137                 ushort_t index;         /* index to next table if mec */
 138         } ii_u;
 139         uchar_t ii_type;                /* IRQ type as above */
 140         union {
 141                 uchar_t ipl;            /* IPL of IRQ, != 0 => has handler */
 142                 uchar_t has_handler;    /* alternate name for ipl */
 143         } ii_u2;
 144 } irq_info_t;
 145 
 146 extern int ec_is_edge_pirq(int);
 147 extern int ec_init(void);
 148 extern void ec_init_debug_irq(void);
 149 extern void ec_suspend(void);
 150 extern void ec_resume(void);
 151 extern void ec_wait_on_evtchn(int, int (*)(void *), void *);
 152 extern void ec_wait_on_ipi(int, int (*)(void *), void *);
 153 
 154 extern void ec_setup_pirq(int, int, cpuset_t *);
 155 extern void ec_set_irq_affinity(int, cpuset_t);
 156 extern int ec_set_irq_priority(int, int);
 157 
 158 extern int ec_bind_ipi_to_irq(int, int);
 159 extern void ec_bind_cpu_ipis(int);
 160 extern int ec_bind_evtchn_to_irq(int);
 161 extern int ec_bind_virq_to_irq(int, int);
 162 extern void ec_unbind_irq(int irq);
 163 
 164 extern void ec_send_ipi(int, int);
 165 extern void ec_try_ipi(int, int);
 166 extern void ec_clear_irq(int);
 167 extern void ec_unmask_irq(int);
 168 extern void ec_try_unmask_irq(int);
 169 extern int ec_block_irq(int);
 170 extern void ec_unpend_irq(int);
 171 extern int ec_irq_needs_rebind(int, int);
 172 extern int ec_irq_rebindable(int);
 173 extern int ec_pending_irq(unsigned int);
 174 extern void ec_enable_irq(unsigned int);
 175 extern void ec_disable_irq(unsigned int);
 176 
 177 extern int xen_bind_interdomain(int, int, int *);
 178 extern int xen_bind_virq(unsigned int, processorid_t, int *);
 179 extern int xen_alloc_unbound_evtchn(int, int *);
 180 extern void ec_bind_vcpu(int, int);
 181 
 182 extern int ec_mask_evtchn(unsigned int);
 183 extern void ec_unmask_evtchn(unsigned int);
 184 extern void ec_clear_evtchn(unsigned int);
 185 
 186 extern void ec_notify_via_evtchn(unsigned int);
 187 
 188 /*
 189  * /dev/xen/evtchn handling.
 190  */
 191 extern void ec_irq_add_evtchn(int, int);
 192 extern void ec_irq_rm_evtchn(int, int);
 193 extern int ec_dev_alloc_irq(void);
 194 
 195 #ifdef __cplusplus
 196 }
 197 #endif
 198 
 199 #endif /* _SYS_EVTCHN_H */