aboutsummaryrefslogtreecommitdiffstats
path: root/xenolinux-2.4.25-sparse/include/asm-xen
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-03-25 11:51:43 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-03-25 11:51:43 +0000
commit163ce6261c54cbfe6fec6f011497a3d14d30b5e4 (patch)
tree00c39fb06d4bb8faf24d95fb4ce373757d382cd3 /xenolinux-2.4.25-sparse/include/asm-xen
parentd6142516315665bd6d38c15e7ad826ed8d542f6b (diff)
downloadxen-163ce6261c54cbfe6fec6f011497a3d14d30b5e4.tar.gz
xen-163ce6261c54cbfe6fec6f011497a3d14d30b5e4.tar.bz2
xen-163ce6261c54cbfe6fec6f011497a3d14d30b5e4.zip
bitkeeper revision 1.825.1.2 (4062c7cfNjG5kiKHfguNA2SIXnllng)
Many files: New IRQ upcall world. evtchn.c: Rename: xenolinux-2.4.25-sparse/arch/xen/kernel/hypervisor.c -> xenolinux-2.4.25-sparse/arch/xen/kernel/evtchn.c
Diffstat (limited to 'xenolinux-2.4.25-sparse/include/asm-xen')
-rw-r--r--xenolinux-2.4.25-sparse/include/asm-xen/evtchn.h87
-rw-r--r--xenolinux-2.4.25-sparse/include/asm-xen/hypervisor.h4
-rw-r--r--xenolinux-2.4.25-sparse/include/asm-xen/irq.h27
-rw-r--r--xenolinux-2.4.25-sparse/include/asm-xen/keyboard.h7
-rw-r--r--xenolinux-2.4.25-sparse/include/asm-xen/system.h25
5 files changed, 119 insertions, 31 deletions
diff --git a/xenolinux-2.4.25-sparse/include/asm-xen/evtchn.h b/xenolinux-2.4.25-sparse/include/asm-xen/evtchn.h
index 88c278d86e..2aea319dd5 100644
--- a/xenolinux-2.4.25-sparse/include/asm-xen/evtchn.h
+++ b/xenolinux-2.4.25-sparse/include/asm-xen/evtchn.h
@@ -1,7 +1,8 @@
/******************************************************************************
* evtchn.h
*
- * Driver for receiving and demuxing event-channel signals.
+ * Communication via Xen event channels.
+ * Also definitions for the device that demuxes notifications to userspace.
*
* Copyright (c) 2004, K A Fraser
*/
@@ -9,10 +10,81 @@
#ifndef __ASM_EVTCHN_H__
#define __ASM_EVTCHN_H__
-typedef void (*evtchn_receiver_t)(unsigned int);
-#define PORT_NORMAL 0x0000
-#define PORT_DISCONNECT 0x8000
-#define PORTIDX_MASK 0x7fff
+#include <linux/config.h>
+#include <asm/hypervisor.h>
+#include <asm/ptrace.h>
+
+/*
+ * LOW-LEVEL DEFINITIONS
+ */
+
+/* Entry point for notifications into Linux subsystems. */
+void evtchn_do_upcall(struct pt_regs *regs);
+
+/* Entry point for notifications into the userland character device. */
+void evtchn_device_upcall(int port, int exception);
+
+static inline void mask_evtchn(int port)
+{
+ shared_info_t *s = HYPERVISOR_shared_info;
+ set_bit(port, &s->evtchn_mask[0]);
+}
+
+/*
+ * I haven't thought too much about the synchronisation in here against
+ * other CPUs, but all the bit-update operations are reorder barriers on
+ * x86 so reordering concerns aren't a problem for now. Some mb() calls
+ * would be required on weaker architectures I think. -- KAF (24/3/2004)
+ */
+static inline void unmask_evtchn(int port)
+{
+ shared_info_t *s = HYPERVISOR_shared_info;
+ int need_upcall = 0;
+
+ clear_bit(port, &s->evtchn_mask[0]);
+
+ /*
+ * The following is basically the equivalent of 'hw_resend_irq'. Just like
+ * a real IO-APIC we 'lose the interrupt edge' if the channel is masked.
+ */
+
+ /* Asserted a standard notification? */
+ if ( test_bit (port, &s->evtchn_pending[0]) &&
+ !test_and_set_bit(port>>5, &s->evtchn_pending_sel) )
+ need_upcall = 1;
+
+ /* Asserted an exceptional notification? */
+ if ( test_bit (port, &s->evtchn_exception[0]) &&
+ !test_and_set_bit(port>>5, &s->evtchn_exception_sel) )
+ need_upcall = 1;
+
+ /* If asserted either type of notification, check the master flags. */
+ if ( need_upcall &&
+ !test_and_set_bit(0, &s->evtchn_upcall_pending) &&
+ !test_bit (0, &s->evtchn_upcall_mask) )
+ evtchn_do_upcall(NULL);
+}
+
+static inline void clear_evtchn(int port)
+{
+ shared_info_t *s = HYPERVISOR_shared_info;
+ clear_bit(port, &s->evtchn_pending[0]);
+}
+
+static inline void clear_evtchn_exception(int port)
+{
+ shared_info_t *s = HYPERVISOR_shared_info;
+ clear_bit(port, &s->evtchn_exception[0]);
+}
+
+
+/*
+ * CHARACTER-DEVICE DEFINITIONS
+ */
+
+#define PORT_NORMAL 0x0000
+#define PORT_EXCEPTION 0x8000
+#define PORTIDX_MASK 0x7fff
/* /dev/xen/evtchn resides at device number major=10, minor=200 */
#define EVTCHN_MINOR 200
@@ -21,9 +93,4 @@ typedef void (*evtchn_receiver_t)(unsigned int);
/* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */
#define EVTCHN_RESET _IO('E', 1)
-int evtchn_request_port(unsigned int port, evtchn_receiver_t rx_fn);
-int evtchn_free_port(unsigned int port);
-void evtchn_clear_port(unsigned int port);
-
-
#endif /* __ASM_EVTCHN_H__ */
diff --git a/xenolinux-2.4.25-sparse/include/asm-xen/hypervisor.h b/xenolinux-2.4.25-sparse/include/asm-xen/hypervisor.h
index 34d0974471..73149d5426 100644
--- a/xenolinux-2.4.25-sparse/include/asm-xen/hypervisor.h
+++ b/xenolinux-2.4.25-sparse/include/asm-xen/hypervisor.h
@@ -25,10 +25,6 @@ union start_info_union
extern union start_info_union start_info_union;
#define start_info (start_info_union.start_info)
-/* arch/xen/kernel/hypervisor.c */
-void do_hypervisor_callback(struct pt_regs *regs);
-
-
/* arch/xen/mm/hypervisor.c */
/*
* NB. ptr values should be PHYSICAL, not MACHINE. 'vals' should be already
diff --git a/xenolinux-2.4.25-sparse/include/asm-xen/irq.h b/xenolinux-2.4.25-sparse/include/asm-xen/irq.h
index 917a05334d..6d175ce6ab 100644
--- a/xenolinux-2.4.25-sparse/include/asm-xen/irq.h
+++ b/xenolinux-2.4.25-sparse/include/asm-xen/irq.h
@@ -14,19 +14,32 @@
#include <asm/hypervisor.h>
#include <asm/ptrace.h>
-#define NR_IRQS 256
+/*
+ * The flat IRQ space is divided into two regions:
+ * 1. A one-to-one mapping of real physical IRQs. This space is only used
+ * if we have physical device-access privilege. This region is at the
+ * start of the IRQ space so that existing device drivers do not need
+ * to be modified to translate physical IRQ numbers into our IRQ space.
+ * 3. A dynamic mapping of inter-domain and Xen-sourced virtual IRQs. These
+ * are bound using the provided bind/unbind functions.
+ */
-#define PHYS_IRQ_BASE 0
-#define NR_PHYS_IRQS 128
+#define PIRQ_BASE 0
+#define NR_PIRQS 128
-#define HYPEREVENT_IRQ_BASE 128
-#define NR_HYPEREVENT_IRQS 128
+#define DYNIRQ_BASE (PIRQ_BASE + NR_PIRQS)
+#define NR_DYNIRQS 128
-#define HYPEREVENT_IRQ(_ev) ((_ev) + HYPEREVENT_IRQ_BASE)
-#define HYPEREVENT_FROM_IRQ(_irq) ((_irq) - HYPEREVENT_IRQ_BASE)
+#define NR_IRQS (NR_PIRQS + NR_DYNIRQS)
extern void physirq_init(void);
+/* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */
+extern int bind_virq_to_irq(int virq);
+extern void unbind_virq_from_irq(int virq);
+extern int bind_evtchn_to_irq(int evtchn);
+extern void unbind_evtchn_from_irq(int evtchn);
+
#define irq_cannonicalize(_irq) (_irq)
extern void disable_irq(unsigned int);
diff --git a/xenolinux-2.4.25-sparse/include/asm-xen/keyboard.h b/xenolinux-2.4.25-sparse/include/asm-xen/keyboard.h
index 79d72da929..9066a3bada 100644
--- a/xenolinux-2.4.25-sparse/include/asm-xen/keyboard.h
+++ b/xenolinux-2.4.25-sparse/include/asm-xen/keyboard.h
@@ -58,8 +58,11 @@ static inline int xen_kbd_controller_present ()
/* resource allocation */
#define kbd_request_region() \
do { } while (0)
-#define kbd_request_irq(handler) \
- request_irq(HYPEREVENT_IRQ(_EVENT_PS2), handler, 0, "ps/2", NULL)
+#define kbd_request_irq(handler) \
+ do { \
+ int irq = bind_virq_to_irq(VIRQ_PS2); \
+ request_irq(irq, handler, 0, "ps/2", NULL); \
+ } while ( 0 )
/* could implement these with command to xen to filter mouse stuff... */
#define aux_request_irq(hand, dev_id) 0
diff --git a/xenolinux-2.4.25-sparse/include/asm-xen/system.h b/xenolinux-2.4.25-sparse/include/asm-xen/system.h
index 3b59252ca3..2c1194a781 100644
--- a/xenolinux-2.4.25-sparse/include/asm-xen/system.h
+++ b/xenolinux-2.4.25-sparse/include/asm-xen/system.h
@@ -7,6 +7,7 @@
#include <asm/segment.h>
#include <asm/hypervisor.h>
#include <linux/bitops.h> /* for LOCK_PREFIX */
+#include <asm/evtchn.h>
#ifdef __KERNEL__
@@ -319,29 +320,38 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
#define set_wmb(var, value) do { var = value; wmb(); } while (0)
+/*
+ * NB. ALl the following routines are SMP-safe on x86, even where they look
+ * possibly racy. For example, we must ensure that we clear the mask bit and
+ * /then/ check teh pending bit. But this will happen because the bit-update
+ * operations are ordering barriers.
+ *
+ * For this reason also, many uses of 'barrier' here are rather anal. But
+ * they do no harm.
+ */
#define __cli() \
do { \
- clear_bit(EVENTS_MASTER_ENABLE_BIT, &HYPERVISOR_shared_info->events_mask);\
+ set_bit(0, &HYPERVISOR_shared_info->evtchn_upcall_mask); \
barrier(); \
} while (0)
#define __sti() \
do { \
shared_info_t *_shared = HYPERVISOR_shared_info; \
- set_bit(EVENTS_MASTER_ENABLE_BIT, &_shared->events_mask); \
+ clear_bit(0, &_shared->evtchn_upcall_mask); \
barrier(); \
- if ( unlikely(_shared->events) ) do_hypervisor_callback(NULL); \
+ if ( unlikely(test_bit(0, &_shared->evtchn_upcall_pending)) ) \
+ evtchn_do_upcall(NULL); \
} while (0)
#define __save_flags(x) \
do { \
- (x) = test_bit(EVENTS_MASTER_ENABLE_BIT, \
- &HYPERVISOR_shared_info->events_mask); \
+ (x) = test_bit(0, &HYPERVISOR_shared_info->evtchn_upcall_mask); \
barrier(); \
} while (0)
-#define __restore_flags(x) do { if (x) __sti(); } while (0)
+#define __restore_flags(x) do { if (x) __cli(); else __sti(); } while (0)
#define safe_halt() ((void)0)
@@ -350,8 +360,7 @@ do { \
#define local_irq_save(x) \
do { \
- (x) = test_and_clear_bit(EVENTS_MASTER_ENABLE_BIT, \
- &HYPERVISOR_shared_info->events_mask); \
+ (x) = test_and_set_bit(0, &HYPERVISOR_shared_info->evtchn_upcall_mask); \
barrier(); \
} while (0)
#define local_irq_restore(x) __restore_flags(x)