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] Merge xen-unstable into xen-ia64-unstable again (to get

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Merge xen-unstable into xen-ia64-unstable again (to get ioapic changes)
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 08 Nov 2005 11:56:16 +0000
Delivery-date: Tue, 08 Nov 2005 11:58:07 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
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 djm@xxxxxxxxxxxxxxx
# Node ID 66dd96e90be4c2a66a98ed67ddd4ee8cec6bd599
# Parent  d51b071bfcfcd9f77127b17b6516a118c33d4915
# Parent  25599e222c333565208c77c0d875bd56d6c719ef
Merge xen-unstable into xen-ia64-unstable again (to get ioapic changes)

diff -r d51b071bfcfc -r 66dd96e90be4 
linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c   Mon Nov  7 22:53:25 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c   Tue Nov  8 02:40:31 2005
@@ -18,7 +18,6 @@
 #include <asm/system.h>
 #include <asm/ldt.h>
 #include <asm/desc.h>
-#include <asm/mmu_context.h>
 
 #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
 static void flush_ldt(void *null)
@@ -101,18 +100,13 @@
        struct mm_struct * old_mm;
        int retval = 0;
 
-       memset(&mm->context, 0, sizeof(mm->context));
        init_MUTEX(&mm->context.sem);
+       mm->context.size = 0;
        old_mm = current->mm;
        if (old_mm && old_mm->context.size > 0) {
                down(&old_mm->context.sem);
                retval = copy_ldt(&mm->context, &old_mm->context);
                up(&old_mm->context.sem);
-       }
-       if (retval == 0) {
-               spin_lock(&mm_unpinned_lock);
-               list_add(&mm->context.unpinned, &mm_unpinned);
-               spin_unlock(&mm_unpinned_lock);
        }
        return retval;
 }
@@ -133,11 +127,6 @@
                else
                        kfree(mm->context.ldt);
                mm->context.size = 0;
-       }
-       if (!mm->context.pinned) {
-               spin_lock(&mm_unpinned_lock);
-               list_del(&mm->context.unpinned);
-               spin_unlock(&mm_unpinned_lock);
        }
 }
 
diff -r d51b071bfcfc -r 66dd96e90be4 
linux-2.6-xen-sparse/arch/xen/i386/mm/init.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c      Mon Nov  7 22:53:25 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c      Tue Nov  8 02:40:31 2005
@@ -376,7 +376,6 @@
                __PAGE_KERNEL_EXEC |= _PAGE_GLOBAL;
        }
 
-       init_mm.context.pinned = 1;
        kernel_physical_mapping_init(pgd_base);
        remap_numa_kva();
 
@@ -689,6 +688,8 @@
 #ifndef CONFIG_SMP
        zap_low_mappings();
 #endif
+
+       set_bit(PG_pinned, &virt_to_page(init_mm.pgd)->flags);
 }
 
 kmem_cache_t *pgd_cache;
diff -r d51b071bfcfc -r 66dd96e90be4 
linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c   Mon Nov  7 22:53:25 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c   Tue Nov  8 02:40:31 2005
@@ -26,6 +26,9 @@
 
 #include <asm-xen/foreign_page.h>
 #include <asm/hypervisor.h>
+
+static void __pgd_pin(pgd_t *pgd);
+static void __pgd_unpin(pgd_t *pgd);
 
 void show_mem(void)
 {
@@ -299,6 +302,8 @@
 {
        unsigned long flags; /* can be called from interrupt context */
 
+       BUG_ON(test_bit(PG_pinned, &virt_to_page(pgd)->flags));
+
        if (HAVE_SHARED_KERNEL_PMD)
                return;
 
@@ -311,6 +316,8 @@
 {
        int i = 0;
        pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
+
+       BUG_ON(test_bit(PG_pinned, &virt_to_page(pgd)->flags));
 
        if (PTRS_PER_PMD == 1 || !pgd)
                return pgd;
@@ -351,15 +358,9 @@
 void pgd_free(pgd_t *pgd)
 {
        int i;
-       pte_t *ptep = virt_to_ptep(pgd);
-
-       if (!pte_write(*ptep)) {
-               xen_pgd_unpin(__pa(pgd));
-               BUG_ON(HYPERVISOR_update_va_mapping(
-                       (unsigned long)pgd,
-                       pfn_pte(virt_to_phys(pgd)>>PAGE_SHIFT, PAGE_KERNEL),
-                       0));
-       }
+
+       if (test_bit(PG_pinned, &virt_to_page(pgd)->flags))
+               __pgd_unpin(pgd);
 
        /* in the PAE case user pgd entries are overwritten before usage */
        if (PTRS_PER_PMD > 1) {
@@ -441,10 +442,7 @@
 }
 #endif /* CONFIG_XEN_SHADOW_MODE */
 
-LIST_HEAD(mm_unpinned);
-DEFINE_SPINLOCK(mm_unpinned_lock);
-
-static inline void mm_walk_set_prot(void *pt, pgprot_t flags)
+static inline void pgd_walk_set_prot(void *pt, pgprot_t flags)
 {
        struct page *page = virt_to_page(pt);
        unsigned long pfn = page_to_pfn(page);
@@ -456,103 +454,111 @@
                pfn_pte(pfn, flags), 0));
 }
 
-static void mm_walk(struct mm_struct *mm, pgprot_t flags)
-{
-       pgd_t       *pgd;
-       pud_t       *pud;
-       pmd_t       *pmd;
-       pte_t       *pte;
-       int          g,u,m;
-
-       pgd = mm->pgd;
+static void pgd_walk(pgd_t *pgd_base, pgprot_t flags)
+{
+       pgd_t *pgd = pgd_base;
+       pud_t *pud;
+       pmd_t *pmd;
+       pte_t *pte;
+       int    g, u, m;
+
        for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
                if (pgd_none(*pgd))
                        continue;
                pud = pud_offset(pgd, 0);
                if (PTRS_PER_PUD > 1) /* not folded */
-                       mm_walk_set_prot(pud,flags);
+                       pgd_walk_set_prot(pud,flags);
                for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
                        if (pud_none(*pud))
                                continue;
                        pmd = pmd_offset(pud, 0);
                        if (PTRS_PER_PMD > 1) /* not folded */
-                               mm_walk_set_prot(pmd,flags);
+                               pgd_walk_set_prot(pmd,flags);
                        for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
                                if (pmd_none(*pmd))
                                        continue;
                                pte = pte_offset_kernel(pmd,0);
-                               mm_walk_set_prot(pte,flags);
+                               pgd_walk_set_prot(pte,flags);
                        }
                }
        }
+
+       BUG_ON(HYPERVISOR_update_va_mapping(
+               (unsigned long)pgd_base,
+               pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
+               UVMF_TLB_FLUSH));
+}
+
+static void __pgd_pin(pgd_t *pgd)
+{
+       pgd_walk(pgd, PAGE_KERNEL_RO);
+       xen_pgd_pin(__pa(pgd));
+       set_bit(PG_pinned, &virt_to_page(pgd)->flags);
+}
+
+static void __pgd_unpin(pgd_t *pgd)
+{
+       xen_pgd_unpin(__pa(pgd));
+       pgd_walk(pgd, PAGE_KERNEL);
+       clear_bit(PG_pinned, &virt_to_page(pgd)->flags);
 }
 
 void mm_pin(struct mm_struct *mm)
 {
-    spin_lock(&mm->page_table_lock);
-
-    mm_walk(mm, PAGE_KERNEL_RO);
-    BUG_ON(HYPERVISOR_update_va_mapping(
-        (unsigned long)mm->pgd,
-        pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL_RO),
-        UVMF_TLB_FLUSH));
-    xen_pgd_pin(__pa(mm->pgd));
-    mm->context.pinned = 1;
-    spin_lock(&mm_unpinned_lock);
-    list_del(&mm->context.unpinned);
-    spin_unlock(&mm_unpinned_lock);
-
-    spin_unlock(&mm->page_table_lock);
+       spin_lock(&mm->page_table_lock);
+       __pgd_pin(mm->pgd);
+       spin_unlock(&mm->page_table_lock);
 }
 
 void mm_unpin(struct mm_struct *mm)
 {
-    spin_lock(&mm->page_table_lock);
-
-    xen_pgd_unpin(__pa(mm->pgd));
-    BUG_ON(HYPERVISOR_update_va_mapping(
-        (unsigned long)mm->pgd,
-        pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL), 0));
-    mm_walk(mm, PAGE_KERNEL);
-    xen_tlb_flush();
-    mm->context.pinned = 0;
-    spin_lock(&mm_unpinned_lock);
-    list_add(&mm->context.unpinned, &mm_unpinned);
-    spin_unlock(&mm_unpinned_lock);
-
-    spin_unlock(&mm->page_table_lock);
+       spin_lock(&mm->page_table_lock);
+       __pgd_unpin(mm->pgd);
+       spin_unlock(&mm->page_table_lock);
 }
 
 void mm_pin_all(void)
 {
-    while (!list_empty(&mm_unpinned))  
-       mm_pin(list_entry(mm_unpinned.next, struct mm_struct,
-                         context.unpinned));
+       struct page *page;
+       for (page = pgd_list; page; page = (struct page *)page->index) {
+               if (!test_bit(PG_pinned, &page->flags))
+                       __pgd_pin((pgd_t *)page_address(page));
+       }
 }
 
 void _arch_exit_mmap(struct mm_struct *mm)
 {
-    struct task_struct *tsk = current;
-
-    task_lock(tsk);
-
-    /*
-     * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
-     * *much* faster this way, as no tlb flushes means bigger wrpt batches.
-     */
-    if ( tsk->active_mm == mm )
-    {
-        tsk->active_mm = &init_mm;
-        atomic_inc(&init_mm.mm_count);
-
-        switch_mm(mm, &init_mm, tsk);
-
-        atomic_dec(&mm->mm_count);
-        BUG_ON(atomic_read(&mm->mm_count) == 0);
-    }
-
-    task_unlock(tsk);
-
-    if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) )
-        mm_unpin(mm);
-}
+       struct task_struct *tsk = current;
+
+       task_lock(tsk);
+
+       /*
+        * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
+        * *much* faster this way, as no tlb flushes means bigger wrpt batches.
+        */
+       if (tsk->active_mm == mm) {
+               tsk->active_mm = &init_mm;
+               atomic_inc(&init_mm.mm_count);
+
+               switch_mm(mm, &init_mm, tsk);
+
+               atomic_dec(&mm->mm_count);
+               BUG_ON(atomic_read(&mm->mm_count) == 0);
+       }
+
+       task_unlock(tsk);
+
+       if (test_bit(PG_pinned, &virt_to_page(mm->pgd)->flags) &&
+           (atomic_read(&mm->mm_count) == 1))
+               mm_unpin(mm);
+}
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r d51b071bfcfc -r 66dd96e90be4 
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Mon Nov  7 22:53:25 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Tue Nov  8 02:40:31 2005
@@ -129,8 +129,8 @@
        preempt_disable();
 
 #ifdef __i386__
