[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH RFC 02/13] ioapic: introduce hooks for some ioapic ops



Create some hooks for IO APIC operations that will diverge from bare
metal when implemented for Xen Dom0.

This patch should not introduce any changes in functionality, it's a
preparatory patch for the implementation of the Xen IO APIC hooks.
---
 sys/amd64/include/apicvar.h |   13 ++++++++
 sys/i386/include/apicvar.h  |   13 ++++++++
 sys/x86/include/apicreg.h   |   12 ++++++++
 sys/x86/x86/io_apic.c       |   65 ++++++++++++++++++++++---------------------
 4 files changed, 71 insertions(+), 32 deletions(-)

diff --git a/sys/amd64/include/apicvar.h b/sys/amd64/include/apicvar.h
index 84e01d4..a48a76b 100644
--- a/sys/amd64/include/apicvar.h
+++ b/sys/amd64/include/apicvar.h
@@ -161,6 +161,19 @@ struct apic_enumerator {
        SLIST_ENTRY(apic_enumerator) apic_next;
 };
 
+struct ioapic_intsrc {
+       struct intsrc io_intsrc;
+       u_int io_irq;
+       u_int io_intpin:8;
+       u_int io_vector:8;
+       u_int io_cpu:8;
+       u_int io_activehi:1;
+       u_int io_edgetrigger:1;
+       u_int io_masked:1;
+       int io_bus:4;
+       uint32_t io_lowreg;
+};
+
 inthand_t
        IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3),
        IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6),
diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h
index 24c99f0..c8ee9bc 100644
--- a/sys/i386/include/apicvar.h
+++ b/sys/i386/include/apicvar.h
@@ -160,6 +160,19 @@ struct apic_enumerator {
        SLIST_ENTRY(apic_enumerator) apic_next;
 };
 
+struct ioapic_intsrc {
+       struct intsrc io_intsrc;
+       u_int io_irq;
+       u_int io_intpin:8;
+       u_int io_vector:8;
+       u_int io_cpu:8;
+       u_int io_activehi:1;
+       u_int io_edgetrigger:1;
+       u_int io_masked:1;
+       int io_bus:4;
+       uint32_t io_lowreg;
+};
+
 inthand_t
        IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3),
        IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6),
