WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Big fixes for the new IO-APIC acknowledging method. The

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Big fixes for the new IO-APIC acknowledging method. The problems
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 15 Apr 2006 19:58:08 +0000
Delivery-date: Sat, 15 Apr 2006 12:59:00 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID b39365343de08af6c76fa3492b2cffb436470b3f
# Parent  4613f42db7806c866e5057f17ad7fa340ccbc7ab
Big fixes for the new IO-APIC acknowledging method. The problems
were:
 1. Some critical Xen interrupts could get blocked behind
    unacknowledged guest interrupts. This is avoided by making
    all Xen-bound interrrupts strictly higher priority.
 2. Interrupts must not only be EOIed on the CPU that received
    them, but also in reverse order when interrupts are nested.
    A whole load of logic has been added to ensure this.

There are two boot parameters relating to all this:
 'ioapic_ack=old' -- use the old IO-APIC ACK method
 'ioapic_ack=new' -- use the new IO-APIC ACK method (default)
 'force_intack'   -- periodically force acknowledgement of
                     interrupts (default is no; useful for debugging)

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 4613f42db780 -r b39365343de0 xen/arch/x86/i8259.c
--- a/xen/arch/x86/i8259.c      Sat Apr 15 14:53:53 2006
+++ b/xen/arch/x86/i8259.c      Sat Apr 15 17:09:52 2006
@@ -318,7 +318,7 @@
      * outb_p - this has to work on a wide range of PC hardware.
      */
     outb_p(0x11, 0x20);     /* ICW1: select 8259A-1 init */