+       kmem_cache_shrink(pgd_cache);
        mm_pin_all();
-       kmem_cache_shrink(pgd_cache);
 #endif
 
        __cli();
diff -r d51b071bfcfc -r 66dd96e90be4 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/mmu.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mmu.h       Mon Nov  7 
22:53:25 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mmu.h       Tue Nov  8 
02:40:31 2005
@@ -12,12 +12,7 @@
        int size;
        struct semaphore sem;
        void *ldt;
-       unsigned pinned:1;
-       struct list_head unpinned;
 } mm_context_t;
-
-extern struct list_head mm_unpinned;
-extern spinlock_t mm_unpinned_lock;
 
 /* mm/memory.c:exit_mmap hook */
 extern void _arch_exit_mmap(struct mm_struct *mm);
diff -r d51b071bfcfc -r 66dd96e90be4 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/mmu_context.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mmu_context.h       Mon Nov 
 7 22:53:25 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mmu_context.h       Tue Nov 
 8 02:40:31 2005
@@ -53,7 +53,7 @@
        struct mmuext_op _op[2], *op = _op;
 
        if (likely(prev != next)) {
-               if (!next->context.pinned)
+               if (!test_bit(PG_pinned, &virt_to_page(next->pgd)->flags))
                        mm_pin(next);
 
                /* stop flush ipis for the previous mm */
diff -r d51b071bfcfc -r 66dd96e90be4 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgalloc.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgalloc.h   Mon Nov  7 
22:53:25 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgalloc.h   Tue Nov  8 
02:40:31 2005
@@ -7,12 +7,15 @@
 #include <linux/mm.h>          /* for struct page */
 #include <asm/io.h>            /* for phys_to_virt and page_to_pseudophys */
 
+/* Is this pagetable pinned? */
+#define PG_pinned      PG_arch_1
+
 #define pmd_populate_kernel(mm, pmd, pte) \
                set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
 
 #define pmd_populate(mm, pmd, pte)                                     \
 do {                                                                   \
-       if (unlikely((mm)->context.pinned)) {                           \
+       if (test_bit(PG_pinned, &virt_to_page((mm)->pgd)->flags)) {     \
                if (!PageHighMem(pte))                                  \
                        BUG_ON(HYPERVISOR_update_va_mapping(            \
                          (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT),\
diff -r d51b071bfcfc -r 66dd96e90be4 xen/arch/x86/dm/i8259.c
--- a/xen/arch/x86/dm/i8259.c   Mon Nov  7 22:53:25 2005
+++ b/xen/arch/x86/dm/i8259.c   Tue Nov  8 02:40:31 2005
@@ -33,6 +33,7 @@
 #include <asm/vmx.h>
 #include <public/io/vmx_vpic.h>
 #include <asm/current.h>
+#include <asm/vmx_vioapic.h>
 #include <asm/vmx_vlapic.h>
 
 /* set irq level. If an edge is detected, then the IRR is set to 1 */
@@ -124,6 +125,7 @@
 {
     struct vmx_virpic *s = opaque;
 
+    vmx_vioapic_set_irq(current->domain, irq, level);
     pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
     /* used for IOAPIC irqs */
     if (s->alt_irq_func)
@@ -135,6 +137,7 @@
 {
     s->pics[1].irr |= (uint8_t)(irqs >> 8);
     s->pics[0].irr |= (uint8_t) irqs;
+    vmx_vioapic_do_irqs(current->domain, irqs);
     pic_update_irq(s);
 }
 
@@ -142,6 +145,7 @@
 {
     s->pics[1].irr &= ~(uint8_t)(irqs >> 8);
     s->pics[0].irr &= ~(uint8_t) irqs;
+    vmx_vioapic_do_irqs_clear(current->domain, irqs);
     pic_update_irq(s);
 }
 
@@ -521,7 +525,13 @@
 
 int is_pit_irq(struct vcpu *v, int irq, int type)
 {
-    int  pit_vec = v->domain->arch.vmx_platform.vmx_pic.pics[0].irq_base;
+    int pit_vec;
+
+    if (type == VLAPIC_DELIV_MODE_EXT)
+        pit_vec = v->domain->arch.vmx_platform.vmx_pic.pics[0].irq_base;
+    else
+        pit_vec =
+          
v->domain->arch.vmx_platform.vmx_vioapic.redirtbl[0].RedirForm.vector;
 
     return (irq == pit_vec);
 }
diff -r d51b071bfcfc -r 66dd96e90be4 xen/arch/x86/vmx_intercept.c
--- a/xen/arch/x86/vmx_intercept.c      Mon Nov  7 22:53:25 2005
+++ b/xen/arch/x86/vmx_intercept.c      Tue Nov  8 02:40:31 2005
@@ -33,13 +33,15 @@
 
 #ifdef CONFIG_VMX
 
-struct vmx_mmio_handler vmx_mmio_handers[VMX_MMIO_HANDLER_NR] =
-{
-    {
-        .check_handler = vlapic_range,
-        .read_handler  = vlapic_read,
-        .write_handler = vlapic_write
-    }
+extern struct vmx_mmio_handler vlapic_mmio_handler;
+extern struct vmx_mmio_handler vioapic_mmio_handler;
+
+#define VMX_MMIO_HANDLER_NR 2
+
+struct vmx_mmio_handler *vmx_mmio_handlers[VMX_MMIO_HANDLER_NR] =
+{
+    &vlapic_mmio_handler,
+    &vioapic_mmio_handler
 };
 
 static inline void vmx_mmio_access(struct vcpu *v,
@@ -134,16 +136,16 @@
 {
     struct vcpu *v = current;
     int i;
-    struct vmx_mmio_handler *handler = vmx_mmio_handers;
 
     /* XXX currently only APIC use intercept */
     if ( !vmx_apic_support(v->domain) )
         return 0;
 
     for ( i = 0; i < VMX_MMIO_HANDLER_NR; i++ ) {
-        if ( handler[i].check_handler(v, p->addr) ) {
+        if ( vmx_mmio_handlers[i]->check_handler(v, p->addr) ) {
             vmx_mmio_access(v, p,
-              handler[i].read_handler, handler[i].write_handler);
+                            vmx_mmio_handlers[i]->read_handler,
+                            vmx_mmio_handlers[i]->write_handler);
             return 1;
         }
     }
diff -r d51b071bfcfc -r 66dd96e90be4 xen/arch/x86/vmx_vlapic.c
--- a/xen/arch/x86/vmx_vlapic.c Mon Nov  7 22:53:25 2005
+++ b/xen/arch/x86/vmx_vlapic.c Tue Nov  8 02:40:31 2005
@@ -307,6 +307,11 @@
 
     vlapic_clear_isr(vlapic, vector);
     vlapic_update_ppr(vlapic);
+
+    if (test_and_clear_bit(vector, &vlapic->tmr[0])) {
+        extern void ioapic_update_EOI(struct domain *d, int vector);
+        ioapic_update_EOI(vlapic->domain, vector);
+    }
 }
 
 int vlapic_check_vector(struct vlapic *vlapic,
@@ -543,8 +548,8 @@
     }
 }
 
-unsigned long vlapic_read(struct vcpu *v, unsigned long address,
-            unsigned long len)
+static unsigned long vlapic_read(struct vcpu *v, unsigned long address,
+                                 unsigned long len)
 {
     unsigned int alignment;
     unsigned int tmp;
@@ -585,8 +590,8 @@
     return result;
 }
 
-unsigned long vlapic_write(struct vcpu *v, unsigned long address,
-                  unsigned long len, unsigned long val)
+static void vlapic_write(struct vcpu *v, unsigned long address,
+                         unsigned long len, unsigned long val)
 {
     struct vlapic *vlapic = VLAPIC(v);
     unsigned int offset = address - vlapic->base_address;
@@ -758,10 +763,9 @@
         printk("Local APIC Write to read-only register\n");
         break;
     }
-    return 1;
-}
-
-int vlapic_range(struct vcpu *v, unsigned long addr)
+}
+
+static int vlapic_range(struct vcpu *v, unsigned long addr)
 {
     struct vlapic *vlapic = VLAPIC(v);
 
@@ -772,6 +776,12 @@
 
     return 0;
 }
+
+struct vmx_mmio_handler vlapic_mmio_handler = {
+    .check_handler = vlapic_range,
+    .read_handler = vlapic_read,
+    .write_handler = vlapic_write
+};
 
 void vlapic_msr_set(struct vlapic *vlapic, uint64_t value)
 {
@@ -963,6 +973,8 @@
     vlapic->dest_format = 0xffffffffU;
 
     vlapic->spurious_vec = 0xff;
+
+    vmx_vioapic_add_lapic(vlapic, v);
 
     init_ac_timer(&vlapic->vlapic_timer,
                   vlapic_timer_fn, vlapic, v->processor);
diff -r d51b071bfcfc -r 66dd96e90be4 xen/arch/x86/vmx_vmcs.c
--- a/xen/arch/x86/vmx_vmcs.c   Mon Nov  7 22:53:25 2005
+++ b/xen/arch/x86/vmx_vmcs.c   Tue Nov  8 02:40:31 2005
@@ -28,6 +28,7 @@
 #include <asm/processor.h>
 #include <asm/msr.h>
 #include <asm/vmx.h>
+#include <asm/vmx_vioapic.h>
 #include <asm/flushtlb.h>
 #include <xen/event.h>
 #include <xen/kernel.h>
@@ -255,6 +256,7 @@
 
     if ( vmx_apic_support(d) ) {
         spin_lock_init(&d->arch.vmx_platform.round_robin_lock);
+        vmx_vioapic_init(d);
     }
 }
 
diff -r d51b071bfcfc -r 66dd96e90be4 xen/include/asm-x86/vmx_intercept.h
--- a/xen/include/asm-x86/vmx_intercept.h       Mon Nov  7 22:53:25 2005
+++ b/xen/include/asm-x86/vmx_intercept.h       Tue Nov  8 02:40:31 2005
@@ -18,10 +18,10 @@
                                          unsigned long addr,
                                          unsigned long length);
 
-typedef unsigned long (*vmx_mmio_write_t)(struct vcpu *v,
-                                         unsigned long addr,
-                                         unsigned long length,
-                                         unsigned long val);
+typedef void (*vmx_mmio_write_t)(struct vcpu *v,
+                                 unsigned long addr,
+                                 unsigned long length,
+                                 unsigned long val);
 
 typedef int (*vmx_mmio_check_t)(struct vcpu *v, unsigned long addr);
 
@@ -43,10 +43,6 @@
     vmx_mmio_write_t write_handler;
 };
 
-#define VMX_MMIO_HANDLER_NR 1
-
-extern struct vmx_mmio_handler vmx_mmio_handers[VMX_MMIO_HANDLER_NR];
-
 /* global io interception point in HV */
 extern int vmx_io_intercept(ioreq_t *p, int type);
 extern int register_io_handler(unsigned long addr, unsigned long size,
diff -r d51b071bfcfc -r 66dd96e90be4 xen/include/asm-x86/vmx_platform.h
--- a/xen/include/asm-x86/vmx_platform.h        Mon Nov  7 22:53:25 2005
+++ b/xen/include/asm-x86/vmx_platform.h        Tue Nov  8 02:40:31 2005
@@ -24,6 +24,7 @@
 #include <asm/e820.h>
 #include <asm/vmx_virpit.h>
 #include <asm/vmx_intercept.h>
+#include <asm/vmx_vioapic.h>
 #include <public/io/vmx_vpic.h>
 
 #define MAX_OPERAND_NUM 2
@@ -85,6 +86,7 @@
     struct vmx_virpit      vmx_pit;
     struct vmx_io_handler  vmx_io_handler;
     struct vmx_virpic      vmx_pic;
+    struct vmx_vioapic      vmx_vioapic;
     unsigned char          round_info[256];
     spinlock_t             round_robin_lock;
     int                    interrupt_request;
diff -r d51b071bfcfc -r 66dd96e90be4 xen/include/asm-x86/vmx_vlapic.h
--- a/xen/include/asm-x86/vmx_vlapic.h  Mon Nov  7 22:53:25 2005
+++ b/xen/include/asm-x86/vmx_vlapic.h  Tue Nov  8 02:40:31 2005
@@ -225,14 +225,6 @@
 
 extern void vlapic_msr_set(struct vlapic *vlapic, uint64_t value);
 
-int vlapic_range(struct vcpu *v, unsigned long addr);
-
-unsigned long vlapic_write(struct vcpu *v, unsigned long address,
-                           unsigned long len, unsigned long val);
-
-unsigned long vlapic_read(struct vcpu *v, unsigned long address,
-                          unsigned long len);
-
 int vlapic_accept_pic_intr(struct vcpu *v);
 
 struct vlapic* apic_round_robin(struct domain *d,
diff -r d51b071bfcfc -r 66dd96e90be4 xen/include/asm-x86/vmx_vmcs.h
--- a/xen/include/asm-x86/vmx_vmcs.h    Mon Nov  7 22:53:25 2005
+++ b/xen/include/asm-x86/vmx_vmcs.h    Tue Nov  8 02:40:31 2005
@@ -284,7 +284,8 @@
 #define DBG_LEVEL_VMMU              (1 << 5)
 #define DBG_LEVEL_VLAPIC            (1 << 6)
 #define DBG_LEVEL_VLAPIC_TIMER      (1 << 7)
-#define DBG_LEVEL_VLAPIC_INTERRUPT  (1 << 7)
+#define DBG_LEVEL_VLAPIC_INTERRUPT  (1 << 8)
+#define DBG_LEVEL_IOAPIC            (1 << 9)
 
 extern unsigned int opt_vmx_debug_level;
 #define VMX_DBG_LOG(level, _f, _a...)           \
diff -r d51b071bfcfc -r 66dd96e90be4 xen/arch/x86/dm/vmx_vioapic.c
--- /dev/null   Mon Nov  7 22:53:25 2005
+++ b/xen/arch/x86/dm/vmx_vioapic.c     Tue Nov  8 02:40:31 2005
@@ -0,0 +1,608 @@
+/*
+*  Copyright (C) 2001  MandrakeSoft S.A.
+*
+*    MandrakeSoft S.A.
+*    43, rue d'Aboukir
+*    75002 Paris - France
+*    http://www.linux-mandrake.com/
+*    http://www.mandrakesoft.com/
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+/*
+*  Yunhong Jiang <yunhong.jiang@xxxxxxxxx>
+*  Ported to xen by using virtual IRQ line.
+*/
+
+#include <asm/vmx_vioapic.h>
+#include <asm/vmx_platform.h>
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/mm.h>
+#include <xen/xmalloc.h>
+#include <xen/lib.h>
+#include <xen/errno.h>
+#include <xen/sched.h>
+#include <public/io/ioreq.h>
+#include <asm/vmx.h>
+#include <public/io/vmx_vpic.h>
+#include <asm/current.h>
+
+static void ioapic_enable(vmx_vioapic_t *s, uint8_t enable)
+{
+    if (enable)
+        s->flags |= IOAPIC_ENABLE_FLAG;
+    else
+        s->flags &= ~IOAPIC_ENABLE_FLAG;
+}
+
+static void ioapic_dump_redir(vmx_vioapic_t *s, uint8_t entry)
+{
+    ASSERT(s);
+
+    RedirStatus redir = s->redirtbl[entry];
+
+    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_dump_redir "
+      "entry %x vector %x deliver_mod %x destmode %x delivestatus %x "
+      "polarity %x remote_irr %x trigmod %x mask %x dest_id %x\n",
+      entry, redir.RedirForm.vector, redir.RedirForm.deliver_mode,
+      redir.RedirForm.destmode, redir.RedirForm.delivestatus,
+      redir.RedirForm.polarity, redir.RedirForm.remoteirr,
+      redir.RedirForm.trigmod, redir.RedirForm.mask,
+      redir.RedirForm.dest_id);
+}
+
+#ifdef VMX_DOMAIN_SAVE_RESTORE
+void ioapic_save(QEMUFile* f, void* opaque)
+{
+    printk("no implementation for ioapic_save\n");
+}
+
+int ioapic_load(QEMUFile* f, void* opaque, int version_id)
+{
+    printk("no implementation for ioapic_load\n");
+    return 0;
+}
+#endif
+
+static unsigned long vmx_vioapic_read_indirect(struct vmx_vioapic *s,
+                                              unsigned long addr,
+                                              unsigned long length)
+{
+    unsigned long result = 0;
+
+    ASSERT(s);
+
+    switch (s->ioregsel) {
+    case IOAPIC_REG_VERSION:
+        result = ((((IOAPIC_NUM_PINS-1) & 0xff) << 16)
+                  | (IOAPIC_VERSION_ID & 0x0f));
+        break;
+
+#ifndef __ia64__
+    case IOAPIC_REG_APIC_ID:
+        result = ((s->id & 0xf) << 24);
+        break;
+
+    case IOAPIC_REG_ARB_ID:
+        /* XXX how arb_id used on p4? */
+        result = ((s->id & 0xf) << 24);
+        break;
+#endif
+
+    default:
+        {
+            uint32_t redir_index = 0;
+            uint64_t redir_content = 0;
+
+            redir_index = (s->ioregsel - 0x10) >> 1;
+
+            if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS) {
+                redir_content = s->redirtbl[redir_index].value;
+
+                result = (s->ioregsel & 0x1)?
+                           (redir_content >> 32) & 0xffffffff :
+                           redir_content & 0xffffffff;
+            } else {
+                printk("upic_mem_readl:undefined ioregsel %x\n",
+                        s->ioregsel);
+                domain_crash_synchronous();
+            }
+            break;
+        }
+    } /* switch */
+
+    return result;
+}
+
+static unsigned long vmx_vioapic_read(struct vcpu *v,
+                                     unsigned long addr,
+                                     unsigned long length)
+{
+    struct vmx_vioapic *s = &(v->domain->arch.vmx_platform.vmx_vioapic);
+    uint32_t    result = 0;
+
+    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "vmx_vioapic_read addr %lx\n", addr);
+
+    ASSERT(s);
+
+    addr &= 0xff;
+
+    switch (addr) {
+    case IOAPIC_REG_SELECT:
+        result = s->ioregsel;
+        break;
+
+    case IOAPIC_REG_WINDOW:
+        result = vmx_vioapic_read_indirect(s, addr, length);
+        break;
+
+    default:
+          break;
+    }
+
+    return result;
+}
+
+static void vmx_vioapic_write_indirect(struct vmx_vioapic *s,
+                                      unsigned long addr,
+                                      unsigned long length,
+                                      unsigned long val)
+{
+    switch (s->ioregsel) {
+    case IOAPIC_REG_VERSION:
+        printk("vmx_vioapic_write_indirect: version register read only\n");
+        break;
+
+#ifndef __ia64__
+    case IOAPIC_REG_APIC_ID:
+        s->id = (val >> 24) & 0xf;
+        break;
+
+    case IOAPIC_REG_ARB_ID:
+        s->arb_id = val;
+        break;
+#endif
+
+    default:
+        {
+            uint32_t redir_index = 0;
+
+            VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "vmx_vioapic_write_indirect "
+              "change redir index %x val %lx\n",
+              redir_index, val);
+
+            redir_index = (s->ioregsel - 0x10) >> 1;
+
+            if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS) {
+                uint64_t redir_content;
+
+                redir_content = s->redirtbl[redir_index].value;
+
+                if (s->ioregsel & 0x1)
+                    redir_content = (((uint64_t)val & 0xffffffff) << 32) |
+                                    (redir_content & 0xffffffff);
+                else
+                    redir_content = ((redir_content >> 32) << 32) |
+                                    (val & 0xffffffff);
+                s->redirtbl[redir_index].value = redir_content;
+            } else  {
+                printk("vmx_vioapic_write_indirect "
+                  "error register %x\n", s->ioregsel);
+            }
+            break;
+        }
+    } /* switch */
+}
+
+static void vmx_vioapic_write(struct vcpu *v,
+                             unsigned long addr,
+                             unsigned long length,
+                             unsigned long val)
+{
+    vmx_vioapic_t *s = &(v->domain->arch.vmx_platform.vmx_vioapic);
+
+    ASSERT(s);
+
+    addr &= 0xff;
+
+    switch (addr) {
+    case IOAPIC_REG_SELECT:
+        s->ioregsel = val;
+        break;
+
+    case IOAPIC_REG_WINDOW:
+        vmx_vioapic_write_indirect(s, addr, length, val);
+        break;
+
+#ifdef __ia64__
+    case IOAPIC_REG_EOI:
+        ioapic_update_EOI(v->domain, val);
+        break;
+#endif
+
+    default:
+        break;
+    }
+}
+
+static int vmx_vioapic_range(struct vcpu *v, unsigned long addr)
+{
+    vmx_vioapic_t *s = &(v->domain->arch.vmx_platform.vmx_vioapic);
+
+    if ((s->flags & IOAPIC_ENABLE_FLAG) &&
+        (addr >= s->base_address &&
+        (addr <= s->base_address + IOAPIC_MEM_LENGTH)))
+        return 1;
+    else
+        return 0;
+}
+
+struct vmx_mmio_handler vioapic_mmio_handler = {
+    .check_handler = vmx_vioapic_range,
+    .read_handler = vmx_vioapic_read,
+    .write_handler = vmx_vioapic_write
+};
+
+static void vmx_vioapic_reset(vmx_vioapic_t *s)
+{
+    int i;
+
+    memset(s, 0, sizeof(vmx_vioapic_t));
+
+    for (i = 0; i < IOAPIC_NUM_PINS; i++)
+        s->redirtbl[i].RedirForm.mask = 0x1;
+}
+
+static void ioapic_update_config(vmx_vioapic_t *s,
+                                 unsigned long address,
+                                 uint8_t enable)
+{
+    ASSERT(s);
+
+    ioapic_enable(s, enable);
+
+    if (address != s->base_address)
+        s->base_address = address;
+}
+
+static int ioapic_inj_irq(vmx_vioapic_t *s,
+                          struct vlapic * target,
+                          uint8_t vector,
+                          uint8_t trig_mode,
+                          uint8_t delivery_mode)
+{
+    int result = 0;
+
+    ASSERT(s && target);
+
+    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_inj_irq "
+      "irq %d trig %d delive mode %d\n",
+      vector, trig_mode, delivery_mode);
+
+    switch (delivery_mode) {
+    case VLAPIC_DELIV_MODE_FIXED:
+    case VLAPIC_DELIV_MODE_LPRI:
+        if (test_and_set_bit(vector, &target->irr[0]) && trig_mode == 1) {
+            /* the level interrupt should not happen before it is cleard */
+            printk("<ioapic_inj_irq> level interrupt happen before cleard\n");
+        }
+        if (trig_mode)
+            test_and_set_bit(vector, &target->tmr[0]);
+        result = 1;
+        break;
+    default:
+        printk("<ioapic_inj_irq> error delivery mode %d\n",
+                delivery_mode);
+        break;
+   }
+
+   return result;
+}
+
+#ifndef __ia64__
+static int ioapic_match_logical_addr(vmx_vioapic_t *s, int number, uint8_t 
dest)
+{
+    int result = 0;
+
+    ASSERT(s && s->lapic_info[number]);
+
+    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_match_logical_addr "
+      "number %i dest %x\n",
+      number, dest);
+
+    switch (((s->lapic_info[number]->dest_format >> 28) & 0xf)) {
+    case 0xf:
+        result =
+          (dest & ((s->lapic_info[number]->logical_dest >> 24) & 0xff)) != 0;
+        break;
+    case 0x0:
+        /* Should we support flat cluster mode ?*/
+        if ( ((s->lapic_info[number]->logical_dest >> 28)
+               == ((dest >> 0x4) & 0xf)) &&
+             (((s->lapic_info[number]->logical_dest >> 24) & 0xf)
+               & (dest  & 0xf)) )
+            result = 1;
+        break;
+    default:
+        printk("error DFR value for %x local apic\n", number);
+        break;
+    }
+
+    return result;
+}
+#else
+extern int ioapic_match_logical_addr(vmx_vioapic_t *s, int number, uint8_t 
dest);
+#endif
+
+static uint32_t ioapic_get_delivery_bitmask(vmx_vioapic_t *s,
+                                            uint16_t dest,
+                                            uint8_t dest_mode,
+                                            uint8_t vector,
+                                            uint8_t delivery_mode)
+{
+    uint32_t mask = 0;
+    int i;
+
+    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask "
+      "dest %d dest_mode %d "
+      "vector %d del_mode %d, lapic_count %d\n",
+      dest, dest_mode, vector, delivery_mode, s->lapic_count);
+
+    ASSERT(s);
+
+    if (dest_mode == 0) { /* Physical mode */
+        for (i = 0; i < s->lapic_count; i++) {
+            if (s->lapic_info[i]->id == dest) {
+                mask = 1 << i;
+                break;
+            }
+        }
+    } else {
+        /* logical destination. call match_logical_addr for each APIC. */
+        if (dest != 0) {
+            for (i=0; i< s->lapic_count; i++) {
+                if ( s->lapic_info[i] &&
+                     ioapic_match_logical_addr(s, i, dest) ) {
+                    mask |= (1<<i);
+                }
+            }
+        }
+    }
+
+    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask "
+      "mask %x\n", mask);
+
+    return mask;
+}
+
+static void ioapic_deliver(vmx_vioapic_t *s, int irqno)
+{
+    uint16_t dest = s->redirtbl[irqno].RedirForm.dest_id;
+    uint8_t dest_mode = s->redirtbl[irqno].RedirForm.destmode;
+    uint8_t delivery_mode = s->redirtbl[irqno].RedirForm.deliver_mode;
+    uint8_t vector = s->redirtbl[irqno].RedirForm.vector;
+    uint8_t trig_mode = s->redirtbl[irqno].RedirForm.trigmod;
+    uint32_t deliver_bitmask;
+
+    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "IOAPIC deliver: "
+      "dest %x dest_mode %x delivery_mode %x vector %x trig_mode %x\n",
+      dest, dest_mode, delivery_mode, vector, trig_mode);
+
+    deliver_bitmask =
+      ioapic_get_delivery_bitmask(s, dest, dest_mode, vector, delivery_mode);
+
+    if (!deliver_bitmask) {
+        VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver "
+          "no target on destination\n");
+
+        return;
+    }
+
+    switch (delivery_mode) {
+    case VLAPIC_DELIV_MODE_LPRI:
+    {
+        struct vlapic* target;
+
+        target = apic_round_robin(
+                s->domain, dest_mode, vector, deliver_bitmask);
+        ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode);
+        break;
+    }
+
+    case VLAPIC_DELIV_MODE_FIXED:
+    case VLAPIC_DELIV_MODE_EXT:
+    {
+        uint8_t bit;
+        for (bit = 0; bit < s->lapic_count; bit++) {
+            if (deliver_bitmask & (1 << bit)) {
+                if (s->lapic_info[bit]) {
+                    ioapic_inj_irq(s, s->lapic_info[bit],
+                                vector, trig_mode, delivery_mode);
+                }
+            }
+        }
+        break;
+    }
+
+    case VLAPIC_DELIV_MODE_SMI:
+    case VLAPIC_DELIV_MODE_NMI:
+    case VLAPIC_DELIV_MODE_INIT:
+    case VLAPIC_DELIV_MODE_STARTUP:
+    default:
+        printk("Not support delivey mode %d\n", delivery_mode);
+        break;
+    }
+}
+
+static int ioapic_get_highest_irq(vmx_vioapic_t *s)
+{
+    uint32_t irqs;
+
+    ASSERT(s);
+
+    irqs = s->irr & ~s->isr;
+    return __fls(irqs);
+}
+
+
+static void service_ioapic(vmx_vioapic_t *s)
+{
+    int irqno;
+
+    while ((irqno = ioapic_get_highest_irq(s)) != -1) {
+
+        VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "service_ioapic "
+          "highest irqno %x\n", irqno);
+
+        if (!s->redirtbl[irqno].RedirForm.mask) {
+            ioapic_deliver(s, irqno);
+        }
+
+        if (s->redirtbl[irqno].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER) {
+            s->isr |= (1 << irqno);
+        }
+
+        s->irr &= ~(1 << irqno);
+    }
+}
+
+void vmx_vioapic_do_irqs(struct domain *d, uint16_t irqs)
+{
+    vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic);
+
+    if (!vmx_apic_support(d))
+        return;
+
+    s->irr |= irqs;
+    service_ioapic(s);
+}
+
+void vmx_vioapic_do_irqs_clear(struct domain *d, uint16_t irqs)
+{
+    vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic);
+
+    if (!vmx_apic_support(d))
+        return;
+
+    s->irr &= ~irqs;
+    service_ioapic(s);
+}
+
+void vmx_vioapic_set_irq(struct domain *d, int irq, int level)
+{
+    vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic);
+
+    if (!vmx_apic_support(d))
+        return ;
+
+    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_set_irq "
+      "irq %x level %x\n", irq, level);
+
+    if (irq < 0 || irq >= IOAPIC_NUM_PINS) {
+        printk("ioapic_set_irq irq %x is illegal\n", irq);
+        domain_crash_synchronous();
+    }
+
+    if (!IOAPICEnabled(s) || s->redirtbl[irq].RedirForm.mask)
+        return;
+
+    ioapic_dump_redir(s, irq);
+
+    if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
+        uint32_t bit = 1 << irq;
+        if (s->redirtbl[irq].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER) {
+            if (level)
+                s->irr |= bit;
+            else
+                s->irr &= ~bit;
+        } else {
+            if (level)
+                /* XXX No irr clear for edge interrupt */
+                s->irr |= bit;
+        }
+    }
+
+    service_ioapic(s);
+}
+
+/* XXX If level interrupt, use vector->irq table for performance */
+static int get_redir_num(vmx_vioapic_t *s, int vector)
+{
+    int i = 0;
+
+    ASSERT(s);
+
+    for(i = 0; i < IOAPIC_NUM_PINS - 1; i++) {
+        if (s->redirtbl[i].RedirForm.vector == vector)
+            return i;
+    }
+
+    return -1;
+}
+
+void ioapic_update_EOI(struct domain *d, int vector)
+{
+    vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic);
+    int redir_num;
+
+    if ((redir_num = get_redir_num(s, vector)) == -1) {
+        printk("Can't find redir item for %d EOI \n", vector);
+        return;
+    }
+
+    if (!test_and_clear_bit(redir_num, &s->isr)) {
+        printk("redir %d not set for %d  EOI\n", redir_num, vector);
+        return;
+    }
+}
+
+int vmx_vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v)
+{
+    vmx_vioapic_t *s = &(v->domain->arch.vmx_platform.vmx_vioapic);
+
+    if (v->vcpu_id != s->lapic_count) {
+        printk("vmx_vioapic_add_lapic "
+           "cpu_id not match vcpu_id %x lapic_count %x\n",
+           v->vcpu_id, s->lapic_count);
+        domain_crash_synchronous();
+    }
+
+    s->lapic_info[s->lapic_count ++] = vlapic;
+
+    return s->lapic_count;
+}
+
+vmx_vioapic_t * vmx_vioapic_init(struct domain *d)
+{
+    int i = 0;
+    vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic);
+
+    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "vmx_vioapic_init\n");
+
+    vmx_vioapic_reset(s);
+
+    s->domain = d;
+
+    for (i = 0; i < MAX_LAPIC_NUM; i++)
+        s->lapic_info[i] = NULL;
+
+    /* Remove after GFW ready */
+    ioapic_update_config(s, IOAPIC_DEFAULT_BASE_ADDRESS, 1);
+
+    return s;
+}
diff -r d51b071bfcfc -r 66dd96e90be4 xen/include/asm-x86/vmx_vioapic.h
--- /dev/null   Mon Nov  7 22:53:25 2005
+++ b/xen/include/asm-x86/vmx_vioapic.h Tue Nov  8 02:40:31 2005
@@ -0,0 +1,136 @@
+/*
+ *
+ *  Copyright (C) 2001  MandrakeSoft S.A.
+ *
+ *    MandrakeSoft S.A.
+ *    43, rue d'Aboukir
+ *    75002 Paris - France
+ *    http://www.linux-mandrake.com/
+ *    http://www.mandrakesoft.com/
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef _IOAPIC_H_
+#define _IOAPIC_H_
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/smp.h>
+
+#ifndef __ia64__
+#define IOAPIC_VERSION_ID 0x11
+#else
+#define IOAPIC_VERSION_ID 0x21
+#endif
+
+#define IOAPIC_NUM_PINS 24
+#define MAX_LAPIC_NUM   32
+
+#define IOAPIC_LEVEL_TRIGGER 1
+
+#define IOAPIC_DEFAULT_BASE_ADDRESS  0xfec00000
+#define IOAPIC_MEM_LENGTH            0x100
+
+#define IOAPIC_ENABLE_MASK  0x0
+#define IOAPIC_ENABLE_FLAG  (1 << IOAPIC_ENABLE_MASK)
+#define IOAPICEnabled(s)    (s->flags & IOAPIC_ENABLE_FLAG)
+
+#define IOAPIC_REG_SELECT  0x0
+#define IOAPIC_REG_WINDOW  0x10
+
+#ifdef __ia64__
+#define IOAPIC_REG_ASSERTION    0x20
+#define IOAPIC_REG_EOI          0x40
+#endif
+
+#ifndef __ia64__
+#define IOAPIC_REG_APIC_ID 0x0
+#define IOAPIC_REG_ARB_ID  0x2
+#endif
+
+#define IOAPIC_REG_VERSION 0x1
+
+#ifdef __ia64__
+typedef union RedirStatus
+{
+    uint64_t value;
+    struct {
+        uint16_t dest_id;
+        uint8_t reserved[3];
+        uint8_t reserve:7;
+        uint8_t mask:1;         /* interrupt mask*/
+        uint8_t trigmod:1;
+        uint8_t remoteirr:1;
+        uint8_t polarity:1;
+        uint8_t delivestatus:1;
+        uint8_t destmode:1;
+        uint8_t deliver_mode:3;
+        uint8_t vector;
+    } RedirForm;
+} RedirStatus;
+#else
+typedef union RedirStatus
+{
+    uint64_t value;
+    struct {
+        uint8_t vector;
+        uint8_t deliver_mode:3;
+        uint8_t destmode:1;
+        uint8_t delivestatus:1;
+        uint8_t polarity:1;
+        uint8_t remoteirr:1;
+        uint8_t trigmod:1;
+        uint8_t mask:1;         /* interrupt mask*/
+        uint8_t reserve:7;
+        uint8_t reserved[4];
+        uint8_t dest_id;
+    } RedirForm;
+} RedirStatus;
+#endif
+
+#define IOAPIC_MEM_LENGTH    0x100
+#define IOAPIC_ENABLE_MASK   0x0
+#define IOAPIC_ENABLE_FLAG   (1 << IOAPIC_ENABLE_MASK)
+#define MAX_LAPIC_NUM        32
+
+typedef struct vmx_vioapic {
+    uint32_t ioregsel;
+    uint32_t irr;
+    uint32_t isr;           /* This is used for level trigger */
+    uint32_t flags;
+    uint32_t lapic_count;
+    uint32_t id;
+    uint32_t arb_id;
+    unsigned long base_address;
+    RedirStatus redirtbl[IOAPIC_NUM_PINS];
+    struct vlapic *lapic_info[MAX_LAPIC_NUM];
+    struct domain *domain;
+} vmx_vioapic_t;
+
+vmx_vioapic_t *vmx_vioapic_init(struct domain *d);
+
+void vmx_vioapic_do_irqs_clear(struct domain *d, uint16_t irqs);
+void vmx_vioapic_do_irqs(struct domain *d, uint16_t irqs);
+void vmx_vioapic_set_irq(struct domain *d, int irq, int level);
+
+int vmx_vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v);
+
+#ifdef VMX_DOMAIN_SAVE_RESTORE
+void ioapic_save(QEMUFile* f, void* opaque);
+int ioapic_load(QEMUFile* f, void* opaque, int version_id);
+#endif
+
+#endif
diff -r d51b071bfcfc -r 66dd96e90be4 tools/ioemu/hw/ioapic.c
--- a/tools/ioemu/hw/ioapic.c   Mon Nov  7 22:53:25 2005
+++ /dev/null   Tue Nov  8 02:40:31 2005
@@ -1,704 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-
-#include "vl.h"
-#include "ioapic.h"
-
-#ifdef __OS
-#undef __OS
-#endif
-#ifdef __i386__
-#define __OS   "l"
-#else
-#define __OS "q"
-#endif
-#define ADDR (*(volatile long *) addr)
-
-#ifdef IOAPIC_DEBUG
-#define IOAPIC_LOG(a...) fprintf(logfile, ##a)
-#else
-#define IOAPIC_LOG(a...)
-#endif
-
-static IOAPICState *ioapic;
-
-#define IOAPIC_ERR(a...) fprintf(logfile, ##a)
-static __inline__ int test_and_set_bit(long nr, volatile void * addr)
-{
-       long oldbit;
-
-       __asm__ __volatile__( 
-               "bts"__OS" %2,%1\n\tsbb"__OS" %0,%0"
-               :"=r" (oldbit),"=m" (ADDR)
-               :"Ir" (nr) : "memory");
-       return oldbit;
-}
-
-static __inline__ int test_and_clear_bit(long nr, volatile void * addr)
-{
-       long oldbit;
-
-       __asm__ __volatile__( LOCK_PREFIX
-               "btr"__OS" %2,%1\n\tsbb"__OS" %0,%0"
-               :"=r" (oldbit),"=m" (ADDR)
-               :"dIr" (nr) : "memory");
-       return oldbit;
-}
-
-static __inline__ void clear_bit(long nr, volatile void * addr)
-{
-       __asm__ __volatile__( 
-               "btr"__OS" %1,%0"
-               :"=m" (ADDR)
-               :"Ir" (nr));
-}
-
-static inline
-void get_shareinfo_apic_msg(vlapic_info *share_info){
-    while(test_and_set_bit(VL_STATE_MSG_LOCK, &share_info->vl_state)){};
-}
-
-static inline
-void put_shareinfo_apic_msg(vlapic_info *share_info){
-    clear_bit(VL_STATE_MSG_LOCK, &share_info->vl_state);
-}
-static inline
-void get_shareinfo_eoi(vlapic_info *share_info){
-    while(test_and_set_bit(VL_STATE_EOI_LOCK, &share_info->vl_state)){};
-}
-
-static inline
-void put_shareinfo_eoi(vlapic_info *share_info){
-    clear_bit(VL_STATE_EOI_LOCK, &share_info->vl_state);
-}
-
-
-static inline
-void get_shareinfo_ext(vlapic_info *share_info){
-    while(test_and_set_bit(VL_STATE_EXT_LOCK, &share_info->vl_state));
-}
-
-static inline
-void put_shareinfo_ext(vlapic_info *share_info){
-    clear_bit(VL_STATE_EXT_LOCK, &share_info->vl_state);
-}
-
-
-static __inline__ int test_bit(int nr, uint32_t value){
-    return value & (1 << nr);
-}
-
-static void ioapic_enable(IOAPICState *s, uint8_t enable)
-{
-    if (!enable ^ IOAPICEnabled(s)) return;
-    if(enable)
-        s->flags |= IOAPIC_ENABLE_FLAG;
-    else
-        s->flags &= ~IOAPIC_ENABLE_FLAG;
-}
-
-#ifdef IOAPIC_DEBUG
-static void
-ioapic_dump_redir(IOAPICState *s, uint8_t entry)
-{
-    if (!s)
-        return;
-
-    RedirStatus redir = s->redirtbl[entry];
-
-    fprintf(logfile, "entry %x: "
-      "vector %x deliver_mod %x destmode %x delivestatus %x "
-      "polarity %x remote_irr %x trigmod %x mask %x dest_id %x\n",
-      entry,
-      redir.RedirForm.vector, redir.RedirForm.deliver_mode,
-      redir.RedirForm.destmode, redir.RedirForm.delivestatus,
-      redir.RedirForm.polarity, redir.RedirForm.remoteirr,
-      redir.RedirForm.trigmod, redir.RedirForm.mask,
-      redir.RedirForm.dest_id);
-}
-
-static void
-ioapic_dump_shareinfo(IOAPICState *s , int number)
-{
-    if (!s || !s->lapic_info[number])
-        return;
-    vlapic_info *m = s->lapic_info[number];
-    IOAPIC_LOG("lapic_info %x : "
-      "vl_lapic_id %x vl_logical_dest %x vl_dest_format %x vl_arb_id %x\n",
-      number, m->vl_lapic_id, m->vl_logical_dest, m->vl_dest_format, 
m->vl_arb_id );
-}
-#endif
-
-static void
-ioapic_save(QEMUFile* f,void* opaque)
-{
-    IOAPIC_ERR("no implementation for ioapic_save\n");
-}
-
-static
-int ioapic_load(QEMUFile* f,void* opaque,int version_id)
-{
-    IOAPIC_ERR("no implementation for ioapic_load\n");
-    return 0;
-}
-
-uint32_t
-ioapic_mem_readb(void *opaque, target_phys_addr_t addr)
-{
-    IOAPIC_ERR("ioapic_mem_readb\n");
-    return 0;
-}
-
-uint32_t
-ioapic_mem_readw(void *opaque, target_phys_addr_t addr)
-{
-    IOAPIC_ERR("ioapic_mem_readw\n");
-    return 0;
-}
-
-static
-void ioapic_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    IOAPIC_ERR("ioapic_mem_writeb\n");
-}
-
-static
-void ioapic_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    IOAPIC_ERR("ioapic_mem_writew\n");
-}
-
-static
-uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr)
-{
-    unsigned short ioregsel;
-    IOAPICState *s = opaque;
-    uint32_t    result = 0;
-    uint32_t    redir_index = 0;
-    uint64_t    redir_content = 0;
-
-    IOAPIC_LOG("apic_mem_readl addr %x\n", addr);
-    if (!s){
-        IOAPIC_ERR("null pointer for apic_mem_readl\n");
-        return result;
-    }
-
-    addr &= 0xff;
-    if(addr == 0x00){
-        result = s->ioregsel;
-        return result;
-    }else if (addr != 0x10){
-        IOAPIC_ERR("apic_mem_readl address error\n");
-        return result;
-    }
-
-    ioregsel = s->ioregsel;
-
-    switch (ioregsel){
-        case IOAPIC_REG_APIC_ID:
-            result = ((s->id & 0xf) << 24);
-            break;
-        case IOAPIC_REG_VERSION:
-            result = ((((IOAPIC_NUM_PINS-1) & 0xff) << 16)  
-                     | (IOAPIC_VERSION_ID & 0x0f));
-            break;
-        case IOAPIC_REG_ARB_ID:
-            //FIXME
-            result = ((s->id & 0xf) << 24);
-            break;
-        default:
-            redir_index = (ioregsel - 0x10) >> 1;
-            if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS){
-               redir_content = s->redirtbl[redir_index].value;
-               result = (ioregsel & 0x1)?
-                        (redir_content >> 32) & 0xffffffff :
-                        redir_content & 0xffffffff;
-            }else{
-                IOAPIC_ERR(
-                  "upic_mem_readl:undefined ioregsel %x\n",
-                  ioregsel);
-            }
-    }
-    return result;
-}
-
-static
-void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    IOAPICState *s = opaque;
-    uint32_t redir_index = 0;
-    uint64_t redir_content;
-
-    IOAPIC_LOG("apic_mem_writel addr %x val %x\n", addr, val);
-
-    if (!s){
-        IOAPIC_ERR("apic_mem_writel: null opaque\n");
-        return;
-    }
-
-    addr &= 0xff;
-    if (addr == 0x00){
-        s->ioregsel = val;
-        return;
-    }else if (addr != 0x10){
-        IOAPIC_ERR("apic_mem_writel: unsupported address\n");
-    }
-
-    switch (s->ioregsel){
-        case IOAPIC_REG_APIC_ID:
-            s->id = (val >> 24) & 0xf;
-            break;
-        case IOAPIC_REG_VERSION:
-            IOAPIC_ERR("apic_mem_writel: version register read only\n");
-            break;
-        case IOAPIC_REG_ARB_ID:
-            s->arb_id = val;
-            break;
-        default:
-            redir_index = (s->ioregsel - 0x10) >> 1;
-//            IOAPIC_LOG("apic_mem_write: change redir :index %x before %lx, 
val %x\n", redir_index, s->redirtbl[redir_index].value, val);
-            if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS){
-                redir_content = s->redirtbl[redir_index].value;
-                if (s->ioregsel & 0x1)
-                   redir_content = (((uint64_t)val & 0xffffffff) << 32) | 
(redir_content & 0xffffffff);
-                else
-                    redir_content = ((redir_content >> 32) << 32) | (val & 
0xffffffff);
-                s->redirtbl[redir_index].value = redir_content;
-            }else {
-                IOAPIC_ERR("apic_mem_writel: error register\n");
-            }
-            //IOAPIC_LOG("after value is %lx\n",  
s->redirtbl[redir_index].value);
-    }
-}
-
-static CPUReadMemoryFunc *ioapic_mem_read[3] = {
-    ioapic_mem_readb,
-    ioapic_mem_readw,
-    ioapic_mem_readl,
-};
-
-static CPUWriteMemoryFunc *ioapic_mem_write[3] = {
-    ioapic_mem_writeb,
-    ioapic_mem_writew,
-    ioapic_mem_writel,
-};
-
-void
-IOAPICReset(IOAPICState *s)
-{
-    int i;
-    if (!s)
-        return ;
-
-    memset(s, 0, sizeof(IOAPICState));
-
-    for (i = 0; i < IOAPIC_NUM_PINS; i++)
-        s->redirtbl[i].RedirForm.mask = 0x1;
-//    IOAPIC_LOG("after Reset %lx\n",  s->redirtbl[0].value);
-}
-
-void
-ioapic_update_config(IOAPICState *s, unsigned long address, uint8_t enable)
-{
-    int ioapic_mem;
-    if (!s)
-       return;
-
-    ioapic_enable(s, enable);
-
-    if (address != s->base_address){
-        ioapic_mem = cpu_register_io_memory(0, ioapic_mem_read, 
ioapic_mem_write, s);
-        cpu_register_physical_memory(address, IOAPIC_MEM_LENGTH, ioapic_mem);
-        s->base_address = ioapic_mem;
-    }
-}
-
-#define direct_intr(mode)   \
-  (mode == VLAPIC_DELIV_MODE_SMI || \
-   mode == VLAPIC_DELIV_MODE_NMI || \
-   mode == VLAPIC_DELIV_MODE_INIT ||\
-   mode == VLAPIC_DELIV_MODE_STARTUP)
-
-int
-ioapic_inj_irq(IOAPICState *s, uint8_t dest, uint8_t vector, uint8_t 
trig_mode, uint8_t delivery_mode)
-{
-    int msg_count;
-    if (!s || !s->lapic_info[dest]){
-        IOAPIC_ERR("ioapic_inj_irq NULL parameter\n");
-        return 0;
-    }
-    IOAPIC_LOG("ioapic_inj_irq %d , trig %d delive mode %d\n",
-      vector, trig_mode, delivery_mode);
-    switch(delivery_mode){
-        case VLAPIC_DELIV_MODE_FIXED:
-        case VLAPIC_DELIV_MODE_LPRI:
-            get_shareinfo_apic_msg(s->lapic_info[dest]);
-            msg_count = s->lapic_info[dest]->apic_msg_count;
-            s->lapic_info[dest]->vl_apic_msg[msg_count].deliv_mode = 
delivery_mode;
-            s->lapic_info[dest]->vl_apic_msg[msg_count].level = trig_mode;
-            s->lapic_info[dest]->vl_apic_msg[msg_count].vector = vector;
-            s->lapic_info[dest]->vl_apic_msg[msg_count].vector = vector;
-            s->lapic_info[dest]->apic_msg_count ++;
-            put_shareinfo_apic_msg(s->lapic_info[dest]);
-            break;
-        case VLAPIC_DELIV_MODE_EXT:
-/*            get_shareinfo_ext(s->lapic_info[dest]);
-            test_and_set_bit(vector, &s->lapic_info[dest]->vl_ext_intr[0]);
-            put_shareinfo_ext(s->lapic_info[dest]);*/
-            IOAPIC_ERR("<ioapic_inj_irq> Ext interrupt\n");
-            return 0;
-        default:
-            IOAPIC_ERR("<ioapic_inj_irq> error delivery mode\n");
-            break;
-    }
-    return 1;
-}
-
-int
-ioapic_match_logical_addr(IOAPICState *s, int number, uint8_t address)
-{
-    if(!s || !s->lapic_info[number]){
-        IOAPIC_ERR("ioapic_match_logical_addr NULL parameter: "
-          "number: %i s %p address %x\n",
-          number, s, address);
-        return 0;
-    }
-    IOAPIC_LOG("ioapic_match_logical_addr number %i address %x\n",
-      number, address);
-
-    if (((s->lapic_info[number]->vl_dest_format >> 28 ) & 0xf) != 0xf) {
-        IOAPIC_ERR("ioapic_match_logical_addr: cluster model not implemented 
still%x"
-          ,s->lapic_info[number]->vl_dest_format);
-#ifdef IOAPIC_DEBUG
-        ioapic_dump_shareinfo(s, number);
-#endif
-        return 0;
-    }
-    return ((address & ((s->lapic_info[number]->vl_logical_dest >> 24) & 
0xff)) != 0);
-}
-
-int
-ioapic_get_apr_lowpri(IOAPICState *s, int number)
-{
-    if(!s || !s->lapic_info[number]){
-        IOAPIC_ERR("ioapic_get_apr_lowpri NULL parameter\n");
-        return 0;
-    }
-    return s->lapic_info[number]->vl_arb_id;
-}
-
-uint32_t
-ioapic_get_delivery_bitmask(IOAPICState *s,
-uint8_t dest, uint8_t dest_mode, uint8_t vector, uint8_t delivery_mode)
-{
-    uint32_t mask = 0;
-    int low_priority = 256, selected = -1, i;
-    fprintf(logfile, "<ioapic_get_delivery_bitmask>: dest %d dest_mode %d"
-      "vector %d del_mode %d, lapic_count %d\n",
-      dest, dest_mode, vector, delivery_mode, s->lapic_count);
-    if (!s) return mask;
-    if (dest_mode == 0) { //Physical mode
-        if ((dest < s->lapic_count) && s->lapic_info[dest])
-            mask = 1 << dest;
-    }
-    else {
-        /* logical destination. call match_logical_addr for each APIC. */
-        if (dest == 0) return 0;
-        for (i=0; i< s->lapic_count; i++) {
-            //FIXME focus one, since no such issue on IPF, shoudl we add it?
-            if ( s->lapic_info[i] && ioapic_match_logical_addr(s, i, dest)){
-                if (delivery_mode != APIC_DM_LOWPRI)
-                    mask |= (1<<i);
-                else {
-                    if (low_priority > ioapic_get_apr_lowpri(s, i)){
-                        low_priority = ioapic_get_apr_lowpri(s, i);
-                        selected = i;
-                    }
-                    fprintf(logfile, "%d low_priority %d apr %d select %d\n",
-                      i, low_priority, ioapic_get_apr_lowpri(s, i), selected);
-                }
-            }
-        }
-        if (delivery_mode == APIC_DM_LOWPRI && (selected != -1)) 
-            mask |= (1<< selected);
-    }
-  return mask;
-}
-
-void
-ioapic_deliver(IOAPICState *s, int irqno){
-    uint8_t dest = s->redirtbl[irqno].RedirForm.dest_id;
-    uint8_t dest_mode = s->redirtbl[irqno].RedirForm.destmode;
-    uint8_t delivery_mode = s->redirtbl[irqno].RedirForm.deliver_mode;
-    uint8_t vector = s->redirtbl[irqno].RedirForm.vector;
-    uint8_t trig_mode = s->redirtbl[irqno].RedirForm.trigmod;
-    uint8_t bit;
-    uint32_t deliver_bitmask; 
-
-    IOAPIC_LOG("IOAPIC deliver: "
-      "dest %x dest_mode %x delivery_mode %x vector %x trig_mode %x\n",
-      dest, dest_mode, delivery_mode, vector, trig_mode);
-
-    deliver_bitmask =
-      ioapic_get_delivery_bitmask(s, dest, dest_mode, vector, delivery_mode);
-
-      IOAPIC_LOG("ioapic_get_delivery_bitmask return %x\n", deliver_bitmask);
-    if (!deliver_bitmask){
-        IOAPIC_ERR("Ioapic deliver, no target on destination\n");
-        return ;
-    }
-
-    switch (delivery_mode){
-        case VLAPIC_DELIV_MODE_FIXED:
-        case VLAPIC_DELIV_MODE_LPRI:
-        case VLAPIC_DELIV_MODE_EXT:
-            break;
-        case VLAPIC_DELIV_MODE_SMI:
-        case VLAPIC_DELIV_MODE_NMI:
-        case VLAPIC_DELIV_MODE_INIT:
-        case VLAPIC_DELIV_MODE_STARTUP:
-        default:
-            IOAPIC_ERR("Not support delivey mode %d\n", delivery_mode);
-            return ;
-    }
-
-    for (bit = 0; bit < s->lapic_count; bit++){
-        if (deliver_bitmask & (1 << bit)){
-            if (s->lapic_info[bit]){
-                ioapic_inj_irq(s, bit, vector, trig_mode, delivery_mode);
-            }
-        }
-    }
-}
-
-static inline int __fls(uint32_t word)
-{
-    int bit;
-    __asm__("bsrl %1,%0"
-      :"=r" (bit)
-      :"rm" (word));
-    return word ? bit : -1;
-}
-
-#if 0
-static __inline__ int find_highest_bit(unsigned long *data, int length){
-    while(length && !data[--length]);
-    return __fls(data[length]) +  32 * length;
-}
-#endif
-int
-ioapic_get_highest_irq(IOAPICState *s){
-    uint32_t irqs;
-    if (!s)
-        return -1;
-    irqs = s->irr & ~s->isr;
-    return __fls(irqs);
-}
-
-
-void
-service_ioapic(IOAPICState *s){
-    int irqno;
-
-    while((irqno = ioapic_get_highest_irq(s)) != -1){
-        IOAPIC_LOG("service_ioapic: highest irqno %x\n", irqno);
-
-        if (!s->redirtbl[irqno].RedirForm.mask)
-            ioapic_deliver(s, irqno);
-
-        if (s->redirtbl[irqno].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER){
-            s->isr |= (1 << irqno);
-        }
- //       clear_bit(irqno, &s->irr);
-        s->irr &= ~(1 << irqno);
-    }
-}
-
-void
-ioapic_update_irq(IOAPICState *s)
-{
-    s->INTR = 1;
-}
-
-void
-ioapic_set_irq(IOAPICState *s, int irq, int level)
-{
-    IOAPIC_LOG("ioapic_set_irq %x %x\n", irq, level);
-
-    /* Timer interrupt implemented on HV side */
-    if(irq == 0x0) return;
-    if (!s){
-        fprintf(logfile, "ioapic_set_irq null parameter\n");
-        return;
-    }
-    if (!IOAPICEnabled(s) || s->redirtbl[irq].RedirForm.mask)
-        return;
-#ifdef IOAPIC_DEBUG
-    ioapic_dump_redir(s, irq);
-#endif
-    if (irq >= 0 && irq < IOAPIC_NUM_PINS){
-        uint32_t bit = 1 << irq;
-        if (s->redirtbl[irq].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER){
-            if(level)
-                s->irr |= bit;
-            else
-                s->irr &= ~bit;
-        }else{
-            if(level)
-                /* XXX No irr clear for edge interrupt */
-                s->irr |= bit;
-        }
-    }
-
-    ioapic_update_irq(s);
-}
-
-void
-ioapic_legacy_irq(int irq, int level)
-{
-    ioapic_set_irq(ioapic, irq, level);
-}
-
-static inline int find_highest_bit(uint32_t *data, int length){
-        while(length && !data[--length]);
-            return __fls(data[length]) +  32 * length;
-}
-
-int
-get_redir_num(IOAPICState *s, int vector){
-    int i = 0;
-    if(!s){
-        IOAPIC_ERR("Null parameter for get_redir_num\n");
-        return -1;
-    }
-    for(; i < IOAPIC_NUM_PINS-1; i++){
-        if (s->redirtbl[i].RedirForm.vector == vector)
-            return i;
-    }
-    return -1;
-}
-
-void
-ioapic_update_EOI()
-{
-    int i = 0;
-    uint32_t isr_info ;
-    uint32_t vector;
-    IOAPICState *s = ioapic;
-
-    isr_info = s->isr;
-
-    for (i = 0; i < s->lapic_count; i++){
-        if (!s->lapic_info[i] ||
-          !test_bit(VL_STATE_EOI, s->lapic_info[i]->vl_state))
-            continue;
-        get_shareinfo_eoi(s->lapic_info[i]);
-        while((vector = find_highest_bit((unsigned int 
*)&s->lapic_info[i]->vl_eoi[0],VLAPIC_INT_COUNT_32)) != -1){
-            int redir_num;
-            if ((redir_num = get_redir_num(s, vector)) == -1){
-                IOAPIC_ERR("Can't find redir item for %d EOI \n", vector);
-                continue;
-            }
-            if (!test_and_clear_bit(redir_num, &s->isr)){
-                IOAPIC_ERR("redir %d not set for %d  EOI\n", redir_num, 
vector);
-                continue;
-            }
-            clear_bit(vector, &s->lapic_info[i]->vl_eoi[0]); 
-        }
-        clear_bit(VL_STATE_EOI, &s->lapic_info[i]->vl_state);
-        put_shareinfo_eoi(s->lapic_info[i]);
-    }
-}
-
-
-void
-ioapic_init_apic_info(IOAPICState *s)
-{
-#ifdef IOAPIC_DEBUG
-    fprintf(logfile, "ioapic_init_apic_info\n");
-    if (!s)
-        return;
-#endif
-
-#if 0
-    if (!vio || !(vio->vl_number)){
-        fprintf(logfile, "null vio or o vl number\n");
-        return;
-    }
-
-    for (i = 0; i < MAX_LAPIC_NUM; i++) s->lapic_info[i] = NULL;
-
-    s->lapic_count = vio->vl_number;
-    for (i = 0; i < vio->vl_number; i++)
-        s->lapic_info[i] = vio->vl_info + i;
-#endif
-
-}
-
-void
-ioapic_intack(IOAPICState *s)
-{
-#ifdef IOAPIC_DEBUG
-    if (!s){
-        fprintf(logfile, "ioapic_intack null parameter\n");
-        return;
-    }
-#endif
-    if (!s) s->INTR = 0;
-}
-
-int
-ioapic_has_intr()
-{
-    return ioapic->INTR;
-}
-
-void
-do_ioapic()
-{
-    service_ioapic(ioapic);
-    ioapic_intack(ioapic);
-}
-
-IOAPICState *
-IOAPICInit( )
-{
-    IOAPICState *s;
-
-    s = qemu_mallocz(sizeof(IOAPICState));
-    if (!s){
-        fprintf(logfile, "IOAPICInit: malloc failed\n");
-        return NULL;
-    }
-
-    IOAPICReset(s);
-    ioapic_init_apic_info(s);
-    register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s);
-    /* Remove after GFW ready */
-    ioapic_update_config(s, 0xfec00000, 1);
-
-    ioapic = s;
-    return s;
-}
diff -r d51b071bfcfc -r 66dd96e90be4 tools/ioemu/hw/ioapic.h
--- a/tools/ioemu/hw/ioapic.h   Mon Nov  7 22:53:25 2005
+++ /dev/null   Tue Nov  8 02:40:31 2005
@@ -1,128 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-
-#ifndef __IOAPIC_H
-#define __IOAPIC_H
-
-#include <xenctrl.h>
-#include <xen/io/ioreq.h>
-#include <xen/io/vmx_vlapic.h>
-
-#define IOAPIC_NUM_PINS 24
-#define IOAPIC_VERSION_ID 0x11
-#define IOAPIC_LEVEL_TRIGGER 1
-#define APIC_DM_FIXED  0
-#define APIC_DM_LOWPRI 1
-
-
-
-#ifdef CONFIG_SMP
-#define LOCK_PREFIX "lock ; "
-#else
-#define LOCK_PREFIX ""
-#endif
-
-#ifdef __I386__
-#define __OS "q" 
-#define __OP "r" 
-#else
-#define __OS "l"  /* Operation Suffix */
-#define __OP "e"  /* Operand Prefix */
-#endif
-
-#define ADDR (*(volatile long *) addr)
-#if 0
-#endif
-extern void *shared_page;
-extern FILE *logfile;
-#ifdef __BIGENDIAN__
-typedef union RedirStatus
-{
-    uint64_t value;
-    struct {
-        uint8_t dest_id;
-        uint8_t reserved[4];
-        uint8_t reserve:7;
-        uint8_t mask:1;         /* interrupt mask*/
-        uint8_t trigmod:1;
-        uint8_t remoteirr:1;
-        uint8_t polarity:1;
-        uint8_t delivestatus:1;
-        uint8_t destmode:1;
-        uint8_t deliver_mode:3;
-        uint8_t vector;
-    }RedirForm;
-}RedirStatus;
-#else
-typedef union RedirStatus
-{
-    uint64_t value;
-    struct {
-        uint8_t vector;
-        uint8_t deliver_mode:3;
-        uint8_t destmode:1;
-        uint8_t delivestatus:1;
-        uint8_t polarity:1;
-        uint8_t remoteirr:1;
-        uint8_t trigmod:1;
-        uint8_t mask:1;         /* interrupt mask*/
-        uint8_t reserve:7;
-        uint8_t reserved[4];
-        uint8_t dest_id;
-    }RedirForm;
-}RedirStatus;
-#endif
-/*
- * IOAPICState stands for a instance of a IOAPIC
- */
-
-/* FIXME tmp before working with Local APIC */
-#define IOAPIC_MEM_LENGTH 0x100
-#define IOAPIC_ENABLE_MASK 0x0
-#define IOAPIC_ENABLE_FLAG (1 << IOAPIC_ENABLE_MASK)
-#define MAX_LAPIC_NUM 32
-
-struct IOAPICState{
-    uint32_t INTR;
-    uint32_t id;
-    uint32_t arb_id;
-    uint32_t  flags;
-    unsigned long base_address;
-    uint32_t irr;
-    uint32_t isr;           /* This is used for level trigger */
-    uint8_t  vector_irr[256];
-    RedirStatus redirtbl[IOAPIC_NUM_PINS];
-    uint32_t ioregsel;
-    uint32_t lapic_count;
-    vlapic_info *lapic_info[MAX_LAPIC_NUM];
-};
-#define IOAPIC_REG_APIC_ID 0x0
-#define IOAPIC_REG_VERSION 0x1
-#define IOAPIC_REG_ARB_ID  0x2
-#define IOAPICEnabled(s) (s->flags & IOAPIC_ENABLE_FLAG)
-
-typedef struct IOAPICState IOAPICState;
-
-#endif

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Merge xen-unstable into xen-ia64-unstable again (to get ioapic changes), Xen patchbot -unstable <=