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 <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_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_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); | |||||
} | |||||
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); | |||||
} | |||||
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); | |||||
} | |||||
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); | |||||
} | |||||
bool | |||||
xen_arch_intr_has_handlers(struct xenisrc *isrc) | |||||
{ | |||||
return (isrc->xi_arch.xai_intsrc.is_handlers != 0); | |||||
} | |||||
void | |||||
xen_arch_intr_execute_handlers(struct xenisrc *isrc, struct trapframe *frame) | |||||
{ | |||||
intr_execute_handlers(&isrc->xi_arch.xai_intsrc, frame); | |||||
} | |||||
int | |||||
xen_arch_intr_add_handler(const char *name, driver_filter_t filter, | |||||
driver_intr_t handler, void *arg, enum intr_type flags, | |||||
struct xenisrc *isrc) | |||||
{ | |||||
return (intr_add_handler(name, isrc->xi_arch.xai_vector, filter, | |||||
handler, arg, flags, &isrc->xi_cookie, 0)); | |||||
} | |||||
int | |||||
xen_arch_intr_describe(struct xenisrc *isrc, const char *descr) | |||||
{ | |||||
return (intr_describe(isrc->xi_arch.xai_vector, isrc->xi_cookie, descr)); | |||||
} | |||||
int | |||||
xen_arch_intr_remove_handler(struct xenisrc *isrc) | |||||
{ | |||||
return (intr_remove_handler(isrc->xi_cookie)); | |||||
} | |||||
int | |||||
xen_arch_intr_event_bind(struct xenisrc *isrc, u_int cpu) | |||||
{ | |||||
return (intr_event_bind(isrc->xi_arch.xai_intsrc.is_event, cpu)); | |||||
} |