diff --git a/sys/x86/include/apicreg.h b/sys/x86/include/apicreg.h
index 283d50e..4629470 100644
--- a/sys/x86/include/apicreg.h
+++ b/sys/x86/include/apicreg.h
@@ -204,6 +204,18 @@ struct IOAPIC {
 
 typedef struct IOAPIC ioapic_t;
 
+struct ioapic_intsrc;
+/*
+ * Struct containing pointers to IO APIC management functions whose
+ * implementation is run time selectable.
+ */
+struct ioapic_ops {
+       u_int    (*read)(volatile ioapic_t *, int);
+       void     (*write)(volatile ioapic_t *, int, u_int);
+       void     (*register_intr)(struct ioapic_intsrc *);
+};
+extern struct ioapic_ops ioapic_ops;
+
 #undef PAD4
 #undef PAD3
 
diff --git a/sys/x86/x86/io_apic.c b/sys/x86/x86/io_apic.c
index 6d62b1e..125d06a 100644
--- a/sys/x86/x86/io_apic.c
+++ b/sys/x86/x86/io_apic.c
@@ -81,19 +81,6 @@ static MALLOC_DEFINE(M_IOAPIC, "io_apic", "I/O APIC 
structures");
  * ftp://download.intel.com/design/chipsets/datashts/29056601.pdf
  */
 
-struct ioapic_intsrc {
-       struct intsrc io_intsrc;
-       u_int io_irq;
-       u_int io_intpin:8;
-       u_int io_vector:8;
-       u_int io_cpu:8;
-       u_int io_activehi:1;
-       u_int io_edgetrigger:1;
-       u_int io_masked:1;
-       int io_bus:4;
-       uint32_t io_lowreg;
-};
-
 struct ioapic {
        struct pic io_pic;
        u_int io_id:8;                  /* logical ID */
@@ -106,8 +93,9 @@ struct ioapic {
        struct ioapic_intsrc io_pins[0];
 };
 
-static u_int   ioapic_read(volatile ioapic_t *apic, int reg);
-static void    ioapic_write(volatile ioapic_t *apic, int reg, u_int val);
+static u_int   native_ioapic_read(volatile ioapic_t *apic, int reg);
+static void    native_ioapic_write(volatile ioapic_t *apic, int reg, u_int 
val);
+static void    native_ioapic_register_intr(struct ioapic_intsrc *pin);
 static const char *ioapic_bus_string(int bus_type);
 static void    ioapic_print_irq(struct ioapic_intsrc *intpin);
 static void    ioapic_enable_source(struct intsrc *isrc);
@@ -139,6 +127,13 @@ SYSCTL_INT(_hw_apic, OID_AUTO, enable_extint, 
CTLFLAG_RDTUN, &enable_extint, 0,
     "Enable the ExtINT pin in the first I/O APIC");
 TUNABLE_INT("hw.apic.enable_extint", &enable_extint);
 
+/* Default ioapic_ops implementation. */
+struct ioapic_ops ioapic_ops = {
+       .read =                 native_ioapic_read,
+       .write =                native_ioapic_write,
+       .register_intr =        native_ioapic_register_intr,
+};
+
 static __inline void
 _ioapic_eoi_source(struct intsrc *isrc)
 {
@@ -146,7 +141,7 @@ _ioapic_eoi_source(struct intsrc *isrc)
 }
 
 static u_int
-ioapic_read(volatile ioapic_t *apic, int reg)
+native_ioapic_read(volatile ioapic_t *apic, int reg)
 {
 
        mtx_assert(&icu_lock, MA_OWNED);
@@ -155,7 +150,7 @@ ioapic_read(volatile ioapic_t *apic, int reg)
 }
 
 static void
-ioapic_write(volatile ioapic_t *apic, int reg, u_int val)
+native_ioapic_write(volatile ioapic_t *apic, int reg, u_int val)
 {
 
        mtx_assert(&icu_lock, MA_OWNED);
@@ -163,6 +158,12 @@ ioapic_write(volatile ioapic_t *apic, int reg, u_int val)
        apic->iowin = val;
 }
 
+static void
+native_ioapic_register_intr(struct ioapic_intsrc *pin)
+{
+       intr_register_source(&pin->io_intsrc);
+}
+
 static const char *
 ioapic_bus_string(int bus_type)
 {
@@ -212,7 +213,7 @@ ioapic_enable_source(struct intsrc *isrc)
        mtx_lock_spin(&icu_lock);
        if (intpin->io_masked) {
                flags = intpin->io_lowreg & ~IOART_INTMASK;
-               ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
+               ioapic_ops.write(io->io_addr, 
IOAPIC_REDTBL_LO(intpin->io_intpin),
                    flags);
                intpin->io_masked = 0;
        }
@@ -229,7 +230,7 @@ ioapic_disable_source(struct intsrc *isrc, int eoi)
        mtx_lock_spin(&icu_lock);
        if (!intpin->io_masked && !intpin->io_edgetrigger) {
                flags = intpin->io_lowreg | IOART_INTMSET;
-               ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
+               ioapic_ops.write(io->io_addr, 
IOAPIC_REDTBL_LO(intpin->io_intpin),
                    flags);
                intpin->io_masked = 1;
        }
@@ -264,10 +265,10 @@ ioapic_program_intpin(struct ioapic_intsrc *intpin)
        mtx_assert(&icu_lock, MA_OWNED);
        if (intpin->io_irq == IRQ_DISABLED || (intpin->io_irq < NUM_IO_INTS &&
            intpin->io_vector == 0)) {
-               low = ioapic_read(io->io_addr,
+               low = ioapic_ops.read(io->io_addr,
                    IOAPIC_REDTBL_LO(intpin->io_intpin));
                if ((low & IOART_INTMASK) == IOART_INTMCLR)
-                       ioapic_write(io->io_addr,
+                       ioapic_ops.write(io->io_addr,
                            IOAPIC_REDTBL_LO(intpin->io_intpin),
                            low | IOART_INTMSET);
                return;
@@ -311,12 +312,12 @@ ioapic_program_intpin(struct ioapic_intsrc *intpin)
        }
 
        /* Write the values to the APIC. */
-       value = ioapic_read(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin));
+       value = ioapic_ops.read(io->io_addr, 
IOAPIC_REDTBL_HI(intpin->io_intpin));
        value &= ~IOART_DEST;
        value |= high;
-       ioapic_write(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin), value);
+       ioapic_ops.write(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin), 
value);
        intpin->io_lowreg = low;
-       ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low);
+       ioapic_ops.write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low);
 }
 
 static int
