# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID 055efdd6b7c5ed07ac6903923634637793ff9106
# Parent 7e3faea076ecf7865538f3ce59b196d39ceccd6d
# Parent 25599e222c333565208c77c0d875bd56d6c719ef
Merged.
diff -r 7e3faea076ec -r 055efdd6b7c5
linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c Tue Nov 8 02:34:23 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c Tue Nov 8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5
linux-2.6-xen-sparse/arch/xen/i386/mm/init.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c Tue Nov 8 02:34:23 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c Tue Nov 8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5
linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c Tue Nov 8 02:34:23 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c Tue Nov 8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Tue Nov 8 02:34:23 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Tue Nov 8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5
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 Tue Nov 8
02:34:23 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mmu.h Tue Nov 8
02:35:25 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 7e3faea076ec -r 055efdd6b7c5
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 Tue Nov
8 02:34:23 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mmu_context.h Tue Nov
8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5
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 Tue Nov 8
02:34:23 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgalloc.h Tue Nov 8
02:35:25 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 7e3faea076ec -r 055efdd6b7c5 xen/arch/x86/dm/i8259.c
--- a/xen/arch/x86/dm/i8259.c Tue Nov 8 02:34:23 2005
+++ b/xen/arch/x86/dm/i8259.c Tue Nov 8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5 xen/arch/x86/vmx_intercept.c
--- a/xen/arch/x86/vmx_intercept.c Tue Nov 8 02:34:23 2005
+++ b/xen/arch/x86/vmx_intercept.c Tue Nov 8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5 xen/arch/x86/vmx_vlapic.c
--- a/xen/arch/x86/vmx_vlapic.c Tue Nov 8 02:34:23 2005
+++ b/xen/arch/x86/vmx_vlapic.c Tue Nov 8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5 xen/arch/x86/vmx_vmcs.c
--- a/xen/arch/x86/vmx_vmcs.c Tue Nov 8 02:34:23 2005
+++ b/xen/arch/x86/vmx_vmcs.c Tue Nov 8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5 xen/include/asm-x86/vmx_intercept.h
--- a/xen/include/asm-x86/vmx_intercept.h Tue Nov 8 02:34:23 2005
+++ b/xen/include/asm-x86/vmx_intercept.h Tue Nov 8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5 xen/include/asm-x86/vmx_platform.h
--- a/xen/include/asm-x86/vmx_platform.h Tue Nov 8 02:34:23 2005
+++ b/xen/include/asm-x86/vmx_platform.h Tue Nov 8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5 xen/include/asm-x86/vmx_vlapic.h
--- a/xen/include/asm-x86/vmx_vlapic.h Tue Nov 8 02:34:23 2005
+++ b/xen/include/asm-x86/vmx_vlapic.h Tue Nov 8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5 xen/include/asm-x86/vmx_vmcs.h
--- a/xen/include/asm-x86/vmx_vmcs.h Tue Nov 8 02:34:23 2005
+++ b/xen/include/asm-x86/vmx_vmcs.h Tue Nov 8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5 xen/arch/x86/dm/vmx_vioapic.c
--- /dev/null Tue Nov 8 02:34:23 2005
+++ b/xen/arch/x86/dm/vmx_vioapic.c Tue Nov 8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5 xen/include/asm-x86/vmx_vioapic.h
--- /dev/null Tue Nov 8 02:34:23 2005
+++ b/xen/include/asm-x86/vmx_vioapic.h Tue Nov 8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5 tools/ioemu/hw/ioapic.c
--- a/tools/ioemu/hw/ioapic.c Tue Nov 8 02:34:23 2005
+++ /dev/null Tue Nov 8 02:35:25 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 7e3faea076ec -r 055efdd6b7c5 tools/ioemu/hw/ioapic.h
--- a/tools/ioemu/hw/ioapic.h Tue Nov 8 02:34:23 2005
+++ /dev/null Tue Nov 8 02:35:25 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
|