-    outb_p(0x20 + 0, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
+    outb_p(FIRST_LEGACY_VECTOR + 0, 0x21); /* ICW2: 8259A-1 IR0-7 */
     outb_p(0x04, 0x21);     /* 8259A-1 (the master) has a slave on IR2 */
     if (auto_eoi)
         outb_p(0x03, 0x21); /* master does Auto EOI */
@@ -326,7 +326,7 @@
         outb_p(0x01, 0x21); /* master expects normal EOI */
 
     outb_p(0x11, 0xA0);     /* ICW1: select 8259A-2 init */
-    outb_p(0x20 + 8, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
+    outb_p(FIRST_LEGACY_VECTOR + 8, 0xA1); /* ICW2: 8259A-2 IR0-7 */
     outb_p(0x02, 0xA1);     /* 8259A-2 is a slave on master's IR2 */
     outb_p(0x01, 0xA1);     /* (slave's support for AEOI in flat mode
                                is to be investigated) */
diff -r 4613f42db780 -r b39365343de0 xen/arch/x86/io_apic.c
--- a/xen/arch/x86/io_apic.c    Sat Apr 15 14:53:53 2006
+++ b/xen/arch/x86/io_apic.c    Sat Apr 15 17:09:52 2006
@@ -669,11 +669,11 @@
 }
 
 /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
-u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
+u8 irq_vector[NR_IRQ_VECTORS] __read_mostly;
 
 int assign_irq_vector(int irq)
 {
-    static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
+    static int current_vector = FIRST_DYNAMIC_VECTOR, offset = 0;
 
     BUG_ON(irq >= NR_IRQ_VECTORS);
     if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
@@ -689,11 +689,11 @@
     if (current_vector == 0x80)
         goto next;
 
-    if (current_vector >= FIRST_SYSTEM_VECTOR) {
+    if (current_vector > LAST_DYNAMIC_VECTOR) {
         offset++;
         if (!(offset%8))
             return -ENOSPC;
-        current_vector = FIRST_DEVICE_VECTOR + offset;
+        current_vector = FIRST_DYNAMIC_VECTOR + offset;
     }
 
     vector_irq[current_vector] = irq;
@@ -1333,15 +1333,24 @@
     return 0; /* don't check for pending */
 }
 
-static int new_ack;
-boolean_param("new_ack", new_ack);
+int ioapic_ack_new = 1;
+static void setup_ioapic_ack(char *s)
+{
+    if ( !strcmp(s, "old") )
+        ioapic_ack_new = 0;
+    else if ( !strcmp(s, "new") )
+        ioapic_ack_new = 1;
+    else
+        printk("Unknown ioapic_ack value specified: '%s'\n", s);
+}
+custom_param("ioapic_ack", setup_ioapic_ack);
 
 static void mask_and_ack_level_ioapic_irq (unsigned int irq)
 {
     unsigned long v;
     int i;
 
-    if ( new_ack )
+    if ( ioapic_ack_new )
         return;
 
     mask_IO_APIC_irq(irq);
@@ -1384,7 +1393,7 @@
     unsigned long v;
     int i;
 
-    if ( !new_ack )
+    if ( !ioapic_ack_new )
     {
         unmask_IO_APIC_irq(irq);
         return;
@@ -1753,7 +1762,7 @@
         io_apic_irqs = ~PIC_IRQS;
 
     printk("ENABLING IO-APIC IRQs\n");
-    printk(" -> Using %s ACK method\n", new_ack ? "new" : "old");
+    printk(" -> Using %s ACK method\n", ioapic_ack_new ? "new" : "old");
 
     /*
      * Set up IO-APIC IRQ routing.
@@ -2015,9 +2024,9 @@
         return 0;
     }
 
-    if ( old_rte.vector >= FIRST_DEVICE_VECTOR )
+    if ( old_rte.vector >= FIRST_DYNAMIC_VECTOR )
         old_irq = vector_irq[old_rte.vector];
-    if ( new_rte.vector >= FIRST_DEVICE_VECTOR )
+    if ( new_rte.vector >= FIRST_DYNAMIC_VECTOR )
         new_irq = vector_irq[new_rte.vector];
 
     if ( (old_irq != new_irq) && (old_irq != -1) && IO_APIC_IRQ(old_irq) )
diff -r 4613f42db780 -r b39365343de0 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Sat Apr 15 14:53:53 2006
+++ b/xen/arch/x86/irq.c        Sat Apr 15 17:09:52 2006
@@ -149,12 +149,22 @@
     u8 in_flight;
     u8 shareable;
     u8 ack_type;
-#define ACKTYPE_NONE   0 /* Final ACK is not required */
-#define ACKTYPE_SINGLE 1 /* Final ACK on any CPU */
-#define ACKTYPE_MULTI  2 /* Final ACK on the CPU that was interrupted */
-    cpumask_t cpu_ack_map;
+#define ACKTYPE_NONE   0     /* No final acknowledgement is required */
+#define ACKTYPE_UNMASK 1     /* Unmask PIC hardware (from any CPU)   */
+#define ACKTYPE_LAPIC_EOI  2 /* EOI on the CPU that was interrupted  */
+    cpumask_t cpu_eoi_map;   /* CPUs that need to EOI this interrupt */
     struct domain *guest[IRQ_MAX_GUESTS];
 } irq_guest_action_t;
+
+/*
+ * Stack of interrupts awaiting EOI on each CPU. These must be popped in
+ * order, as only the current highest-priority pending irq can be EOIed.
+ */
+static struct {
+    u8 vector;
+    u8 ready_to_end;
+} pending_lapic_eoi[NR_CPUS][NR_VECTORS] __cacheline_aligned;
+#define pending_lapic_eoi_sp(cpu) (pending_lapic_eoi[cpu][NR_VECTORS-1].vector)
 
 static void __do_IRQ_guest(int vector)
 {
@@ -162,18 +172,26 @@
     irq_desc_t         *desc = &irq_desc[vector];
     irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
     struct domain      *d;
-    int                 i;
+    int                 i, sp, cpu = smp_processor_id();
 
     if ( unlikely(action->nr_guests == 0) )
     {
-        /* An interrupt may slip through while freeing an ACKTYPE_MULTI irq. */
-        ASSERT(action->ack_type == ACKTYPE_MULTI);
+        /* An interrupt may slip through while freeing a LAPIC_EOI irq. */
+        ASSERT(action->ack_type == ACKTYPE_LAPIC_EOI);
         desc->handler->end(vector);
         return;
     }
 
-    if ( action->ack_type == ACKTYPE_MULTI )
-        cpu_set(smp_processor_id(), action->cpu_ack_map);
+    if ( action->ack_type == ACKTYPE_LAPIC_EOI )
+    {
+        sp = pending_lapic_eoi_sp(cpu);
+        ASSERT((sp == 0) || (pending_lapic_eoi[cpu][sp-1].vector < vector));
+        ASSERT(sp < (NR_VECTORS-1));
+        pending_lapic_eoi[cpu][sp].vector = vector;
+        pending_lapic_eoi[cpu][sp].ready_to_end = 0;
+        pending_lapic_eoi_sp(cpu) = sp+1;
+        cpu_set(cpu, action->cpu_eoi_map);
+    }
 
     for ( i = 0; i < action->nr_guests; i++ )
     {
@@ -190,20 +208,49 @@
     irq_desc_t         *desc = data;
     irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
     unsigned long       flags;
+    int                 vector, sp, cpu = smp_processor_id();
+
+    vector = desc - irq_desc;
 
     spin_lock_irqsave(&desc->lock, flags);
+
     if ( (desc->status & IRQ_GUEST) &&
          (action->in_flight == 0) &&
-         test_and_clear_bit(smp_processor_id(), &action->cpu_ack_map) )
-        desc->handler->end(desc - irq_desc);
-    spin_unlock_irqrestore(&desc->lock, flags);    
+         test_and_clear_bit(cpu, &action->cpu_eoi_map) )
+    {
+        sp = pending_lapic_eoi_sp(cpu);
+        do {
+            ASSERT(sp > 0);
+        } while ( pending_lapic_eoi[cpu][--sp].vector != vector );
+        ASSERT(!pending_lapic_eoi[cpu][sp].ready_to_end);
+        pending_lapic_eoi[cpu][sp].ready_to_end = 1;
+    }
+
+    for ( ; ; )
+    {
+        sp = pending_lapic_eoi_sp(cpu);
+        if ( (sp == 0) || !pending_lapic_eoi[cpu][sp-1].ready_to_end )
+        {
+            spin_unlock_irqrestore(&desc->lock, flags);    
+            return;
+        }
+        if ( pending_lapic_eoi[cpu][sp-1].vector != vector )
+        {
+            spin_unlock(&desc->lock);
+            vector = pending_lapic_eoi[cpu][sp-1].vector;
+            desc = &irq_desc[vector];
+            spin_lock(&desc->lock);
+        }
+        desc->handler->end(vector);
+        pending_lapic_eoi_sp(cpu) = sp-1;
+    }
 }
 
 int pirq_guest_unmask(struct domain *d)
 {
     irq_desc_t         *desc;
     irq_guest_action_t *action;
-    cpumask_t           cpu_ack_map = CPU_MASK_NONE;
+    cpumask_t           cpu_eoi_map = CPU_MASK_NONE;
     unsigned int        pirq, cpu = smp_processor_id();
     shared_info_t      *s = d->shared_info;
 
@@ -221,24 +268,27 @@
             ASSERT(action->ack_type != ACKTYPE_NONE);
             if ( --action->in_flight == 0 )
             {
-                if ( (action->ack_type == ACKTYPE_SINGLE) ||
-                     test_and_clear_bit(cpu, &action->cpu_ack_map) )
+                if ( action->ack_type == ACKTYPE_UNMASK )
                     desc->handler->end(irq_to_vector(pirq));
-                cpu_ack_map = action->cpu_ack_map;
+                cpu_eoi_map = action->cpu_eoi_map;
             }
         }
         spin_unlock_irq(&desc->lock);
 
-        if ( !cpus_empty(cpu_ack_map) )
-        {
-            on_selected_cpus(cpu_ack_map, end_guest_irq, desc, 1, 0);
-            cpu_ack_map = CPU_MASK_NONE;
+        if ( __test_and_clear_bit(cpu, &cpu_eoi_map) )
+            end_guest_irq(desc);
+
+        if ( !cpus_empty(cpu_eoi_map) )
+        {
+            on_selected_cpus(cpu_eoi_map, end_guest_irq, desc, 1, 0);
+            cpu_eoi_map = CPU_MASK_NONE;
         }
     }
 
     return 0;
 }
 
+extern int ioapic_ack_new;
 int pirq_acktype(int irq)
 {
     irq_desc_t  *desc;
@@ -259,14 +309,17 @@
 
     /* Legacy PIC interrupts can be acknowledged from any CPU. */
     if ( !strcmp(desc->handler->typename, "XT-PIC") )
-        return ACKTYPE_SINGLE;
+        return ACKTYPE_UNMASK;
 
     /*
-     * By default assume that an interrupt must be finally acknowledged on
-     * the CPU on which it was received. This is true for level-triggered
-     * IO-APIC interrupts, for example, where we tickle the LAPIC to EOI.
+     * Level-triggered IO-APIC interrupts need to be acknowledged on the CPU
+     * on which they were received. This is because we tickle the LAPIC to EOI.
      */
-    return ACKTYPE_MULTI;
+    if ( !strcmp(desc->handler->typename, "IO-APIC-level") )
+        return ioapic_ack_new ? ACKTYPE_LAPIC_EOI : ACKTYPE_UNMASK;
+
+    BUG();
+    return 0;
 }
 
 int pirq_guest_bind(struct vcpu *v, int irq, int will_share)
@@ -313,7 +366,7 @@
         action->in_flight   = 0;
         action->shareable   = will_share;
         action->ack_type    = pirq_acktype(irq);
-        action->cpu_ack_map = CPU_MASK_NONE;
+        action->cpu_eoi_map = CPU_MASK_NONE;
 
         desc->depth = 0;
         desc->status |= IRQ_GUEST;
@@ -352,7 +405,7 @@
     unsigned int        vector = irq_to_vector(irq);
     irq_desc_t         *desc = &irq_desc[vector];
     irq_guest_action_t *action;
-    cpumask_t           cpu_ack_map;
+    cpumask_t           cpu_eoi_map;
     unsigned long       flags;
     int                 i;
 
@@ -370,30 +423,30 @@
 
     switch ( action->ack_type )
     {
-    case ACKTYPE_SINGLE:
+    case ACKTYPE_UNMASK:
         if ( test_and_clear_bit(irq, &d->pirq_mask) &&
              (--action->in_flight == 0) )
             desc->handler->end(vector);
         break;
-    case ACKTYPE_MULTI:
+    case ACKTYPE_LAPIC_EOI:
         if ( test_and_clear_bit(irq, &d->pirq_mask) )
             --action->in_flight;
         while ( action->in_flight == 0 )
         {
             /* We cannot release guest info until all pending ACKs are done. */
-            cpu_ack_map = action->cpu_ack_map;
-            if ( cpus_empty(cpu_ack_map) )
+            cpu_eoi_map = action->cpu_eoi_map;
+            if ( cpus_empty(cpu_eoi_map) )
                 break;
 
             /* We cannot hold the lock while interrupting other CPUs. */
             spin_unlock_irqrestore(&desc->lock, flags);    
-            on_selected_cpus(cpu_ack_map, end_guest_irq, desc, 1, 1);
+            on_selected_cpus(cpu_eoi_map, end_guest_irq, desc, 1, 1);
             spin_lock_irqsave(&desc->lock, flags);
 
             /* The world can change while we do not hold the lock. */
             if ( !(desc->status & IRQ_GUEST) )
                 goto out;
-            if ( (action->ack_type != ACKTYPE_MULTI) ||
+            if ( (action->ack_type != ACKTYPE_LAPIC_EOI) ||
                  (action->nr_guests != 0) )
                 break;
         }
@@ -406,7 +459,7 @@
         goto out;
 
     BUG_ON(action->in_flight != 0);
-    BUG_ON(!cpus_empty(action->cpu_ack_map));
+    BUG_ON(!cpus_empty(action->cpu_eoi_map));
 
     desc->action = NULL;
     xfree(action);
@@ -487,3 +540,61 @@
     return 0;
 }
 __initcall(setup_dump_irqs);
+
+static struct timer end_irq_timer[NR_CPUS];
+
+static void end_irq_timeout(void *unused)
+{
+    irq_desc_t         *desc;
+    irq_guest_action_t *action;
+    cpumask_t           cpu_eoi_map;
+    unsigned int        cpu = smp_processor_id();
+    int                 sp, vector, i;
+
+    local_irq_disable();
+
+    if ( (sp = pending_lapic_eoi_sp(cpu)) == 0 )
+    {
+        local_irq_enable();
+        return;
+    }
+
+    vector = pending_lapic_eoi[cpu][sp-1].vector;
+    ASSERT(!pending_lapic_eoi[cpu][sp-1].ready_to_end);
+
+    desc = &irq_desc[vector];
+    spin_lock(&desc->lock);
+    action = (irq_guest_action_t *)desc->action;
+    ASSERT(action->ack_type == ACKTYPE_LAPIC_EOI);
+    ASSERT(desc->status & IRQ_GUEST);
+    for ( i = 0; i < action->nr_guests; i++ )
+        clear_bit(vector_to_irq(vector), &action->guest[i]->pirq_mask);
+    action->in_flight = 0;
+    cpu_eoi_map = action->cpu_eoi_map;
+    spin_unlock(&desc->lock);
+
+    local_irq_enable();
+
+    if ( !cpus_empty(cpu_eoi_map) )
+        on_selected_cpus(cpu_eoi_map, end_guest_irq, desc, 1, 0);
+
+    set_timer(&end_irq_timer[cpu], NOW() + MILLISECS(1000));
+}
+
+static void __init __setup_irq_timeout(void *unused)
+{
+    int cpu = smp_processor_id();
+    init_timer(&end_irq_timer[cpu], end_irq_timeout, NULL, cpu);
+    set_timer(&end_irq_timer[cpu], NOW() + MILLISECS(1000));
+}
+
+static int force_intack;
+boolean_param("force_intack", force_intack);
+
+static int __init setup_irq_timeout(void)
+{
+    if ( force_intack )
+        on_each_cpu(__setup_irq_timeout, NULL, 1, 1);
+    return 0;
+}
+__initcall(setup_irq_timeout);
diff -r 4613f42db780 -r b39365343de0 xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c    Sat Apr 15 14:53:53 2006
+++ b/xen/arch/x86/smpboot.c    Sat Apr 15 17:09:52 2006
@@ -41,6 +41,7 @@
 #include <xen/irq.h>
 #include <xen/delay.h>
 #include <xen/softirq.h>
+#include <xen/serial.h>
 #include <asm/current.h>
 #include <asm/mc146818rtc.h>
 #include <asm/desc.h>
@@ -1231,12 +1232,25 @@
 
 void __init smp_intr_init(void)
 {
+       int irq, seridx;
+
        /*
         * IRQ0 must be given a fixed assignment and initialized,
         * because it's used before the IO-APIC is set up.
         */
-       irq_vector[0] = FIRST_DEVICE_VECTOR;
-       vector_irq[FIRST_DEVICE_VECTOR] = 0;
+       irq_vector[0] = FIRST_HIPRIORITY_VECTOR;
+       vector_irq[FIRST_HIPRIORITY_VECTOR] = 0;
+
+       /*
+        * Also ensure serial interrupts are high priority. We do not
+        * want them to be blocked by unacknowledged guest-bound interrupts.
+        */
+       for (seridx = 0; seridx < 2; seridx++) {
+               if ((irq = serial_irq(seridx)) < 0)
+                       continue;
+               irq_vector[irq] = FIRST_HIPRIORITY_VECTOR + seridx + 1;
+               vector_irq[FIRST_HIPRIORITY_VECTOR + seridx + 1] = irq;
+       }
 
        /* IPI for event checking. */
        set_intr_gate(EVENT_CHECK_VECTOR, event_check_interrupt);
diff -r 4613f42db780 -r b39365343de0 xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c        Sat Apr 15 14:53:53 2006
+++ b/xen/drivers/char/ns16550.c        Sat Apr 15 17:09:52 2006
@@ -260,13 +260,20 @@
 #define ns16550_endboot NULL
 #endif
 
+static int ns16550_irq(struct serial_port *port)
+{
+    struct ns16550 *uart = port->uart;
+    return ((uart->irq > 0) ? uart->irq : -1);
+}
+
 static struct uart_driver ns16550_driver = {
     .init_preirq  = ns16550_init_preirq,
     .init_postirq = ns16550_init_postirq,
     .endboot      = ns16550_endboot,
     .tx_empty     = ns16550_tx_empty,
     .putc         = ns16550_putc,
-    .getc         = ns16550_getc
+    .getc         = ns16550_getc,
+    .irq          = ns16550_irq
 };
 
 static int parse_parity_char(int c)
diff -r 4613f42db780 -r b39365343de0 xen/drivers/char/serial.c
--- a/xen/drivers/char/serial.c Sat Apr 15 14:53:53 2006
+++ b/xen/drivers/char/serial.c Sat Apr 15 17:09:52 2006
@@ -372,6 +372,15 @@
             com[i].driver->endboot(&com[i]);
 }
 
+int serial_irq(int idx)
+{
+    if ( (idx >= 0) && (idx < ARRAY_SIZE(com)) &&
+         com[idx].driver && com[idx].driver->irq )
+        return com[idx].driver->irq(&com[idx]);
+
+    return -1;
+}
+
 void serial_register_uart(int idx, struct uart_driver *driver, void *uart)
 {
     /* Store UART-specific info. */
diff -r 4613f42db780 -r b39365343de0 xen/include/asm-x86/irq.h
--- a/xen/include/asm-x86/irq.h Sat Apr 15 14:53:53 2006
+++ b/xen/include/asm-x86/irq.h Sat Apr 15 17:09:52 2006
@@ -11,8 +11,8 @@
 #define IO_APIC_IRQ(irq)    (((irq) >= 16) || ((1<<(irq)) & io_apic_irqs))
 #define IO_APIC_VECTOR(irq) (irq_vector[irq])
 
-#define LEGACY_VECTOR(irq)          ((irq) + FIRST_EXTERNAL_VECTOR)
-#define LEGACY_IRQ_FROM_VECTOR(vec) ((vec) - FIRST_EXTERNAL_VECTOR)
+#define LEGACY_VECTOR(irq)          ((irq) + FIRST_LEGACY_VECTOR)
+#define LEGACY_IRQ_FROM_VECTOR(vec) ((vec) - FIRST_LEGACY_VECTOR)
 
 #define irq_to_vector(irq)  \
     (IO_APIC_IRQ(irq) ? IO_APIC_VECTOR(irq) : LEGACY_VECTOR(irq))
diff -r 4613f42db780 -r b39365343de0 
xen/include/asm-x86/mach-default/irq_vectors.h
--- a/xen/include/asm-x86/mach-default/irq_vectors.h    Sat Apr 15 14:53:53 2006
+++ b/xen/include/asm-x86/mach-default/irq_vectors.h    Sat Apr 15 17:09:52 2006
@@ -1,96 +1,36 @@
-/*
- * This file should contain #defines for all of the interrupt vector
- * numbers used by this architecture.
- *
- * In addition, there are some standard defines:
- *
- *     FIRST_EXTERNAL_VECTOR:
- *             The first free place for external interrupts
- *
- *     SYSCALL_VECTOR:
- *             The IRQ vector a syscall makes the user to kernel transition
- *             under.
- *
- *     TIMER_IRQ:
- *             The IRQ number the timer interrupt comes in at.
- *
- *     NR_IRQS:
- *             The total number of interrupt vectors (including all the
- *             architecture specific interrupts) needed.
- *
- */                    
 #ifndef _ASM_IRQ_VECTORS_H
 #define _ASM_IRQ_VECTORS_H
 
-/*
- * IDT vectors usable for external interrupt sources start
- * at 0x20:
- */
-#define FIRST_EXTERNAL_VECTOR  0x20
-
-#define HYPERCALL_VECTOR       0x82
-
-/*
- * Vectors 0x20-0x2f are used for ISA interrupts.
- */
-
-/*
- * Special IRQ vectors used by the SMP architecture, 0xf0-0xff
- *
- *  some of the following vectors are 'rare', they are merged
- *  into a single vector (CALL_FUNCTION_VECTOR) to save vector space.
- *  TLB, reschedule and local APIC vectors are performance-critical.
- *
- *  Vectors 0xf0-0xfa are free (reserved for future Linux use).
- */
+/* Processor-initiated interrupts are all high priority. */
 #define SPURIOUS_APIC_VECTOR   0xff
 #define ERROR_APIC_VECTOR      0xfe
 #define INVALIDATE_TLB_VECTOR  0xfd
 #define EVENT_CHECK_VECTOR     0xfc
 #define CALL_FUNCTION_VECTOR   0xfb
-
-#define THERMAL_APIC_VECTOR    0xf0
-/*
- * Local APIC timer IRQ vector is on a different priority level,
- * to work around the 'lost local interrupt if more than 2 IRQ
- * sources per level' errata.
- */
-#define LOCAL_TIMER_VECTOR     0xef
+#define THERMAL_APIC_VECTOR    0xfa
+#define LOCAL_TIMER_VECTOR     0xf9
 
 /*
- * First APIC vector available to drivers: (vectors 0x30-0xee)
- * we start at 0x31 to spread out vectors evenly between priority
- * levels. (0x80 is the syscall vector)
+ * High-priority dynamically-allocated vectors. For interrupts that
+ * must be higher priority than any guest-bound interrupt.
  */
-#define FIRST_DEVICE_VECTOR    0x31
-#define FIRST_SYSTEM_VECTOR    0xef
+#define FIRST_HIPRIORITY_VECTOR        0xf0
+#define LAST_HIPRIORITY_VECTOR  0xf8
 
-#define TIMER_IRQ 0
+/* Legacy PIC uses vectors 0xe0-0xef. */
+#define FIRST_LEGACY_VECTOR    0xe0
+#define LAST_LEGACY_VECTOR      0xef
 
-/*
- * 16 8259A IRQ's, 208 potential APIC interrupt sources.
- * Right now the APIC is mostly only used for SMP.
- * 256 vectors is an architectural limit. (we can have
- * more than 256 devices theoretically, but they will
- * have to use shared interrupts)
- * Since vectors 0x00-0x1f are used/reserved for the CPU,
- * the usable vector space is 0x20-0xff (224 vectors)
- */
+#define HYPERCALL_VECTOR       0x82
 
-/*
- * The maximum number of vectors supported by i386 processors
- * is limited to 256. For processors other than i386, NR_VECTORS
- * should be changed accordingly.
- */
+/* Dynamically-allocated vectors available to any driver. */
+#define FIRST_DYNAMIC_VECTOR   0x20
+#define LAST_DYNAMIC_VECTOR    0xdf
+
 #define NR_VECTORS 256
 
-#include "irq_vectors_limits.h"
-
-#define FPU_IRQ                        13
-
-#define        FIRST_VM86_IRQ          3
-#define LAST_VM86_IRQ          15
-#define invalid_vm86_irq(irq)  ((irq) < 3 || (irq) > 15)
-
+/* Limited by number of trap vectors. */
+#define NR_IRQS        NR_VECTORS
+#define NR_IRQ_VECTORS NR_IRQS
 
 #endif /* _ASM_IRQ_VECTORS_H */
diff -r 4613f42db780 -r b39365343de0 xen/include/xen/serial.h
--- a/xen/include/xen/serial.h  Sat Apr 15 14:53:53 2006
+++ b/xen/include/xen/serial.h  Sat Apr 15 17:09:52 2006
@@ -57,6 +57,8 @@
     void (*putc)(struct serial_port *, char);
     /* Get a character from the serial line: returns 0 if none available. */
     int  (*getc)(struct serial_port *, char *);
+    /* Get IRQ number for this port's serial line: returns -1 if none. */
+    int  (*irq)(struct serial_port *);
 };
 
 /* 'Serial handles' are composed from the following fields. */
@@ -99,6 +101,9 @@
 /* Return number of bytes headroom in transmit buffer. */
 int serial_tx_space(int handle);
 
+/* Return irq number for specified serial port (identified by index). */
+int serial_irq(int idx);
+
 /*
  * Initialisation and helper functions for uart drivers.
  */
diff -r 4613f42db780 -r b39365343de0 
xen/include/asm-x86/mach-default/irq_vectors_limits.h
--- a/xen/include/asm-x86/mach-default/irq_vectors_limits.h     Sat Apr 15 
14:53:53 2006
+++ /dev/null   Sat Apr 15 17:09:52 2006
@@ -1,8 +0,0 @@
-#ifndef _ASM_IRQ_VECTORS_LIMITS_H
-#define _ASM_IRQ_VECTORS_LIMITS_H
-
-/* Limited by number of trap vectors. */
-#define NR_IRQS        FIRST_SYSTEM_VECTOR
-#define NR_IRQ_VECTORS NR_IRQS
-
-#endif /* _ASM_IRQ_VECTORS_LIMITS_H */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Big fixes for the new IO-APIC acknowledging method. The problems, Xen patchbot -unstable <=