Changeset View
Changeset View
Standalone View
Standalone View
sys/x86/xen/xen_arch_intr.c
- This file was added.
/* | |||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD | |||||
* | |||||
* Copyright (c) 2015 Julien Grall | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
*/ | |||||
#include <sys/cdefs.h> | |||||
__FBSDID("$FreeBSD$"); | |||||
#include <sys/param.h> | |||||
#include <sys/systm.h> | |||||
#include <sys/bus.h> | |||||
#include <sys/malloc.h> | |||||
#include <sys/kernel.h> | |||||
#include <sys/limits.h> | |||||
#include <sys/lock.h> | |||||
#include <sys/mutex.h> | |||||
#include <sys/interrupt.h> | |||||
#include <sys/pcpu.h> | |||||
#include <sys/smp.h> | |||||
#include <sys/stddef.h> | |||||
#include <machine/intr_machdep.h> | |||||
#include <x86/apicvar.h> | |||||
#include <xen/xen-os.h> | |||||
#include <xen/xen_intr.h> | |||||
#include <machine/xen/arch-intr.h> | |||||
/********************************* EVTCHN PIC ********************************/ | |||||
static void | |||||
xen_intr_pic_enable_source(struct intsrc *isrc) | |||||
{ | |||||
CTASSERT(offsetof(struct xenisrc, xi_arch.xai_intsrc) == 0); | |||||
xen_intr_enable_source((struct xenisrc *)isrc); | |||||
} | |||||
static void | |||||
xen_intr_pic_disable_source(struct intsrc *isrc, int eoi) | |||||
{ | |||||
CTASSERT(offsetof(struct xenisrc, xi_arch.xai_intsrc) == 0); | |||||
xen_intr_disable_source((struct xenisrc *)isrc, eoi == PIC_EOI); | |||||
} | |||||
static void | |||||
xen_intr_pic_eoi_source(struct intsrc *isrc) | |||||
{ | |||||
CTASSERT(offsetof(struct xenisrc, xi_arch.xai_intsrc) == 0); | |||||
xen_intr_eoi_source((struct xenisrc *)isrc); | |||||
} | |||||
static void | |||||
xen_intr_pic_enable_intr(struct intsrc *isrc) | |||||
{ | |||||
CTASSERT(offsetof(struct xenisrc, xi_arch.xai_intsrc) == 0); | |||||
xen_intr_enable_intr((struct xenisrc *)isrc); | |||||
} | |||||
static void | |||||
xen_intr_pic_disable_intr(struct intsrc *isrc) | |||||
{ | |||||
CTASSERT(offsetof(struct xenisrc, xi_arch.xai_intsrc) == 0); | |||||
xen_intr_disable_intr((struct xenisrc *)isrc); | |||||
} | |||||
/** | |||||
* Determine the global interrupt vector number for | |||||
* a Xen interrupt source. | |||||
* | |||||
* \param isrc The interrupt source to query. | |||||
* | |||||
* \return The vector number corresponding to the given interrupt source. | |||||
*/ | |||||
static int | |||||
xen_intr_pic_vector(struct intsrc *isrc) | |||||
{ | |||||
CTASSERT(offsetof(struct xenisrc, xi_arch.xai_intsrc) == 0); | |||||
return (((xen_arch_isrc_t *)isrc)->xai_vector); | |||||
} | |||||
/** | |||||
* Determine whether or not interrupt events are pending on the | |||||
* the given interrupt source. | |||||
* | |||||
* \param isrc The interrupt source to query. | |||||
* | |||||
* \returns 0 if no events are pending, otherwise non-zero. | |||||
*/ | |||||
static int | |||||
xen_intr_pic_source_pending(struct intsrc *isrc) | |||||
{ | |||||
/* | |||||
* EventChannels are edge triggered and never masked. | |||||
* There can be no pending events. | |||||
*/ | |||||
return (0); | |||||
} | |||||
static void | |||||
xen_intr_pic_suspend(struct pic *pic) | |||||
{ | |||||
xen_intr_suspend(); | |||||
} | |||||
static void | |||||
xen_intr_pic_resume(struct pic *pic, bool suspend_cancelled) | |||||
{ | |||||
xen_intr_resume(suspend_cancelled); | |||||
} | |||||
/** | |||||
* Perform configuration of an interrupt source. | |||||
* | |||||
* \param isrc The interrupt source to configure. | |||||
* \param trig Edge or level. | |||||
* \param pol Active high or low. | |||||
* | |||||
* \returns 0 if no events are pending, otherwise non-zero. | |||||
*/ | |||||
static int | |||||
xen_intr_pic_config_intr(struct intsrc *isrc, enum intr_trigger trig, | |||||
enum intr_polarity pol) | |||||
{ | |||||
/* Configuration is only possible via the evtchn apis. */ | |||||
return (ENODEV); | |||||
} | |||||
static int | |||||
xen_intr_pic_assign_cpu(struct intsrc *isrc, u_int apic_id) | |||||
{ | |||||
CTASSERT(offsetof(struct xenisrc, xi_arch.xai_intsrc) == 0); | |||||
return (xen_intr_assign_cpu((struct xenisrc *)isrc, | |||||
apic_cpuid(apic_id))); | |||||
} | |||||
/** | |||||
* PIC interface for all event channel port types except physical IRQs. | |||||
*/ | |||||
struct pic xen_intr_pic = { | |||||
.pic_enable_source = xen_intr_pic_enable_source, | |||||
.pic_disable_source = xen_intr_pic_disable_source, | |||||
.pic_eoi_source = xen_intr_pic_eoi_source, | |||||
.pic_enable_intr = xen_intr_pic_enable_intr, | |||||
.pic_disable_intr = xen_intr_pic_disable_intr, | |||||
.pic_vector = xen_intr_pic_vector, | |||||
.pic_source_pending = xen_intr_pic_source_pending, | |||||
.pic_suspend = xen_intr_pic_suspend, | |||||
.pic_resume = xen_intr_pic_resume, | |||||
.pic_config_intr = xen_intr_pic_config_intr, | |||||
.pic_assign_cpu = xen_intr_pic_assign_cpu | |||||
}; | |||||
/****************************** ARCH wrappers ********************************/ | |||||
void | |||||
xen_arch_intr_init(void) | |||||
{ | |||||
intr_register_pic(&xen_intr_pic); | |||||
} |