aboutsummaryrefslogtreecommitdiffstats
path: root/xen/include/asm-x86/hvm
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2006-11-21 19:22:25 +0000
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2006-11-21 19:22:25 +0000
commitd46c9ce0d7b805e6b4bbf54b381728a391e23e45 (patch)
treeea5cbf1372bb5d4f2dbc953eb70a84a90f4cc7d0 /xen/include/asm-x86/hvm
parent3b724073d6a410b5a967a6827d2f8c50693aadfb (diff)
downloadxen-d46c9ce0d7b805e6b4bbf54b381728a391e23e45.tar.gz
xen-d46c9ce0d7b805e6b4bbf54b381728a391e23e45.tar.bz2
xen-d46c9ce0d7b805e6b4bbf54b381728a391e23e45.zip
[HVM] Reworked interrupt distribution logic.
TODO: 1. Fix IO-APIC ID to not conflict with LAPIC IDS. 2. Fix i8259 device model (seems to work already though!). 3. Add INTSRC overrides in MPBIOS and ACPI tables so that PCI legacy IRQ routing always ends up at an IO-APIC input with level trigger. Restricting link routing to {5,6,10,11} and setting overrides for all four of those would work. Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'xen/include/asm-x86/hvm')
-rw-r--r--xen/include/asm-x86/hvm/domain.h11
-rw-r--r--xen/include/asm-x86/hvm/io.h1
-rw-r--r--xen/include/asm-x86/hvm/irq.h107
-rw-r--r--xen/include/asm-x86/hvm/vioapic.h20
-rw-r--r--xen/include/asm-x86/hvm/vpic.h18
5 files changed, 123 insertions, 34 deletions
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index 77c691e351..63159504ae 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -16,16 +16,15 @@
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
- *
*/
#ifndef __ASM_X86_HVM_DOMAIN_H__
#define __ASM_X86_HVM_DOMAIN_H__
-#include <asm/hvm/vpic.h>
+#include <asm/hvm/irq.h>
#include <asm/hvm/vpt.h>
#include <asm/hvm/vlapic.h>
-#include <asm/hvm/vioapic.h>
+#include <asm/hvm/io.h>
#include <public/hvm/params.h>
struct hvm_domain {
@@ -35,13 +34,9 @@ struct hvm_domain {
s64 tsc_frequency;
struct pl_time pl_time;
- struct vpic vpic;
- struct vioapic vioapic;
struct hvm_io_handler io_handler;
- unsigned char round_info[256];
- spinlock_t round_robin_lock;
- int interrupt_request;
+ struct hvm_irq irq;
/* hvm_print_line() logging. */
char pbuf[80];
diff --git a/xen/include/asm-x86/hvm/io.h b/xen/include/asm-x86/hvm/io.h
index 55ac4b5c3c..028a885eb2 100644
--- a/xen/include/asm-x86/hvm/io.h
+++ b/xen/include/asm-x86/hvm/io.h
@@ -147,7 +147,6 @@ extern void send_pio_req(unsigned long port, unsigned long count, int size,
extern void handle_mmio(unsigned long gpa);
extern void hvm_interrupt_post(struct vcpu *v, int vector, int type);
extern void hvm_io_assist(struct vcpu *v);
-extern void pic_irq_request(void *data, int level);
extern int cpu_get_interrupt(struct vcpu *v, int *type);
extern int cpu_has_pending_irq(struct vcpu *v);
diff --git a/xen/include/asm-x86/hvm/irq.h b/xen/include/asm-x86/hvm/irq.h
new file mode 100644
index 0000000000..3115889219
--- /dev/null
+++ b/xen/include/asm-x86/hvm/irq.h
@@ -0,0 +1,107 @@
+/******************************************************************************
+ * irq.h
+ *
+ * Interrupt distribution and delivery logic.
+ *
+ * Copyright (c) 2006, K A Fraser, XenSource Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef __ASM_X86_HVM_IRQ_H__
+#define __ASM_X86_HVM_IRQ_H__
+
+#include <xen/types.h>
+#include <xen/spinlock.h>
+#include <asm/hvm/vpic.h>
+#include <asm/hvm/vioapic.h>
+
+struct hvm_irq {
+ /* Lock protects access to all other fields. */
+ spinlock_t lock;
+
+ /*
+ * Virtual interrupt wires for a single PCI bus.
+ * Indexed by: device*4 + INTx#.
+ */
+ DECLARE_BITMAP(pci_intx, 32*4);
+
+ /*
+ * Virtual interrupt wires for ISA devices.
+ * Indexed by ISA IRQ (assumes no ISA-device IRQ sharing).
+ */
+ DECLARE_BITMAP(isa_irq, 16);
+
+ /* Virtual interrupt wire and GSI link for paravirtual platform driver. */
+ DECLARE_BITMAP(callback_irq_wire, 1);
+ unsigned int callback_gsi;
+
+ /*
+ * PCI-ISA interrupt router.
+ * Each PCI <device:INTx#> is 'wire-ORed' into one of four links using
+ * the traditional 'barber's pole' mapping ((device + INTx#) & 3).
+ * The router provides a programmable mapping from each link to a GSI.
+ */
+ u8 pci_link_route[4];
+
+ /* Number of INTx wires asserting each PCI-ISA link. */
+ u8 pci_link_assert_count[4];
+
+ /*
+ * Number of wires asserting each GSI.
+ *
+ * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space.
+ * PCI links map into this space via the PCI-ISA bridge.
+ *
+ * GSIs 16+ are used only be PCI devices. The mapping from PCI device to
+ * GSI is as follows: ((device*4 + device/8 + INTx#) & 31) + 16
+ */
+ u8 gsi_assert_count[VIOAPIC_NUM_PINS];
+
+ /*
+ * GSIs map onto PIC/IO-APIC in the usual way:
+ * 0-7: Master 8259 PIC, IO-APIC pins 0-7
+ * 8-15: Slave 8259 PIC, IO-APIC pins 8-15
+ * 16+ : IO-APIC pins 16+
+ */
+ struct vpic vpic;
+ struct vioapic vioapic;
+
+ /* Last VCPU that was delivered a LowestPrio interrupt. */
+ u8 round_robin_prev_vcpu;
+};
+
+#define hvm_pci_intx_gsi(dev, intx) \
+ (((((dev)<<2) + ((dev)>>3) + (intx)) & 31) + 16)
+#define hvm_pci_intx_link(dev, intx) \
+ (((dev) + (intx)) & 3)
+
+/* Modify state of a PCI INTx wire. */
+void hvm_pci_intx_assert(
+ struct domain *d, unsigned int device, unsigned int intx);
+void hvm_pci_intx_deassert(
+ struct domain *d, unsigned int device, unsigned int intx);
+
+/* Modify state of an ISA device's IRQ wire. */
+void hvm_isa_irq_assert(
+ struct domain *d, unsigned int isa_irq);
+void hvm_isa_irq_deassert(
+ struct domain *d, unsigned int isa_irq);
+
+void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq);
+
+void hvm_set_callback_irq_level(void);
+void hvm_set_callback_gsi(struct domain *d, unsigned int gsi);
+
+#endif /* __ASM_X86_HVM_IRQ_H__ */
diff --git a/xen/include/asm-x86/hvm/vioapic.h b/xen/include/asm-x86/hvm/vioapic.h
index 32223341ef..6a934b7b39 100644
--- a/xen/include/asm-x86/hvm/vioapic.h
+++ b/xen/include/asm-x86/hvm/vioapic.h
@@ -1,5 +1,4 @@
/*
- *
* Copyright (C) 2001 MandrakeSoft S.A.
*
* MandrakeSoft S.A.
@@ -32,6 +31,9 @@
#ifdef __ia64__
#define VIOAPIC_IS_IOSAPIC 1
+#define VIOAPIC_NUM_PINS 24
+#else
+#define VIOAPIC_NUM_PINS 48 /* 16 ISA IRQs, 32 non-legacy PCI IRQS. */
#endif
#if !VIOAPIC_IS_IOSAPIC
@@ -40,8 +42,6 @@
#define VIOAPIC_VERSION_ID 0x21 /* IOSAPIC version */
#endif
-#define VIOAPIC_NUM_PINS 24
-
#define VIOAPIC_EDGE_TRIG 0
#define VIOAPIC_LEVEL_TRIG 1
@@ -58,9 +58,9 @@
#define VIOAPIC_REG_VERSION 0x01
#define VIOAPIC_REG_ARB_ID 0x02 /* x86 IOAPIC only */
-#define domain_vioapic(d) (&(d)->arch.hvm_domain.vioapic)
+#define domain_vioapic(d) (&(d)->arch.hvm_domain.irq.vioapic)
#define vioapic_domain(v) (container_of((v), struct domain, \
- arch.hvm_domain.vioapic))
+ arch.hvm_domain.irq.vioapic))
union vioapic_redir_entry
{
@@ -86,19 +86,13 @@ union vioapic_redir_entry
};
struct vioapic {
- uint32_t irr;
- uint32_t irr_xen; /* interrupts forced on by the hypervisor. */
- uint32_t isr; /* This is used for level trigger */
- uint32_t imr;
- uint32_t ioregsel;
- uint32_t id;
+ uint32_t ioregsel, id;
unsigned long base_address;
union vioapic_redir_entry redirtbl[VIOAPIC_NUM_PINS];
};
void vioapic_init(struct domain *d);
-void vioapic_set_xen_irq(struct domain *d, int irq, int level);
-void vioapic_set_irq(struct domain *d, int irq, int level);
+void vioapic_irq_positive_edge(struct domain *d, unsigned int irq);
void vioapic_update_EOI(struct domain *d, int vector);
#endif /* __ASM_X86_HVM_VIOAPIC_H__ */
diff --git a/xen/include/asm-x86/hvm/vpic.h b/xen/include/asm-x86/hvm/vpic.h
index 49c2df9011..b5cf8d455d 100644
--- a/xen/include/asm-x86/hvm/vpic.h
+++ b/xen/include/asm-x86/hvm/vpic.h
@@ -26,14 +26,14 @@
#ifndef __ASM_X86_HVM_VPIC_H__
#define __ASM_X86_HVM_VPIC_H__
-#define domain_vpic(d) (&(d)->arch.hvm_domain.vpic)
-#define vpic_domain(v) (container_of((v), struct domain, arch.hvm_domain.vpic))
+#define domain_vpic(d) (&(d)->arch.hvm_domain.irq.vpic)
+#define vpic_domain(v) (container_of((v), struct domain, \
+ arch.hvm_domain.irq.vpic))
+#define vpic_lock(v) (&container_of((v), struct hvm_irq, vpic)->lock)
typedef struct PicState {
uint8_t last_irr; /* edge detection */
uint8_t irr; /* interrupt request register */
- uint8_t irr_xen; /* interrupts forced on by the hypervisor e.g.
- the callback irq. */
uint8_t imr; /* interrupt mask register */
uint8_t isr; /* interrupt service register */
uint8_t priority_add; /* highest irq priority */
@@ -54,17 +54,11 @@ typedef struct PicState {
struct vpic {
/* 0 is master pic, 1 is slave pic */
PicState pics[2];
- void (*irq_request)(void *opaque, int level);
- void *irq_request_opaque;
- /* IOAPIC callback support */
- spinlock_t lock;
+ int irq_pending;
};
-void pic_set_xen_irq(void *opaque, int irq, int level);
void pic_set_irq(struct vpic *vpic, int irq, int level);
-void pic_init(struct vpic *vpic,
- void (*irq_request)(void *, int),
- void *irq_request_opaque);
+void pic_init(struct vpic *vpic);
void pic_update_irq(struct vpic *vpic); /* Caller must hold vpic->lock */
void register_pic_io_hook(struct domain *d);
int cpu_get_pic_interrupt(struct vcpu *v, int *type);