@@ -357,7 +358,7 @@ ioapic_assign_cpu(struct intsrc *isrc, u_int apic_id)
         */
        mtx_lock_spin(&icu_lock);
        if (!intpin->io_masked && !intpin->io_edgetrigger) {
-               ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
+               ioapic_ops.write(io->io_addr, 
IOAPIC_REDTBL_LO(intpin->io_intpin),
                    intpin->io_lowreg | IOART_INTMSET);
                mtx_unlock_spin(&icu_lock);
                DELAY(100);
@@ -512,7 +513,7 @@ ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase)
        /* Map the register window so we can access the device. */
        apic = pmap_mapdev(addr, IOAPIC_MEM_REGION);
        mtx_lock_spin(&icu_lock);
-       value = ioapic_read(apic, IOAPIC_VER);
+       value = ioapic_ops.read(apic, IOAPIC_VER);
        mtx_unlock_spin(&icu_lock);
 
        /* If it's version register doesn't seem to work, punt. */
@@ -528,9 +529,9 @@ ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase)
        io->io_pic = ioapic_template;
        mtx_lock_spin(&icu_lock);
        io->io_id = next_id++;
-       io->io_apic_id = ioapic_read(apic, IOAPIC_ID) >> APIC_ID_SHIFT;
+       io->io_apic_id = ioapic_ops.read(apic, IOAPIC_ID) >> APIC_ID_SHIFT;
        if (apic_id != -1 && io->io_apic_id != apic_id) {
-               ioapic_write(apic, IOAPIC_ID, apic_id << APIC_ID_SHIFT);
+               ioapic_ops.write(apic, IOAPIC_ID, apic_id << APIC_ID_SHIFT);
                mtx_unlock_spin(&icu_lock);
                io->io_apic_id = apic_id;
                printf("ioapic%u: Changing APIC ID to %d\n", io->io_id,
@@ -586,8 +587,8 @@ ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase)
                 * be routed to other CPUs later after they are enabled.
                 */
                intpin->io_cpu = PCPU_GET(apic_id);
-               value = ioapic_read(apic, IOAPIC_REDTBL_LO(i));
-               ioapic_write(apic, IOAPIC_REDTBL_LO(i), value | IOART_INTMSET);
+               value = ioapic_ops.read(apic, IOAPIC_REDTBL_LO(i));
+               ioapic_ops.write(apic, IOAPIC_REDTBL_LO(i), value | 
IOART_INTMSET);
        }
        mtx_unlock_spin(&icu_lock);
 
@@ -788,7 +789,7 @@ ioapic_register(void *cookie)
        io = (struct ioapic *)cookie;
        apic = io->io_addr;
        mtx_lock_spin(&icu_lock);
-       flags = ioapic_read(apic, IOAPIC_VER) & IOART_VER_VERSION;
+       flags = ioapic_ops.read(apic, IOAPIC_VER) & IOART_VER_VERSION;
        STAILQ_INSERT_TAIL(&ioapic_list, io, io_next);
        mtx_unlock_spin(&icu_lock);
        printf("ioapic%u <Version %u.%u> irqs %u-%u on motherboard\n",
@@ -799,7 +800,7 @@ ioapic_register(void *cookie)
        intr_register_pic(&io->io_pic);
        for (i = 0, pin = io->io_pins; i < io->io_numintr; i++, pin++)
                if (pin->io_irq < NUM_IO_INTS)
-                       intr_register_source(&pin->io_intsrc);
+                       ioapic_ops.register_intr(pin);
 }
 
 /* A simple new-bus driver to consume PCI I/O APIC devices. */
-- 
1.7.7.5 (Apple Git-26)


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.