ia64/xen-unstable

changeset 7663:66dd96e90be4

Merge xen-unstable into xen-ia64-unstable again (to get ioapic changes)
author djm@kirby.fc.hp.com
date Mon Nov 07 20:40:31 2005 -0600 (2005-11-07)
parents d51b071bfcfc 25599e222c33
children 7d81d6b8c302 0aeb37de0e4a
files
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c	Mon Nov 07 16:53:25 2005 -0600
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c	Mon Nov 07 20:40:31 2005 -0600
     1.3 @@ -18,7 +18,6 @@
     1.4  #include <asm/system.h>
     1.5  #include <asm/ldt.h>
     1.6  #include <asm/desc.h>
     1.7 -#include <asm/mmu_context.h>
     1.8  
     1.9  #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
    1.10  static void flush_ldt(void *null)
    1.11 @@ -101,19 +100,14 @@ int init_new_context(struct task_struct 
    1.12  	struct mm_struct * old_mm;
    1.13  	int retval = 0;
    1.14  
    1.15 -	memset(&mm->context, 0, sizeof(mm->context));
    1.16  	init_MUTEX(&mm->context.sem);
    1.17 +	mm->context.size = 0;
    1.18  	old_mm = current->mm;
    1.19  	if (old_mm && old_mm->context.size > 0) {
    1.20  		down(&old_mm->context.sem);
    1.21  		retval = copy_ldt(&mm->context, &old_mm->context);
    1.22  		up(&old_mm->context.sem);
    1.23  	}
    1.24 -	if (retval == 0) {
    1.25 -		spin_lock(&mm_unpinned_lock);
    1.26 -		list_add(&mm->context.unpinned, &mm_unpinned);
    1.27 -		spin_unlock(&mm_unpinned_lock);
    1.28 -	}
    1.29  	return retval;
    1.30  }
    1.31  
    1.32 @@ -134,11 +128,6 @@ void destroy_context(struct mm_struct *m
    1.33  			kfree(mm->context.ldt);
    1.34  		mm->context.size = 0;
    1.35  	}
    1.36 -	if (!mm->context.pinned) {
    1.37 -		spin_lock(&mm_unpinned_lock);
    1.38 -		list_del(&mm->context.unpinned);
    1.39 -		spin_unlock(&mm_unpinned_lock);
    1.40 -	}
    1.41  }
    1.42  
    1.43  static int read_ldt(void __user * ptr, unsigned long bytecount)
     2.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c	Mon Nov 07 16:53:25 2005 -0600
     2.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c	Mon Nov 07 20:40:31 2005 -0600
     2.3 @@ -376,7 +376,6 @@ static void __init pagetable_init (void)
     2.4  		__PAGE_KERNEL_EXEC |= _PAGE_GLOBAL;
     2.5  	}
     2.6  
     2.7 -	init_mm.context.pinned = 1;
     2.8  	kernel_physical_mapping_init(pgd_base);
     2.9  	remap_numa_kva();
    2.10  
    2.11 @@ -689,6 +688,8 @@ void __init mem_init(void)
    2.12  #ifndef CONFIG_SMP
    2.13  	zap_low_mappings();
    2.14  #endif
    2.15 +
    2.16 +	set_bit(PG_pinned, &virt_to_page(init_mm.pgd)->flags);
    2.17  }
    2.18  
    2.19  kmem_cache_t *pgd_cache;
     3.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c	Mon Nov 07 16:53:25 2005 -0600
     3.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c	Mon Nov 07 20:40:31 2005 -0600
     3.3 @@ -27,6 +27,9 @@
     3.4  #include <asm-xen/foreign_page.h>
     3.5  #include <asm/hypervisor.h>
     3.6  
     3.7 +static void __pgd_pin(pgd_t *pgd);
     3.8 +static void __pgd_unpin(pgd_t *pgd);
     3.9 +
    3.10  void show_mem(void)
    3.11  {
    3.12  	int total = 0, reserved = 0;
    3.13 @@ -299,6 +302,8 @@ void pgd_dtor(void *pgd, kmem_cache_t *c
    3.14  {
    3.15  	unsigned long flags; /* can be called from interrupt context */
    3.16  
    3.17 +	BUG_ON(test_bit(PG_pinned, &virt_to_page(pgd)->flags));
    3.18 +
    3.19  	if (HAVE_SHARED_KERNEL_PMD)
    3.20  		return;
    3.21  
    3.22 @@ -312,6 +317,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
    3.23  	int i = 0;
    3.24  	pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
    3.25  
    3.26 +	BUG_ON(test_bit(PG_pinned, &virt_to_page(pgd)->flags));
    3.27 +
    3.28  	if (PTRS_PER_PMD == 1 || !pgd)
    3.29  		return pgd;
    3.30  
    3.31 @@ -351,15 +358,9 @@ out_oom:
    3.32  void pgd_free(pgd_t *pgd)
    3.33  {
    3.34  	int i;
    3.35 -	pte_t *ptep = virt_to_ptep(pgd);
    3.36  
    3.37 -	if (!pte_write(*ptep)) {
    3.38 -		xen_pgd_unpin(__pa(pgd));
    3.39 -		BUG_ON(HYPERVISOR_update_va_mapping(
    3.40 -			(unsigned long)pgd,
    3.41 -			pfn_pte(virt_to_phys(pgd)>>PAGE_SHIFT, PAGE_KERNEL),
    3.42 -			0));
    3.43 -	}
    3.44 +	if (test_bit(PG_pinned, &virt_to_page(pgd)->flags))
    3.45 +		__pgd_unpin(pgd);
    3.46  
    3.47  	/* in the PAE case user pgd entries are overwritten before usage */
    3.48  	if (PTRS_PER_PMD > 1) {
    3.49 @@ -441,10 +442,7 @@ void make_pages_writable(void *va, unsig
    3.50  }
    3.51  #endif /* CONFIG_XEN_SHADOW_MODE */
    3.52  
    3.53 -LIST_HEAD(mm_unpinned);
    3.54 -DEFINE_SPINLOCK(mm_unpinned_lock);
    3.55 -
    3.56 -static inline void mm_walk_set_prot(void *pt, pgprot_t flags)
    3.57 +static inline void pgd_walk_set_prot(void *pt, pgprot_t flags)
    3.58  {
    3.59  	struct page *page = virt_to_page(pt);
    3.60  	unsigned long pfn = page_to_pfn(page);
    3.61 @@ -456,103 +454,111 @@ static inline void mm_walk_set_prot(void
    3.62  		pfn_pte(pfn, flags), 0));
    3.63  }
    3.64  
    3.65 -static void mm_walk(struct mm_struct *mm, pgprot_t flags)
    3.66 +static void pgd_walk(pgd_t *pgd_base, pgprot_t flags)
    3.67  {
    3.68 -	pgd_t       *pgd;
    3.69 -	pud_t       *pud;
    3.70 -	pmd_t       *pmd;
    3.71 -	pte_t       *pte;
    3.72 -	int          g,u,m;
    3.73 +	pgd_t *pgd = pgd_base;
    3.74 +	pud_t *pud;
    3.75 +	pmd_t *pmd;
    3.76 +	pte_t *pte;
    3.77 +	int    g, u, m;
    3.78  
    3.79 -	pgd = mm->pgd;
    3.80  	for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
    3.81  		if (pgd_none(*pgd))
    3.82  			continue;
    3.83  		pud = pud_offset(pgd, 0);
    3.84  		if (PTRS_PER_PUD > 1) /* not folded */
    3.85 -			mm_walk_set_prot(pud,flags);
    3.86 +			pgd_walk_set_prot(pud,flags);
    3.87  		for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
    3.88  			if (pud_none(*pud))
    3.89  				continue;
    3.90  			pmd = pmd_offset(pud, 0);
    3.91  			if (PTRS_PER_PMD > 1) /* not folded */
    3.92 -				mm_walk_set_prot(pmd,flags);
    3.93 +				pgd_walk_set_prot(pmd,flags);
    3.94  			for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
    3.95  				if (pmd_none(*pmd))
    3.96  					continue;
    3.97  				pte = pte_offset_kernel(pmd,0);
    3.98 -				mm_walk_set_prot(pte,flags);
    3.99 +				pgd_walk_set_prot(pte,flags);
   3.100  			}
   3.101  		}
   3.102  	}
   3.103 +
   3.104 +	BUG_ON(HYPERVISOR_update_va_mapping(
   3.105 +		(unsigned long)pgd_base,
   3.106 +		pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
   3.107 +		UVMF_TLB_FLUSH));
   3.108 +}
   3.109 +
   3.110 +static void __pgd_pin(pgd_t *pgd)
   3.111 +{
   3.112 +	pgd_walk(pgd, PAGE_KERNEL_RO);
   3.113 +	xen_pgd_pin(__pa(pgd));
   3.114 +	set_bit(PG_pinned, &virt_to_page(pgd)->flags);
   3.115 +}
   3.116 +
   3.117 +static void __pgd_unpin(pgd_t *pgd)
   3.118 +{
   3.119 +	xen_pgd_unpin(__pa(pgd));
   3.120 +	pgd_walk(pgd, PAGE_KERNEL);
   3.121 +	clear_bit(PG_pinned, &virt_to_page(pgd)->flags);
   3.122  }
   3.123  
   3.124  void mm_pin(struct mm_struct *mm)
   3.125  {
   3.126 -    spin_lock(&mm->page_table_lock);
   3.127 -
   3.128 -    mm_walk(mm, PAGE_KERNEL_RO);
   3.129 -    BUG_ON(HYPERVISOR_update_va_mapping(
   3.130 -        (unsigned long)mm->pgd,
   3.131 -        pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL_RO),
   3.132 -        UVMF_TLB_FLUSH));
   3.133 -    xen_pgd_pin(__pa(mm->pgd));
   3.134 -    mm->context.pinned = 1;
   3.135 -    spin_lock(&mm_unpinned_lock);
   3.136 -    list_del(&mm->context.unpinned);
   3.137 -    spin_unlock(&mm_unpinned_lock);
   3.138 -
   3.139 -    spin_unlock(&mm->page_table_lock);
   3.140 +	spin_lock(&mm->page_table_lock);
   3.141 +	__pgd_pin(mm->pgd);
   3.142 +	spin_unlock(&mm->page_table_lock);
   3.143  }
   3.144  
   3.145  void mm_unpin(struct mm_struct *mm)
   3.146  {
   3.147 -    spin_lock(&mm->page_table_lock);
   3.148 -
   3.149 -    xen_pgd_unpin(__pa(mm->pgd));
   3.150 -    BUG_ON(HYPERVISOR_update_va_mapping(
   3.151 -        (unsigned long)mm->pgd,
   3.152 -        pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL), 0));
   3.153 -    mm_walk(mm, PAGE_KERNEL);
   3.154 -    xen_tlb_flush();
   3.155 -    mm->context.pinned = 0;
   3.156 -    spin_lock(&mm_unpinned_lock);
   3.157 -    list_add(&mm->context.unpinned, &mm_unpinned);
   3.158 -    spin_unlock(&mm_unpinned_lock);
   3.159 -
   3.160 -    spin_unlock(&mm->page_table_lock);
   3.161 +	spin_lock(&mm->page_table_lock);
   3.162 +	__pgd_unpin(mm->pgd);
   3.163 +	spin_unlock(&mm->page_table_lock);
   3.164  }
   3.165  
   3.166  void mm_pin_all(void)
   3.167  {
   3.168 -    while (!list_empty(&mm_unpinned))	
   3.169 -	mm_pin(list_entry(mm_unpinned.next, struct mm_struct,
   3.170 -			  context.unpinned));
   3.171 +	struct page *page;
   3.172 +	for (page = pgd_list; page; page = (struct page *)page->index) {
   3.173 +		if (!test_bit(PG_pinned, &page->flags))
   3.174 +			__pgd_pin((pgd_t *)page_address(page));
   3.175 +	}
   3.176  }
   3.177  
   3.178  void _arch_exit_mmap(struct mm_struct *mm)
   3.179  {
   3.180 -    struct task_struct *tsk = current;
   3.181 -
   3.182 -    task_lock(tsk);
   3.183 +	struct task_struct *tsk = current;
   3.184  
   3.185 -    /*
   3.186 -     * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
   3.187 -     * *much* faster this way, as no tlb flushes means bigger wrpt batches.
   3.188 -     */
   3.189 -    if ( tsk->active_mm == mm )
   3.190 -    {
   3.191 -        tsk->active_mm = &init_mm;
   3.192 -        atomic_inc(&init_mm.mm_count);
   3.193 +	task_lock(tsk);
   3.194  
   3.195 -        switch_mm(mm, &init_mm, tsk);
   3.196 +	/*
   3.197 +	 * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
   3.198 +	 * *much* faster this way, as no tlb flushes means bigger wrpt batches.
   3.199 +	 */
   3.200 +	if (tsk->active_mm == mm) {
   3.201 +		tsk->active_mm = &init_mm;
   3.202 +		atomic_inc(&init_mm.mm_count);
   3.203  
   3.204 -        atomic_dec(&mm->mm_count);
   3.205 -        BUG_ON(atomic_read(&mm->mm_count) == 0);
   3.206 -    }
   3.207 +		switch_mm(mm, &init_mm, tsk);
   3.208  
   3.209 -    task_unlock(tsk);
   3.210 +		atomic_dec(&mm->mm_count);
   3.211 +		BUG_ON(atomic_read(&mm->mm_count) == 0);
   3.212 +	}
   3.213  
   3.214 -    if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) )
   3.215 -        mm_unpin(mm);
   3.216 +	task_unlock(tsk);
   3.217 +
   3.218 +	if (test_bit(PG_pinned, &virt_to_page(mm->pgd)->flags) &&
   3.219 +	    (atomic_read(&mm->mm_count) == 1))
   3.220 +		mm_unpin(mm);
   3.221  }
   3.222 +
   3.223 +/*
   3.224 + * Local variables:
   3.225 + *  c-file-style: "linux"
   3.226 + *  indent-tabs-mode: t
   3.227 + *  c-indent-level: 8
   3.228 + *  c-basic-offset: 8
   3.229 + *  tab-width: 8
   3.230 + * End:
   3.231 + */
     4.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Mon Nov 07 16:53:25 2005 -0600
     4.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Mon Nov 07 20:40:31 2005 -0600
     4.3 @@ -129,8 +129,8 @@ static int __do_suspend(void *ignore)
     4.4  	preempt_disable();
     4.5  
     4.6  #ifdef __i386__
     4.7 +	kmem_cache_shrink(pgd_cache);
     4.8  	mm_pin_all();
     4.9 -	kmem_cache_shrink(pgd_cache);
    4.10  #endif
    4.11  
    4.12  	__cli();
     5.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mmu.h	Mon Nov 07 16:53:25 2005 -0600
     5.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mmu.h	Mon Nov 07 20:40:31 2005 -0600
     5.3 @@ -12,13 +12,8 @@ typedef struct {
     5.4  	int size;
     5.5  	struct semaphore sem;
     5.6  	void *ldt;
     5.7 -	unsigned pinned:1;
     5.8 -	struct list_head unpinned;
     5.9  } mm_context_t;
    5.10  
    5.11 -extern struct list_head mm_unpinned;
    5.12 -extern spinlock_t mm_unpinned_lock;
    5.13 -
    5.14  /* mm/memory.c:exit_mmap hook */
    5.15  extern void _arch_exit_mmap(struct mm_struct *mm);
    5.16  #define arch_exit_mmap(_mm) _arch_exit_mmap(_mm)
     6.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mmu_context.h	Mon Nov 07 16:53:25 2005 -0600
     6.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mmu_context.h	Mon Nov 07 20:40:31 2005 -0600
     6.3 @@ -53,7 +53,7 @@ static inline void switch_mm(struct mm_s
     6.4  	struct mmuext_op _op[2], *op = _op;
     6.5  
     6.6  	if (likely(prev != next)) {
     6.7 -		if (!next->context.pinned)
     6.8 +		if (!test_bit(PG_pinned, &virt_to_page(next->pgd)->flags))
     6.9  			mm_pin(next);
    6.10  
    6.11  		/* stop flush ipis for the previous mm */
     7.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgalloc.h	Mon Nov 07 16:53:25 2005 -0600
     7.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgalloc.h	Mon Nov 07 20:40:31 2005 -0600
     7.3 @@ -7,12 +7,15 @@
     7.4  #include <linux/mm.h>		/* for struct page */
     7.5  #include <asm/io.h>		/* for phys_to_virt and page_to_pseudophys */
     7.6  
     7.7 +/* Is this pagetable pinned? */
     7.8 +#define PG_pinned	PG_arch_1
     7.9 +
    7.10  #define pmd_populate_kernel(mm, pmd, pte) \
    7.11  		set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
    7.12  
    7.13  #define pmd_populate(mm, pmd, pte) 					\
    7.14  do {									\
    7.15 -	if (unlikely((mm)->context.pinned)) {				\
    7.16 +	if (test_bit(PG_pinned, &virt_to_page((mm)->pgd)->flags)) {	\
    7.17  		if (!PageHighMem(pte))					\
    7.18  			BUG_ON(HYPERVISOR_update_va_mapping(		\
    7.19  			  (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT),\
     8.1 --- a/tools/ioemu/hw/ioapic.c	Mon Nov 07 16:53:25 2005 -0600
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,704 +0,0 @@
     8.4 -/////////////////////////////////////////////////////////////////////////
     8.5 -//
     8.6 -//  Copyright (C) 2001  MandrakeSoft S.A.
     8.7 -//
     8.8 -//    MandrakeSoft S.A.
     8.9 -//    43, rue d'Aboukir
    8.10 -//    75002 Paris - France
    8.11 -//    http://www.linux-mandrake.com/
    8.12 -//    http://www.mandrakesoft.com/
    8.13 -//
    8.14 -//  This library is free software; you can redistribute it and/or
    8.15 -//  modify it under the terms of the GNU Lesser General Public
    8.16 -//  License as published by the Free Software Foundation; either
    8.17 -//  version 2 of the License, or (at your option) any later version.
    8.18 -//
    8.19 -//  This library is distributed in the hope that it will be useful,
    8.20 -//  but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.21 -//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    8.22 -//  Lesser General Public License for more details.
    8.23 -//
    8.24 -//  You should have received a copy of the GNU Lesser General Public
    8.25 -//  License along with this library; if not, write to the Free Software
    8.26 -//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    8.27 -//
    8.28 -
    8.29 -#include "vl.h"
    8.30 -#include "ioapic.h"
    8.31 -
    8.32 -#ifdef __OS
    8.33 -#undef __OS
    8.34 -#endif
    8.35 -#ifdef __i386__
    8.36 -#define __OS	"l"
    8.37 -#else
    8.38 -#define __OS "q"
    8.39 -#endif
    8.40 -#define ADDR (*(volatile long *) addr)
    8.41 -
    8.42 -#ifdef IOAPIC_DEBUG
    8.43 -#define IOAPIC_LOG(a...) fprintf(logfile, ##a)
    8.44 -#else
    8.45 -#define IOAPIC_LOG(a...)
    8.46 -#endif
    8.47 -
    8.48 -static IOAPICState *ioapic;
    8.49 -
    8.50 -#define IOAPIC_ERR(a...) fprintf(logfile, ##a)
    8.51 -static __inline__ int test_and_set_bit(long nr, volatile void * addr)
    8.52 -{
    8.53 -	long oldbit;
    8.54 -
    8.55 -	__asm__ __volatile__( 
    8.56 -		"bts"__OS" %2,%1\n\tsbb"__OS" %0,%0"
    8.57 -		:"=r" (oldbit),"=m" (ADDR)
    8.58 -		:"Ir" (nr) : "memory");
    8.59 -	return oldbit;
    8.60 -}
    8.61 -
    8.62 -static __inline__ int test_and_clear_bit(long nr, volatile void * addr)
    8.63 -{
    8.64 -	long oldbit;
    8.65 -
    8.66 -	__asm__ __volatile__( LOCK_PREFIX
    8.67 -		"btr"__OS" %2,%1\n\tsbb"__OS" %0,%0"
    8.68 -		:"=r" (oldbit),"=m" (ADDR)
    8.69 -		:"dIr" (nr) : "memory");
    8.70 -	return oldbit;
    8.71 -}
    8.72 -
    8.73 -static __inline__ void clear_bit(long nr, volatile void * addr)
    8.74 -{
    8.75 -	__asm__ __volatile__( 
    8.76 -		"btr"__OS" %1,%0"
    8.77 -		:"=m" (ADDR)
    8.78 -		:"Ir" (nr));
    8.79 -}
    8.80 -
    8.81 -static inline
    8.82 -void get_shareinfo_apic_msg(vlapic_info *share_info){
    8.83 -    while(test_and_set_bit(VL_STATE_MSG_LOCK, &share_info->vl_state)){};
    8.84 -}
    8.85 -
    8.86 -static inline
    8.87 -void put_shareinfo_apic_msg(vlapic_info *share_info){
    8.88 -    clear_bit(VL_STATE_MSG_LOCK, &share_info->vl_state);
    8.89 -}
    8.90 -static inline
    8.91 -void get_shareinfo_eoi(vlapic_info *share_info){
    8.92 -    while(test_and_set_bit(VL_STATE_EOI_LOCK, &share_info->vl_state)){};
    8.93 -}
    8.94 -
    8.95 -static inline
    8.96 -void put_shareinfo_eoi(vlapic_info *share_info){
    8.97 -    clear_bit(VL_STATE_EOI_LOCK, &share_info->vl_state);
    8.98 -}
    8.99 -
   8.100 -
   8.101 -static inline
   8.102 -void get_shareinfo_ext(vlapic_info *share_info){
   8.103 -    while(test_and_set_bit(VL_STATE_EXT_LOCK, &share_info->vl_state));
   8.104 -}
   8.105 -
   8.106 -static inline
   8.107 -void put_shareinfo_ext(vlapic_info *share_info){
   8.108 -    clear_bit(VL_STATE_EXT_LOCK, &share_info->vl_state);
   8.109 -}
   8.110 -
   8.111 -
   8.112 -static __inline__ int test_bit(int nr, uint32_t value){
   8.113 -    return value & (1 << nr);
   8.114 -}
   8.115 -
   8.116 -static void ioapic_enable(IOAPICState *s, uint8_t enable)
   8.117 -{
   8.118 -    if (!enable ^ IOAPICEnabled(s)) return;
   8.119 -    if(enable)
   8.120 -        s->flags |= IOAPIC_ENABLE_FLAG;
   8.121 -    else
   8.122 -        s->flags &= ~IOAPIC_ENABLE_FLAG;
   8.123 -}
   8.124 -
   8.125 -#ifdef IOAPIC_DEBUG
   8.126 -static void
   8.127 -ioapic_dump_redir(IOAPICState *s, uint8_t entry)
   8.128 -{
   8.129 -    if (!s)
   8.130 -        return;
   8.131 -
   8.132 -    RedirStatus redir = s->redirtbl[entry];
   8.133 -
   8.134 -    fprintf(logfile, "entry %x: "
   8.135 -      "vector %x deliver_mod %x destmode %x delivestatus %x "
   8.136 -      "polarity %x remote_irr %x trigmod %x mask %x dest_id %x\n",
   8.137 -      entry,
   8.138 -      redir.RedirForm.vector, redir.RedirForm.deliver_mode,
   8.139 -      redir.RedirForm.destmode, redir.RedirForm.delivestatus,
   8.140 -      redir.RedirForm.polarity, redir.RedirForm.remoteirr,
   8.141 -      redir.RedirForm.trigmod, redir.RedirForm.mask,
   8.142 -      redir.RedirForm.dest_id);
   8.143 -}
   8.144 -
   8.145 -static void
   8.146 -ioapic_dump_shareinfo(IOAPICState *s , int number)
   8.147 -{
   8.148 -    if (!s || !s->lapic_info[number])
   8.149 -        return;
   8.150 -    vlapic_info *m = s->lapic_info[number];
   8.151 -    IOAPIC_LOG("lapic_info %x : "
   8.152 -      "vl_lapic_id %x vl_logical_dest %x vl_dest_format %x vl_arb_id %x\n",
   8.153 -      number, m->vl_lapic_id, m->vl_logical_dest, m->vl_dest_format, m->vl_arb_id );
   8.154 -}
   8.155 -#endif
   8.156 -
   8.157 -static void
   8.158 -ioapic_save(QEMUFile* f,void* opaque)
   8.159 -{
   8.160 -    IOAPIC_ERR("no implementation for ioapic_save\n");
   8.161 -}
   8.162 -
   8.163 -static
   8.164 -int ioapic_load(QEMUFile* f,void* opaque,int version_id)
   8.165 -{
   8.166 -    IOAPIC_ERR("no implementation for ioapic_load\n");
   8.167 -    return 0;
   8.168 -}
   8.169 -
   8.170 -uint32_t
   8.171 -ioapic_mem_readb(void *opaque, target_phys_addr_t addr)
   8.172 -{
   8.173 -    IOAPIC_ERR("ioapic_mem_readb\n");
   8.174 -    return 0;
   8.175 -}
   8.176 -
   8.177 -uint32_t
   8.178 -ioapic_mem_readw(void *opaque, target_phys_addr_t addr)
   8.179 -{
   8.180 -    IOAPIC_ERR("ioapic_mem_readw\n");
   8.181 -    return 0;
   8.182 -}
   8.183 -
   8.184 -static
   8.185 -void ioapic_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
   8.186 -{
   8.187 -    IOAPIC_ERR("ioapic_mem_writeb\n");
   8.188 -}
   8.189 -
   8.190 -static
   8.191 -void ioapic_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
   8.192 -{
   8.193 -    IOAPIC_ERR("ioapic_mem_writew\n");
   8.194 -}
   8.195 -
   8.196 -static
   8.197 -uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr)
   8.198 -{
   8.199 -    unsigned short ioregsel;
   8.200 -    IOAPICState *s = opaque;
   8.201 -    uint32_t    result = 0;
   8.202 -    uint32_t    redir_index = 0;
   8.203 -    uint64_t    redir_content = 0;
   8.204 -
   8.205 -    IOAPIC_LOG("apic_mem_readl addr %x\n", addr);
   8.206 -    if (!s){
   8.207 -        IOAPIC_ERR("null pointer for apic_mem_readl\n");
   8.208 -        return result;
   8.209 -    }
   8.210 -
   8.211 -    addr &= 0xff;
   8.212 -    if(addr == 0x00){
   8.213 -        result = s->ioregsel;
   8.214 -        return result;
   8.215 -    }else if (addr != 0x10){
   8.216 -        IOAPIC_ERR("apic_mem_readl address error\n");
   8.217 -        return result;
   8.218 -    }
   8.219 -
   8.220 -    ioregsel = s->ioregsel;
   8.221 -
   8.222 -    switch (ioregsel){
   8.223 -        case IOAPIC_REG_APIC_ID:
   8.224 -            result = ((s->id & 0xf) << 24);
   8.225 -            break;
   8.226 -        case IOAPIC_REG_VERSION:
   8.227 -            result = ((((IOAPIC_NUM_PINS-1) & 0xff) << 16)  
   8.228 -                     | (IOAPIC_VERSION_ID & 0x0f));
   8.229 -            break;
   8.230 -        case IOAPIC_REG_ARB_ID:
   8.231 -            //FIXME
   8.232 -            result = ((s->id & 0xf) << 24);
   8.233 -            break;
   8.234 -        default:
   8.235 -            redir_index = (ioregsel - 0x10) >> 1;
   8.236 -            if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS){
   8.237 -               redir_content = s->redirtbl[redir_index].value;
   8.238 -               result = (ioregsel & 0x1)?
   8.239 -                        (redir_content >> 32) & 0xffffffff :
   8.240 -                        redir_content & 0xffffffff;
   8.241 -            }else{
   8.242 -                IOAPIC_ERR(
   8.243 -                  "upic_mem_readl:undefined ioregsel %x\n",
   8.244 -                  ioregsel);
   8.245 -            }
   8.246 -    }
   8.247 -    return result;
   8.248 -}
   8.249 -
   8.250 -static
   8.251 -void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
   8.252 -{
   8.253 -    IOAPICState *s = opaque;
   8.254 -    uint32_t redir_index = 0;
   8.255 -    uint64_t redir_content;
   8.256 -
   8.257 -    IOAPIC_LOG("apic_mem_writel addr %x val %x\n", addr, val);
   8.258 -
   8.259 -    if (!s){
   8.260 -        IOAPIC_ERR("apic_mem_writel: null opaque\n");
   8.261 -        return;
   8.262 -    }
   8.263 -
   8.264 -    addr &= 0xff;
   8.265 -    if (addr == 0x00){
   8.266 -        s->ioregsel = val;
   8.267 -        return;
   8.268 -    }else if (addr != 0x10){
   8.269 -        IOAPIC_ERR("apic_mem_writel: unsupported address\n");
   8.270 -    }
   8.271 -
   8.272 -    switch (s->ioregsel){
   8.273 -        case IOAPIC_REG_APIC_ID:
   8.274 -            s->id = (val >> 24) & 0xf;
   8.275 -            break;
   8.276 -        case IOAPIC_REG_VERSION:
   8.277 -            IOAPIC_ERR("apic_mem_writel: version register read only\n");
   8.278 -            break;
   8.279 -        case IOAPIC_REG_ARB_ID:
   8.280 -            s->arb_id = val;
   8.281 -            break;
   8.282 -        default:
   8.283 -            redir_index = (s->ioregsel - 0x10) >> 1;
   8.284 -//            IOAPIC_LOG("apic_mem_write: change redir :index %x before %lx, val %x\n", redir_index, s->redirtbl[redir_index].value, val);
   8.285 -            if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS){
   8.286 -                redir_content = s->redirtbl[redir_index].value;
   8.287 -                if (s->ioregsel & 0x1)
   8.288 -                   redir_content = (((uint64_t)val & 0xffffffff) << 32) | (redir_content & 0xffffffff);
   8.289 -                else
   8.290 -                    redir_content = ((redir_content >> 32) << 32) | (val & 0xffffffff);
   8.291 -                s->redirtbl[redir_index].value = redir_content;
   8.292 -            }else {
   8.293 -                IOAPIC_ERR("apic_mem_writel: error register\n");
   8.294 -            }
   8.295 -            //IOAPIC_LOG("after value is %lx\n",  s->redirtbl[redir_index].value);
   8.296 -    }
   8.297 -}
   8.298 -
   8.299 -static CPUReadMemoryFunc *ioapic_mem_read[3] = {
   8.300 -    ioapic_mem_readb,
   8.301 -    ioapic_mem_readw,
   8.302 -    ioapic_mem_readl,
   8.303 -};
   8.304 -
   8.305 -static CPUWriteMemoryFunc *ioapic_mem_write[3] = {
   8.306 -    ioapic_mem_writeb,
   8.307 -    ioapic_mem_writew,
   8.308 -    ioapic_mem_writel,
   8.309 -};
   8.310 -
   8.311 -void
   8.312 -IOAPICReset(IOAPICState *s)
   8.313 -{
   8.314 -    int i;
   8.315 -    if (!s)
   8.316 -        return ;
   8.317 -
   8.318 -    memset(s, 0, sizeof(IOAPICState));
   8.319 -
   8.320 -    for (i = 0; i < IOAPIC_NUM_PINS; i++)
   8.321 -        s->redirtbl[i].RedirForm.mask = 0x1;
   8.322 -//    IOAPIC_LOG("after Reset %lx\n",  s->redirtbl[0].value);
   8.323 -}
   8.324 -
   8.325 -void
   8.326 -ioapic_update_config(IOAPICState *s, unsigned long address, uint8_t enable)
   8.327 -{
   8.328 -    int ioapic_mem;
   8.329 -    if (!s)
   8.330 -       return;
   8.331 -
   8.332 -    ioapic_enable(s, enable);
   8.333 -
   8.334 -    if (address != s->base_address){
   8.335 -        ioapic_mem = cpu_register_io_memory(0, ioapic_mem_read, ioapic_mem_write, s);
   8.336 -        cpu_register_physical_memory(address, IOAPIC_MEM_LENGTH, ioapic_mem);
   8.337 -        s->base_address = ioapic_mem;
   8.338 -    }
   8.339 -}
   8.340 -
   8.341 -#define direct_intr(mode)   \
   8.342 -  (mode == VLAPIC_DELIV_MODE_SMI || \
   8.343 -   mode == VLAPIC_DELIV_MODE_NMI || \
   8.344 -   mode == VLAPIC_DELIV_MODE_INIT ||\
   8.345 -   mode == VLAPIC_DELIV_MODE_STARTUP)
   8.346 -
   8.347 -int
   8.348 -ioapic_inj_irq(IOAPICState *s, uint8_t dest, uint8_t vector, uint8_t trig_mode, uint8_t delivery_mode)
   8.349 -{
   8.350 -    int msg_count;
   8.351 -    if (!s || !s->lapic_info[dest]){
   8.352 -        IOAPIC_ERR("ioapic_inj_irq NULL parameter\n");
   8.353 -        return 0;
   8.354 -    }
   8.355 -    IOAPIC_LOG("ioapic_inj_irq %d , trig %d delive mode %d\n",
   8.356 -      vector, trig_mode, delivery_mode);
   8.357 -    switch(delivery_mode){
   8.358 -        case VLAPIC_DELIV_MODE_FIXED:
   8.359 -        case VLAPIC_DELIV_MODE_LPRI:
   8.360 -            get_shareinfo_apic_msg(s->lapic_info[dest]);
   8.361 -            msg_count = s->lapic_info[dest]->apic_msg_count;
   8.362 -            s->lapic_info[dest]->vl_apic_msg[msg_count].deliv_mode = delivery_mode;
   8.363 -            s->lapic_info[dest]->vl_apic_msg[msg_count].level = trig_mode;
   8.364 -            s->lapic_info[dest]->vl_apic_msg[msg_count].vector = vector;
   8.365 -            s->lapic_info[dest]->vl_apic_msg[msg_count].vector = vector;
   8.366 -            s->lapic_info[dest]->apic_msg_count ++;
   8.367 -            put_shareinfo_apic_msg(s->lapic_info[dest]);
   8.368 -            break;
   8.369 -        case VLAPIC_DELIV_MODE_EXT:
   8.370 -/*            get_shareinfo_ext(s->lapic_info[dest]);
   8.371 -            test_and_set_bit(vector, &s->lapic_info[dest]->vl_ext_intr[0]);
   8.372 -            put_shareinfo_ext(s->lapic_info[dest]);*/
   8.373 -            IOAPIC_ERR("<ioapic_inj_irq> Ext interrupt\n");
   8.374 -            return 0;
   8.375 -        default:
   8.376 -            IOAPIC_ERR("<ioapic_inj_irq> error delivery mode\n");
   8.377 -            break;
   8.378 -    }
   8.379 -    return 1;
   8.380 -}
   8.381 -
   8.382 -int
   8.383 -ioapic_match_logical_addr(IOAPICState *s, int number, uint8_t address)
   8.384 -{
   8.385 -    if(!s || !s->lapic_info[number]){
   8.386 -        IOAPIC_ERR("ioapic_match_logical_addr NULL parameter: "
   8.387 -          "number: %i s %p address %x\n",
   8.388 -          number, s, address);
   8.389 -        return 0;
   8.390 -    }
   8.391 -    IOAPIC_LOG("ioapic_match_logical_addr number %i address %x\n",
   8.392 -      number, address);
   8.393 -
   8.394 -    if (((s->lapic_info[number]->vl_dest_format >> 28 ) & 0xf) != 0xf) {
   8.395 -        IOAPIC_ERR("ioapic_match_logical_addr: cluster model not implemented still%x"
   8.396 -          ,s->lapic_info[number]->vl_dest_format);
   8.397 -#ifdef IOAPIC_DEBUG
   8.398 -        ioapic_dump_shareinfo(s, number);
   8.399 -#endif
   8.400 -        return 0;
   8.401 -    }
   8.402 -    return ((address & ((s->lapic_info[number]->vl_logical_dest >> 24) & 0xff)) != 0);
   8.403 -}
   8.404 -
   8.405 -int
   8.406 -ioapic_get_apr_lowpri(IOAPICState *s, int number)
   8.407 -{
   8.408 -    if(!s || !s->lapic_info[number]){
   8.409 -        IOAPIC_ERR("ioapic_get_apr_lowpri NULL parameter\n");
   8.410 -        return 0;
   8.411 -    }
   8.412 -    return s->lapic_info[number]->vl_arb_id;
   8.413 -}
   8.414 -
   8.415 -uint32_t
   8.416 -ioapic_get_delivery_bitmask(IOAPICState *s,
   8.417 -uint8_t dest, uint8_t dest_mode, uint8_t vector, uint8_t delivery_mode)
   8.418 -{
   8.419 -    uint32_t mask = 0;
   8.420 -    int low_priority = 256, selected = -1, i;
   8.421 -    fprintf(logfile, "<ioapic_get_delivery_bitmask>: dest %d dest_mode %d"
   8.422 -      "vector %d del_mode %d, lapic_count %d\n",
   8.423 -      dest, dest_mode, vector, delivery_mode, s->lapic_count);
   8.424 -    if (!s) return mask;
   8.425 -    if (dest_mode == 0) { //Physical mode
   8.426 -        if ((dest < s->lapic_count) && s->lapic_info[dest])
   8.427 -            mask = 1 << dest;
   8.428 -    }
   8.429 -    else {
   8.430 -        /* logical destination. call match_logical_addr for each APIC. */
   8.431 -        if (dest == 0) return 0;
   8.432 -        for (i=0; i< s->lapic_count; i++) {
   8.433 -            //FIXME focus one, since no such issue on IPF, shoudl we add it?
   8.434 -            if ( s->lapic_info[i] && ioapic_match_logical_addr(s, i, dest)){
   8.435 -                if (delivery_mode != APIC_DM_LOWPRI)
   8.436 -                    mask |= (1<<i);
   8.437 -                else {
   8.438 -                    if (low_priority > ioapic_get_apr_lowpri(s, i)){
   8.439 -                        low_priority = ioapic_get_apr_lowpri(s, i);
   8.440 -                        selected = i;
   8.441 -                    }
   8.442 -                    fprintf(logfile, "%d low_priority %d apr %d select %d\n",
   8.443 -                      i, low_priority, ioapic_get_apr_lowpri(s, i), selected);
   8.444 -                }
   8.445 -            }
   8.446 -        }
   8.447 -        if (delivery_mode == APIC_DM_LOWPRI && (selected != -1)) 
   8.448 -            mask |= (1<< selected);
   8.449 -    }
   8.450 -  return mask;
   8.451 -}
   8.452 -
   8.453 -void
   8.454 -ioapic_deliver(IOAPICState *s, int irqno){
   8.455 -    uint8_t dest = s->redirtbl[irqno].RedirForm.dest_id;
   8.456 -    uint8_t dest_mode = s->redirtbl[irqno].RedirForm.destmode;
   8.457 -    uint8_t delivery_mode = s->redirtbl[irqno].RedirForm.deliver_mode;
   8.458 -    uint8_t vector = s->redirtbl[irqno].RedirForm.vector;
   8.459 -    uint8_t trig_mode = s->redirtbl[irqno].RedirForm.trigmod;
   8.460 -    uint8_t bit;
   8.461 -    uint32_t deliver_bitmask; 
   8.462 -
   8.463 -    IOAPIC_LOG("IOAPIC deliver: "
   8.464 -      "dest %x dest_mode %x delivery_mode %x vector %x trig_mode %x\n",
   8.465 -      dest, dest_mode, delivery_mode, vector, trig_mode);
   8.466 -
   8.467 -    deliver_bitmask =
   8.468 -      ioapic_get_delivery_bitmask(s, dest, dest_mode, vector, delivery_mode);
   8.469 -
   8.470 -      IOAPIC_LOG("ioapic_get_delivery_bitmask return %x\n", deliver_bitmask);
   8.471 -    if (!deliver_bitmask){
   8.472 -        IOAPIC_ERR("Ioapic deliver, no target on destination\n");
   8.473 -        return ;
   8.474 -    }
   8.475 -
   8.476 -    switch (delivery_mode){
   8.477 -        case VLAPIC_DELIV_MODE_FIXED:
   8.478 -        case VLAPIC_DELIV_MODE_LPRI:
   8.479 -        case VLAPIC_DELIV_MODE_EXT:
   8.480 -            break;
   8.481 -        case VLAPIC_DELIV_MODE_SMI:
   8.482 -        case VLAPIC_DELIV_MODE_NMI:
   8.483 -        case VLAPIC_DELIV_MODE_INIT:
   8.484 -        case VLAPIC_DELIV_MODE_STARTUP:
   8.485 -        default:
   8.486 -            IOAPIC_ERR("Not support delivey mode %d\n", delivery_mode);
   8.487 -            return ;
   8.488 -    }
   8.489 -
   8.490 -    for (bit = 0; bit < s->lapic_count; bit++){
   8.491 -        if (deliver_bitmask & (1 << bit)){
   8.492 -            if (s->lapic_info[bit]){
   8.493 -                ioapic_inj_irq(s, bit, vector, trig_mode, delivery_mode);
   8.494 -            }
   8.495 -        }
   8.496 -    }
   8.497 -}
   8.498 -
   8.499 -static inline int __fls(uint32_t word)
   8.500 -{
   8.501 -    int bit;
   8.502 -    __asm__("bsrl %1,%0"
   8.503 -      :"=r" (bit)
   8.504 -      :"rm" (word));
   8.505 -    return word ? bit : -1;
   8.506 -}
   8.507 -
   8.508 -#if 0
   8.509 -static __inline__ int find_highest_bit(unsigned long *data, int length){
   8.510 -    while(length && !data[--length]);
   8.511 -    return __fls(data[length]) +  32 * length;
   8.512 -}
   8.513 -#endif
   8.514 -int
   8.515 -ioapic_get_highest_irq(IOAPICState *s){
   8.516 -    uint32_t irqs;
   8.517 -    if (!s)
   8.518 -        return -1;
   8.519 -    irqs = s->irr & ~s->isr;
   8.520 -    return __fls(irqs);
   8.521 -}
   8.522 -
   8.523 -
   8.524 -void
   8.525 -service_ioapic(IOAPICState *s){
   8.526 -    int irqno;
   8.527 -
   8.528 -    while((irqno = ioapic_get_highest_irq(s)) != -1){
   8.529 -        IOAPIC_LOG("service_ioapic: highest irqno %x\n", irqno);
   8.530 -
   8.531 -        if (!s->redirtbl[irqno].RedirForm.mask)
   8.532 -            ioapic_deliver(s, irqno);
   8.533 -
   8.534 -        if (s->redirtbl[irqno].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER){
   8.535 -            s->isr |= (1 << irqno);
   8.536 -        }
   8.537 - //       clear_bit(irqno, &s->irr);
   8.538 -        s->irr &= ~(1 << irqno);
   8.539 -    }
   8.540 -}
   8.541 -
   8.542 -void
   8.543 -ioapic_update_irq(IOAPICState *s)
   8.544 -{
   8.545 -    s->INTR = 1;
   8.546 -}
   8.547 -
   8.548 -void
   8.549 -ioapic_set_irq(IOAPICState *s, int irq, int level)
   8.550 -{
   8.551 -    IOAPIC_LOG("ioapic_set_irq %x %x\n", irq, level);
   8.552 -
   8.553 -    /* Timer interrupt implemented on HV side */
   8.554 -    if(irq == 0x0) return;
   8.555 -    if (!s){
   8.556 -        fprintf(logfile, "ioapic_set_irq null parameter\n");
   8.557 -        return;
   8.558 -    }
   8.559 -    if (!IOAPICEnabled(s) || s->redirtbl[irq].RedirForm.mask)
   8.560 -        return;
   8.561 -#ifdef IOAPIC_DEBUG
   8.562 -    ioapic_dump_redir(s, irq);
   8.563 -#endif
   8.564 -    if (irq >= 0 && irq < IOAPIC_NUM_PINS){
   8.565 -        uint32_t bit = 1 << irq;
   8.566 -        if (s->redirtbl[irq].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER){
   8.567 -            if(level)
   8.568 -                s->irr |= bit;
   8.569 -            else
   8.570 -                s->irr &= ~bit;
   8.571 -        }else{
   8.572 -            if(level)
   8.573 -                /* XXX No irr clear for edge interrupt */
   8.574 -                s->irr |= bit;
   8.575 -        }
   8.576 -    }
   8.577 -
   8.578 -    ioapic_update_irq(s);
   8.579 -}
   8.580 -
   8.581 -void
   8.582 -ioapic_legacy_irq(int irq, int level)
   8.583 -{
   8.584 -    ioapic_set_irq(ioapic, irq, level);
   8.585 -}
   8.586 -
   8.587 -static inline int find_highest_bit(uint32_t *data, int length){
   8.588 -        while(length && !data[--length]);
   8.589 -            return __fls(data[length]) +  32 * length;
   8.590 -}
   8.591 -
   8.592 -int
   8.593 -get_redir_num(IOAPICState *s, int vector){
   8.594 -    int i = 0;
   8.595 -    if(!s){
   8.596 -        IOAPIC_ERR("Null parameter for get_redir_num\n");
   8.597 -        return -1;
   8.598 -    }
   8.599 -    for(; i < IOAPIC_NUM_PINS-1; i++){
   8.600 -        if (s->redirtbl[i].RedirForm.vector == vector)
   8.601 -            return i;
   8.602 -    }
   8.603 -    return -1;
   8.604 -}
   8.605 -
   8.606 -void
   8.607 -ioapic_update_EOI()
   8.608 -{
   8.609 -    int i = 0;
   8.610 -    uint32_t isr_info ;
   8.611 -    uint32_t vector;
   8.612 -    IOAPICState *s = ioapic;
   8.613 -
   8.614 -    isr_info = s->isr;
   8.615 -
   8.616 -    for (i = 0; i < s->lapic_count; i++){
   8.617 -        if (!s->lapic_info[i] ||
   8.618 -          !test_bit(VL_STATE_EOI, s->lapic_info[i]->vl_state))
   8.619 -            continue;
   8.620 -        get_shareinfo_eoi(s->lapic_info[i]);
   8.621 -        while((vector = find_highest_bit((unsigned int *)&s->lapic_info[i]->vl_eoi[0],VLAPIC_INT_COUNT_32)) != -1){
   8.622 -            int redir_num;
   8.623 -            if ((redir_num = get_redir_num(s, vector)) == -1){
   8.624 -                IOAPIC_ERR("Can't find redir item for %d EOI \n", vector);
   8.625 -                continue;
   8.626 -            }
   8.627 -            if (!test_and_clear_bit(redir_num, &s->isr)){
   8.628 -                IOAPIC_ERR("redir %d not set for %d  EOI\n", redir_num, vector);
   8.629 -                continue;
   8.630 -            }
   8.631 -            clear_bit(vector, &s->lapic_info[i]->vl_eoi[0]); 
   8.632 -        }
   8.633 -        clear_bit(VL_STATE_EOI, &s->lapic_info[i]->vl_state);
   8.634 -        put_shareinfo_eoi(s->lapic_info[i]);
   8.635 -    }
   8.636 -}
   8.637 -
   8.638 -
   8.639 -void
   8.640 -ioapic_init_apic_info(IOAPICState *s)
   8.641 -{
   8.642 -#ifdef IOAPIC_DEBUG
   8.643 -    fprintf(logfile, "ioapic_init_apic_info\n");
   8.644 -    if (!s)
   8.645 -        return;
   8.646 -#endif
   8.647 -
   8.648 -#if 0
   8.649 -    if (!vio || !(vio->vl_number)){
   8.650 -        fprintf(logfile, "null vio or o vl number\n");
   8.651 -        return;
   8.652 -    }
   8.653 -
   8.654 -    for (i = 0; i < MAX_LAPIC_NUM; i++) s->lapic_info[i] = NULL;
   8.655 -
   8.656 -    s->lapic_count = vio->vl_number;
   8.657 -    for (i = 0; i < vio->vl_number; i++)
   8.658 -        s->lapic_info[i] = vio->vl_info + i;
   8.659 -#endif
   8.660 -
   8.661 -}
   8.662 -
   8.663 -void
   8.664 -ioapic_intack(IOAPICState *s)
   8.665 -{
   8.666 -#ifdef IOAPIC_DEBUG
   8.667 -    if (!s){
   8.668 -        fprintf(logfile, "ioapic_intack null parameter\n");
   8.669 -        return;
   8.670 -    }
   8.671 -#endif
   8.672 -    if (!s) s->INTR = 0;
   8.673 -}
   8.674 -
   8.675 -int
   8.676 -ioapic_has_intr()
   8.677 -{
   8.678 -    return ioapic->INTR;
   8.679 -}
   8.680 -
   8.681 -void
   8.682 -do_ioapic()
   8.683 -{
   8.684 -    service_ioapic(ioapic);
   8.685 -    ioapic_intack(ioapic);
   8.686 -}
   8.687 -
   8.688 -IOAPICState *
   8.689 -IOAPICInit( )
   8.690 -{
   8.691 -    IOAPICState *s;
   8.692 -
   8.693 -    s = qemu_mallocz(sizeof(IOAPICState));
   8.694 -    if (!s){
   8.695 -        fprintf(logfile, "IOAPICInit: malloc failed\n");
   8.696 -        return NULL;
   8.697 -    }
   8.698 -
   8.699 -    IOAPICReset(s);
   8.700 -    ioapic_init_apic_info(s);
   8.701 -    register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s);
   8.702 -    /* Remove after GFW ready */
   8.703 -    ioapic_update_config(s, 0xfec00000, 1);
   8.704 -
   8.705 -    ioapic = s;
   8.706 -    return s;
   8.707 -}
     9.1 --- a/tools/ioemu/hw/ioapic.h	Mon Nov 07 16:53:25 2005 -0600
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,128 +0,0 @@
     9.4 -/////////////////////////////////////////////////////////////////////////
     9.5 -//
     9.6 -//  Copyright (C) 2001  MandrakeSoft S.A.
     9.7 -//
     9.8 -//    MandrakeSoft S.A.
     9.9 -//    43, rue d'Aboukir
    9.10 -//    75002 Paris - France
    9.11 -//    http://www.linux-mandrake.com/
    9.12 -//    http://www.mandrakesoft.com/
    9.13 -//
    9.14 -//  This library is free software; you can redistribute it and/or
    9.15 -//  modify it under the terms of the GNU Lesser General Public
    9.16 -//  License as published by the Free Software Foundation; either
    9.17 -//  version 2 of the License, or (at your option) any later version.
    9.18 -//
    9.19 -//  This library is distributed in the hope that it will be useful,
    9.20 -//  but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.21 -//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    9.22 -//  Lesser General Public License for more details.
    9.23 -//
    9.24 -//  You should have received a copy of the GNU Lesser General Public
    9.25 -//  License along with this library; if not, write to the Free Software
    9.26 -//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    9.27 -//
    9.28 -
    9.29 -#ifndef __IOAPIC_H
    9.30 -#define __IOAPIC_H
    9.31 -
    9.32 -#include <xenctrl.h>
    9.33 -#include <xen/io/ioreq.h>
    9.34 -#include <xen/io/vmx_vlapic.h>
    9.35 -
    9.36 -#define IOAPIC_NUM_PINS 24
    9.37 -#define IOAPIC_VERSION_ID 0x11
    9.38 -#define IOAPIC_LEVEL_TRIGGER 1
    9.39 -#define APIC_DM_FIXED	0
    9.40 -#define APIC_DM_LOWPRI	1
    9.41 -
    9.42 -
    9.43 -
    9.44 -#ifdef CONFIG_SMP
    9.45 -#define LOCK_PREFIX "lock ; "
    9.46 -#else
    9.47 -#define LOCK_PREFIX ""
    9.48 -#endif
    9.49 -
    9.50 -#ifdef __I386__
    9.51 -#define __OS "q" 
    9.52 -#define __OP "r" 
    9.53 -#else
    9.54 -#define __OS "l"  /* Operation Suffix */
    9.55 -#define __OP "e"  /* Operand Prefix */
    9.56 -#endif
    9.57 -
    9.58 -#define ADDR (*(volatile long *) addr)
    9.59 -#if 0
    9.60 -#endif
    9.61 -extern void *shared_page;
    9.62 -extern FILE *logfile;
    9.63 -#ifdef __BIGENDIAN__
    9.64 -typedef union RedirStatus
    9.65 -{
    9.66 -    uint64_t value;
    9.67 -    struct {
    9.68 -        uint8_t dest_id;
    9.69 -        uint8_t reserved[4];
    9.70 -        uint8_t reserve:7;
    9.71 -        uint8_t mask:1;         /* interrupt mask*/
    9.72 -        uint8_t trigmod:1;
    9.73 -        uint8_t remoteirr:1;
    9.74 -        uint8_t polarity:1;
    9.75 -        uint8_t delivestatus:1;
    9.76 -        uint8_t destmode:1;
    9.77 -        uint8_t deliver_mode:3;
    9.78 -        uint8_t vector;
    9.79 -    }RedirForm;
    9.80 -}RedirStatus;
    9.81 -#else
    9.82 -typedef union RedirStatus
    9.83 -{
    9.84 -    uint64_t value;
    9.85 -    struct {
    9.86 -        uint8_t vector;
    9.87 -        uint8_t deliver_mode:3;
    9.88 -        uint8_t destmode:1;
    9.89 -        uint8_t delivestatus:1;
    9.90 -        uint8_t polarity:1;
    9.91 -        uint8_t remoteirr:1;
    9.92 -        uint8_t trigmod:1;
    9.93 -        uint8_t mask:1;         /* interrupt mask*/
    9.94 -        uint8_t reserve:7;
    9.95 -        uint8_t reserved[4];
    9.96 -        uint8_t dest_id;
    9.97 -    }RedirForm;
    9.98 -}RedirStatus;
    9.99 -#endif
   9.100 -/*
   9.101 - * IOAPICState stands for a instance of a IOAPIC
   9.102 - */
   9.103 -
   9.104 -/* FIXME tmp before working with Local APIC */
   9.105 -#define IOAPIC_MEM_LENGTH 0x100
   9.106 -#define IOAPIC_ENABLE_MASK 0x0
   9.107 -#define IOAPIC_ENABLE_FLAG (1 << IOAPIC_ENABLE_MASK)
   9.108 -#define MAX_LAPIC_NUM 32
   9.109 -
   9.110 -struct IOAPICState{
   9.111 -    uint32_t INTR;
   9.112 -    uint32_t id;
   9.113 -    uint32_t arb_id;
   9.114 -    uint32_t  flags;
   9.115 -    unsigned long base_address;
   9.116 -    uint32_t irr;
   9.117 -    uint32_t isr;           /* This is used for level trigger */
   9.118 -    uint8_t  vector_irr[256];
   9.119 -    RedirStatus redirtbl[IOAPIC_NUM_PINS];
   9.120 -    uint32_t ioregsel;
   9.121 -    uint32_t lapic_count;
   9.122 -    vlapic_info *lapic_info[MAX_LAPIC_NUM];
   9.123 -};
   9.124 -#define IOAPIC_REG_APIC_ID 0x0
   9.125 -#define IOAPIC_REG_VERSION 0x1
   9.126 -#define IOAPIC_REG_ARB_ID  0x2
   9.127 -#define IOAPICEnabled(s) (s->flags & IOAPIC_ENABLE_FLAG)
   9.128 -
   9.129 -typedef struct IOAPICState IOAPICState;
   9.130 -
   9.131 -#endif
    10.1 --- a/xen/arch/x86/dm/i8259.c	Mon Nov 07 16:53:25 2005 -0600
    10.2 +++ b/xen/arch/x86/dm/i8259.c	Mon Nov 07 20:40:31 2005 -0600
    10.3 @@ -33,6 +33,7 @@
    10.4  #include <asm/vmx.h>
    10.5  #include <public/io/vmx_vpic.h>
    10.6  #include <asm/current.h>
    10.7 +#include <asm/vmx_vioapic.h>
    10.8  #include <asm/vmx_vlapic.h>
    10.9  
   10.10  /* set irq level. If an edge is detected, then the IRR is set to 1 */
   10.11 @@ -124,6 +125,7 @@ void pic_set_irq_new(void *opaque, int i
   10.12  {
   10.13      struct vmx_virpic *s = opaque;
   10.14  
   10.15 +    vmx_vioapic_set_irq(current->domain, irq, level);
   10.16      pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
   10.17      /* used for IOAPIC irqs */
   10.18      if (s->alt_irq_func)
   10.19 @@ -135,6 +137,7 @@ void do_pic_irqs (struct vmx_virpic *s, 
   10.20  {
   10.21      s->pics[1].irr |= (uint8_t)(irqs >> 8);
   10.22      s->pics[0].irr |= (uint8_t) irqs;
   10.23 +    vmx_vioapic_do_irqs(current->domain, irqs);
   10.24      pic_update_irq(s);
   10.25  }
   10.26  
   10.27 @@ -142,6 +145,7 @@ void do_pic_irqs_clear (struct vmx_virpi
   10.28  {
   10.29      s->pics[1].irr &= ~(uint8_t)(irqs >> 8);
   10.30      s->pics[0].irr &= ~(uint8_t) irqs;
   10.31 +    vmx_vioapic_do_irqs_clear(current->domain, irqs);
   10.32      pic_update_irq(s);
   10.33  }
   10.34  
   10.35 @@ -521,7 +525,13 @@ int cpu_get_pic_interrupt(struct vcpu *v
   10.36  
   10.37  int is_pit_irq(struct vcpu *v, int irq, int type)
   10.38  {
   10.39 -    int  pit_vec = v->domain->arch.vmx_platform.vmx_pic.pics[0].irq_base;
   10.40 +    int pit_vec;
   10.41 +
   10.42 +    if (type == VLAPIC_DELIV_MODE_EXT)
   10.43 +        pit_vec = v->domain->arch.vmx_platform.vmx_pic.pics[0].irq_base;
   10.44 +    else
   10.45 +        pit_vec =
   10.46 +          v->domain->arch.vmx_platform.vmx_vioapic.redirtbl[0].RedirForm.vector;
   10.47  
   10.48      return (irq == pit_vec);
   10.49  }
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/xen/arch/x86/dm/vmx_vioapic.c	Mon Nov 07 20:40:31 2005 -0600
    11.3 @@ -0,0 +1,608 @@
    11.4 +/*
    11.5 +*  Copyright (C) 2001  MandrakeSoft S.A.
    11.6 +*
    11.7 +*    MandrakeSoft S.A.
    11.8 +*    43, rue d'Aboukir
    11.9 +*    75002 Paris - France
   11.10 +*    http://www.linux-mandrake.com/
   11.11 +*    http://www.mandrakesoft.com/
   11.12 +*
   11.13 +*  This library is free software; you can redistribute it and/or
   11.14 +*  modify it under the terms of the GNU Lesser General Public
   11.15 +*  License as published by the Free Software Foundation; either
   11.16 +*  version 2 of the License, or (at your option) any later version.
   11.17 +*
   11.18 +*  This library is distributed in the hope that it will be useful,
   11.19 +*  but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.20 +*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   11.21 +*  Lesser General Public License for more details.
   11.22 +*
   11.23 +*  You should have received a copy of the GNU Lesser General Public
   11.24 +*  License along with this library; if not, write to the Free Software
   11.25 +*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   11.26 +*/
   11.27 +
   11.28 +/*
   11.29 +*  Yunhong Jiang <yunhong.jiang@intel.com>
   11.30 +*  Ported to xen by using virtual IRQ line.
   11.31 +*/
   11.32 +
   11.33 +#include <asm/vmx_vioapic.h>
   11.34 +#include <asm/vmx_platform.h>
   11.35 +
   11.36 +#include <xen/config.h>
   11.37 +#include <xen/types.h>
   11.38 +#include <xen/mm.h>
   11.39 +#include <xen/xmalloc.h>
   11.40 +#include <xen/lib.h>
   11.41 +#include <xen/errno.h>
   11.42 +#include <xen/sched.h>
   11.43 +#include <public/io/ioreq.h>
   11.44 +#include <asm/vmx.h>
   11.45 +#include <public/io/vmx_vpic.h>
   11.46 +#include <asm/current.h>
   11.47 +
   11.48 +static void ioapic_enable(vmx_vioapic_t *s, uint8_t enable)
   11.49 +{
   11.50 +    if (enable)
   11.51 +        s->flags |= IOAPIC_ENABLE_FLAG;
   11.52 +    else
   11.53 +        s->flags &= ~IOAPIC_ENABLE_FLAG;
   11.54 +}
   11.55 +
   11.56 +static void ioapic_dump_redir(vmx_vioapic_t *s, uint8_t entry)
   11.57 +{
   11.58 +    ASSERT(s);
   11.59 +
   11.60 +    RedirStatus redir = s->redirtbl[entry];
   11.61 +
   11.62 +    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_dump_redir "
   11.63 +      "entry %x vector %x deliver_mod %x destmode %x delivestatus %x "
   11.64 +      "polarity %x remote_irr %x trigmod %x mask %x dest_id %x\n",
   11.65 +      entry, redir.RedirForm.vector, redir.RedirForm.deliver_mode,
   11.66 +      redir.RedirForm.destmode, redir.RedirForm.delivestatus,
   11.67 +      redir.RedirForm.polarity, redir.RedirForm.remoteirr,
   11.68 +      redir.RedirForm.trigmod, redir.RedirForm.mask,
   11.69 +      redir.RedirForm.dest_id);
   11.70 +}
   11.71 +
   11.72 +#ifdef VMX_DOMAIN_SAVE_RESTORE
   11.73 +void ioapic_save(QEMUFile* f, void* opaque)
   11.74 +{
   11.75 +    printk("no implementation for ioapic_save\n");
   11.76 +}
   11.77 +
   11.78 +int ioapic_load(QEMUFile* f, void* opaque, int version_id)
   11.79 +{
   11.80 +    printk("no implementation for ioapic_load\n");
   11.81 +    return 0;
   11.82 +}
   11.83 +#endif
   11.84 +
   11.85 +static unsigned long vmx_vioapic_read_indirect(struct vmx_vioapic *s,
   11.86 +                                              unsigned long addr,
   11.87 +                                              unsigned long length)
   11.88 +{
   11.89 +    unsigned long result = 0;
   11.90 +
   11.91 +    ASSERT(s);
   11.92 +
   11.93 +    switch (s->ioregsel) {
   11.94 +    case IOAPIC_REG_VERSION:
   11.95 +        result = ((((IOAPIC_NUM_PINS-1) & 0xff) << 16)
   11.96 +                  | (IOAPIC_VERSION_ID & 0x0f));
   11.97 +        break;
   11.98 +
   11.99 +#ifndef __ia64__
  11.100 +    case IOAPIC_REG_APIC_ID:
  11.101 +        result = ((s->id & 0xf) << 24);
  11.102 +        break;
  11.103 +
  11.104 +    case IOAPIC_REG_ARB_ID:
  11.105 +        /* XXX how arb_id used on p4? */
  11.106 +        result = ((s->id & 0xf) << 24);
  11.107 +        break;
  11.108 +#endif
  11.109 +
  11.110 +    default:
  11.111 +        {
  11.112 +            uint32_t redir_index = 0;
  11.113 +            uint64_t redir_content = 0;
  11.114 +
  11.115 +            redir_index = (s->ioregsel - 0x10) >> 1;
  11.116 +
  11.117 +            if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS) {
  11.118 +                redir_content = s->redirtbl[redir_index].value;
  11.119 +
  11.120 +                result = (s->ioregsel & 0x1)?
  11.121 +                           (redir_content >> 32) & 0xffffffff :
  11.122 +                           redir_content & 0xffffffff;
  11.123 +            } else {
  11.124 +                printk("upic_mem_readl:undefined ioregsel %x\n",
  11.125 +                        s->ioregsel);
  11.126 +                domain_crash_synchronous();
  11.127 +            }
  11.128 +            break;
  11.129 +        }
  11.130 +    } /* switch */
  11.131 +
  11.132 +    return result;
  11.133 +}
  11.134 +
  11.135 +static unsigned long vmx_vioapic_read(struct vcpu *v,
  11.136 +                                     unsigned long addr,
  11.137 +                                     unsigned long length)
  11.138 +{
  11.139 +    struct vmx_vioapic *s = &(v->domain->arch.vmx_platform.vmx_vioapic);
  11.140 +    uint32_t    result = 0;
  11.141 +
  11.142 +    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "vmx_vioapic_read addr %lx\n", addr);
  11.143 +
  11.144 +    ASSERT(s);
  11.145 +
  11.146 +    addr &= 0xff;
  11.147 +
  11.148 +    switch (addr) {
  11.149 +    case IOAPIC_REG_SELECT:
  11.150 +        result = s->ioregsel;
  11.151 +        break;
  11.152 +
  11.153 +    case IOAPIC_REG_WINDOW:
  11.154 +        result = vmx_vioapic_read_indirect(s, addr, length);
  11.155 +        break;
  11.156 +
  11.157 +    default:
  11.158 +          break;
  11.159 +    }
  11.160 +
  11.161 +    return result;
  11.162 +}
  11.163 +
  11.164 +static void vmx_vioapic_write_indirect(struct vmx_vioapic *s,
  11.165 +                                      unsigned long addr,
  11.166 +                                      unsigned long length,
  11.167 +                                      unsigned long val)
  11.168 +{
  11.169 +    switch (s->ioregsel) {
  11.170 +    case IOAPIC_REG_VERSION:
  11.171 +        printk("vmx_vioapic_write_indirect: version register read only\n");
  11.172 +        break;
  11.173 +
  11.174 +#ifndef __ia64__
  11.175 +    case IOAPIC_REG_APIC_ID:
  11.176 +        s->id = (val >> 24) & 0xf;
  11.177 +        break;
  11.178 +
  11.179 +    case IOAPIC_REG_ARB_ID:
  11.180 +        s->arb_id = val;
  11.181 +        break;
  11.182 +#endif
  11.183 +
  11.184 +    default:
  11.185 +        {
  11.186 +            uint32_t redir_index = 0;
  11.187 +
  11.188 +            VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "vmx_vioapic_write_indirect "
  11.189 +              "change redir index %x val %lx\n",
  11.190 +              redir_index, val);
  11.191 +
  11.192 +            redir_index = (s->ioregsel - 0x10) >> 1;
  11.193 +
  11.194 +            if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS) {
  11.195 +                uint64_t redir_content;
  11.196 +
  11.197 +                redir_content = s->redirtbl[redir_index].value;
  11.198 +
  11.199 +                if (s->ioregsel & 0x1)
  11.200 +                    redir_content = (((uint64_t)val & 0xffffffff) << 32) |
  11.201 +                                    (redir_content & 0xffffffff);
  11.202 +                else
  11.203 +                    redir_content = ((redir_content >> 32) << 32) |
  11.204 +                                    (val & 0xffffffff);
  11.205 +                s->redirtbl[redir_index].value = redir_content;
  11.206 +            } else  {
  11.207 +                printk("vmx_vioapic_write_indirect "
  11.208 +                  "error register %x\n", s->ioregsel);
  11.209 +            }
  11.210 +            break;
  11.211 +        }
  11.212 +    } /* switch */
  11.213 +}
  11.214 +
  11.215 +static void vmx_vioapic_write(struct vcpu *v,
  11.216 +                             unsigned long addr,
  11.217 +                             unsigned long length,
  11.218 +                             unsigned long val)
  11.219 +{
  11.220 +    vmx_vioapic_t *s = &(v->domain->arch.vmx_platform.vmx_vioapic);
  11.221 +
  11.222 +    ASSERT(s);
  11.223 +
  11.224 +    addr &= 0xff;
  11.225 +
  11.226 +    switch (addr) {
  11.227 +    case IOAPIC_REG_SELECT:
  11.228 +        s->ioregsel = val;
  11.229 +        break;
  11.230 +
  11.231 +    case IOAPIC_REG_WINDOW:
  11.232 +        vmx_vioapic_write_indirect(s, addr, length, val);
  11.233 +        break;
  11.234 +
  11.235 +#ifdef __ia64__
  11.236 +    case IOAPIC_REG_EOI:
  11.237 +        ioapic_update_EOI(v->domain, val);
  11.238 +        break;
  11.239 +#endif
  11.240 +
  11.241 +    default:
  11.242 +        break;
  11.243 +    }
  11.244 +}
  11.245 +
  11.246 +static int vmx_vioapic_range(struct vcpu *v, unsigned long addr)
  11.247 +{
  11.248 +    vmx_vioapic_t *s = &(v->domain->arch.vmx_platform.vmx_vioapic);
  11.249 +
  11.250 +    if ((s->flags & IOAPIC_ENABLE_FLAG) &&
  11.251 +        (addr >= s->base_address &&
  11.252 +        (addr <= s->base_address + IOAPIC_MEM_LENGTH)))
  11.253 +        return 1;
  11.254 +    else
  11.255 +        return 0;
  11.256 +}
  11.257 +
  11.258 +struct vmx_mmio_handler vioapic_mmio_handler = {
  11.259 +    .check_handler = vmx_vioapic_range,
  11.260 +    .read_handler = vmx_vioapic_read,
  11.261 +    .write_handler = vmx_vioapic_write
  11.262 +};
  11.263 +
  11.264 +static void vmx_vioapic_reset(vmx_vioapic_t *s)
  11.265 +{
  11.266 +    int i;
  11.267 +
  11.268 +    memset(s, 0, sizeof(vmx_vioapic_t));
  11.269 +
  11.270 +    for (i = 0; i < IOAPIC_NUM_PINS; i++)
  11.271 +        s->redirtbl[i].RedirForm.mask = 0x1;
  11.272 +}
  11.273 +
  11.274 +static void ioapic_update_config(vmx_vioapic_t *s,
  11.275 +                                 unsigned long address,
  11.276 +                                 uint8_t enable)
  11.277 +{
  11.278 +    ASSERT(s);
  11.279 +
  11.280 +    ioapic_enable(s, enable);
  11.281 +
  11.282 +    if (address != s->base_address)
  11.283 +        s->base_address = address;
  11.284 +}
  11.285 +
  11.286 +static int ioapic_inj_irq(vmx_vioapic_t *s,
  11.287 +                          struct vlapic * target,
  11.288 +                          uint8_t vector,
  11.289 +                          uint8_t trig_mode,
  11.290 +                          uint8_t delivery_mode)
  11.291 +{
  11.292 +    int result = 0;
  11.293 +
  11.294 +    ASSERT(s && target);
  11.295 +
  11.296 +    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_inj_irq "
  11.297 +      "irq %d trig %d delive mode %d\n",
  11.298 +      vector, trig_mode, delivery_mode);
  11.299 +
  11.300 +    switch (delivery_mode) {
  11.301 +    case VLAPIC_DELIV_MODE_FIXED:
  11.302 +    case VLAPIC_DELIV_MODE_LPRI:
  11.303 +        if (test_and_set_bit(vector, &target->irr[0]) && trig_mode == 1) {
  11.304 +            /* the level interrupt should not happen before it is cleard */
  11.305 +            printk("<ioapic_inj_irq> level interrupt happen before cleard\n");
  11.306 +        }
  11.307 +        if (trig_mode)
  11.308 +            test_and_set_bit(vector, &target->tmr[0]);
  11.309 +        result = 1;
  11.310 +        break;
  11.311 +    default:
  11.312 +        printk("<ioapic_inj_irq> error delivery mode %d\n",
  11.313 +                delivery_mode);
  11.314 +        break;
  11.315 +   }
  11.316 +
  11.317 +   return result;
  11.318 +}
  11.319 +
  11.320 +#ifndef __ia64__
  11.321 +static int ioapic_match_logical_addr(vmx_vioapic_t *s, int number, uint8_t dest)
  11.322 +{
  11.323 +    int result = 0;
  11.324 +
  11.325 +    ASSERT(s && s->lapic_info[number]);
  11.326 +
  11.327 +    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_match_logical_addr "
  11.328 +      "number %i dest %x\n",
  11.329 +      number, dest);
  11.330 +
  11.331 +    switch (((s->lapic_info[number]->dest_format >> 28) & 0xf)) {
  11.332 +    case 0xf:
  11.333 +        result =
  11.334 +          (dest & ((s->lapic_info[number]->logical_dest >> 24) & 0xff)) != 0;
  11.335 +        break;
  11.336 +    case 0x0:
  11.337 +        /* Should we support flat cluster mode ?*/
  11.338 +        if ( ((s->lapic_info[number]->logical_dest >> 28)
  11.339 +               == ((dest >> 0x4) & 0xf)) &&
  11.340 +             (((s->lapic_info[number]->logical_dest >> 24) & 0xf)
  11.341 +               & (dest  & 0xf)) )
  11.342 +            result = 1;
  11.343 +        break;
  11.344 +    default:
  11.345 +        printk("error DFR value for %x local apic\n", number);
  11.346 +        break;
  11.347 +    }
  11.348 +
  11.349 +    return result;
  11.350 +}
  11.351 +#else
  11.352 +extern int ioapic_match_logical_addr(vmx_vioapic_t *s, int number, uint8_t dest);
  11.353 +#endif
  11.354 +
  11.355 +static uint32_t ioapic_get_delivery_bitmask(vmx_vioapic_t *s,
  11.356 +                                            uint16_t dest,
  11.357 +                                            uint8_t dest_mode,
  11.358 +                                            uint8_t vector,
  11.359 +                                            uint8_t delivery_mode)
  11.360 +{
  11.361 +    uint32_t mask = 0;
  11.362 +    int i;
  11.363 +
  11.364 +    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask "
  11.365 +      "dest %d dest_mode %d "
  11.366 +      "vector %d del_mode %d, lapic_count %d\n",
  11.367 +      dest, dest_mode, vector, delivery_mode, s->lapic_count);
  11.368 +
  11.369 +    ASSERT(s);
  11.370 +
  11.371 +    if (dest_mode == 0) { /* Physical mode */
  11.372 +        for (i = 0; i < s->lapic_count; i++) {
  11.373 +            if (s->lapic_info[i]->id == dest) {
  11.374 +                mask = 1 << i;
  11.375 +                break;
  11.376 +            }
  11.377 +        }
  11.378 +    } else {
  11.379 +        /* logical destination. call match_logical_addr for each APIC. */
  11.380 +        if (dest != 0) {
  11.381 +            for (i=0; i< s->lapic_count; i++) {
  11.382 +                if ( s->lapic_info[i] &&
  11.383 +                     ioapic_match_logical_addr(s, i, dest) ) {
  11.384 +                    mask |= (1<<i);
  11.385 +                }
  11.386 +            }
  11.387 +        }
  11.388 +    }
  11.389 +
  11.390 +    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask "
  11.391 +      "mask %x\n", mask);
  11.392 +
  11.393 +    return mask;
  11.394 +}
  11.395 +
  11.396 +static void ioapic_deliver(vmx_vioapic_t *s, int irqno)
  11.397 +{
  11.398 +    uint16_t dest = s->redirtbl[irqno].RedirForm.dest_id;
  11.399 +    uint8_t dest_mode = s->redirtbl[irqno].RedirForm.destmode;
  11.400 +    uint8_t delivery_mode = s->redirtbl[irqno].RedirForm.deliver_mode;
  11.401 +    uint8_t vector = s->redirtbl[irqno].RedirForm.vector;
  11.402 +    uint8_t trig_mode = s->redirtbl[irqno].RedirForm.trigmod;
  11.403 +    uint32_t deliver_bitmask;
  11.404 +
  11.405 +    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "IOAPIC deliver: "
  11.406 +      "dest %x dest_mode %x delivery_mode %x vector %x trig_mode %x\n",
  11.407 +      dest, dest_mode, delivery_mode, vector, trig_mode);
  11.408 +
  11.409 +    deliver_bitmask =
  11.410 +      ioapic_get_delivery_bitmask(s, dest, dest_mode, vector, delivery_mode);
  11.411 +
  11.412 +    if (!deliver_bitmask) {
  11.413 +        VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver "
  11.414 +          "no target on destination\n");
  11.415 +
  11.416 +        return;
  11.417 +    }
  11.418 +
  11.419 +    switch (delivery_mode) {
  11.420 +    case VLAPIC_DELIV_MODE_LPRI:
  11.421 +    {
  11.422 +        struct vlapic* target;
  11.423 +
  11.424 +        target = apic_round_robin(
  11.425 +                s->domain, dest_mode, vector, deliver_bitmask);
  11.426 +        ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode);
  11.427 +        break;
  11.428 +    }
  11.429 +
  11.430 +    case VLAPIC_DELIV_MODE_FIXED:
  11.431 +    case VLAPIC_DELIV_MODE_EXT:
  11.432 +    {
  11.433 +        uint8_t bit;
  11.434 +        for (bit = 0; bit < s->lapic_count; bit++) {
  11.435 +            if (deliver_bitmask & (1 << bit)) {
  11.436 +                if (s->lapic_info[bit]) {
  11.437 +                    ioapic_inj_irq(s, s->lapic_info[bit],
  11.438 +                                vector, trig_mode, delivery_mode);
  11.439 +                }
  11.440 +            }
  11.441 +        }
  11.442 +        break;
  11.443 +    }
  11.444 +
  11.445 +    case VLAPIC_DELIV_MODE_SMI:
  11.446 +    case VLAPIC_DELIV_MODE_NMI:
  11.447 +    case VLAPIC_DELIV_MODE_INIT:
  11.448 +    case VLAPIC_DELIV_MODE_STARTUP:
  11.449 +    default:
  11.450 +        printk("Not support delivey mode %d\n", delivery_mode);
  11.451 +        break;
  11.452 +    }
  11.453 +}
  11.454 +
  11.455 +static int ioapic_get_highest_irq(vmx_vioapic_t *s)
  11.456 +{
  11.457 +    uint32_t irqs;
  11.458 +
  11.459 +    ASSERT(s);
  11.460 +
  11.461 +    irqs = s->irr & ~s->isr;
  11.462 +    return __fls(irqs);
  11.463 +}
  11.464 +
  11.465 +
  11.466 +static void service_ioapic(vmx_vioapic_t *s)
  11.467 +{
  11.468 +    int irqno;
  11.469 +
  11.470 +    while ((irqno = ioapic_get_highest_irq(s)) != -1) {
  11.471 +
  11.472 +        VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "service_ioapic "
  11.473 +          "highest irqno %x\n", irqno);
  11.474 +
  11.475 +        if (!s->redirtbl[irqno].RedirForm.mask) {
  11.476 +            ioapic_deliver(s, irqno);
  11.477 +        }
  11.478 +
  11.479 +        if (s->redirtbl[irqno].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER) {
  11.480 +            s->isr |= (1 << irqno);
  11.481 +        }
  11.482 +
  11.483 +        s->irr &= ~(1 << irqno);
  11.484 +    }
  11.485 +}
  11.486 +
  11.487 +void vmx_vioapic_do_irqs(struct domain *d, uint16_t irqs)
  11.488 +{
  11.489 +    vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic);
  11.490 +
  11.491 +    if (!vmx_apic_support(d))
  11.492 +        return;
  11.493 +
  11.494 +    s->irr |= irqs;
  11.495 +    service_ioapic(s);
  11.496 +}
  11.497 +
  11.498 +void vmx_vioapic_do_irqs_clear(struct domain *d, uint16_t irqs)
  11.499 +{
  11.500 +    vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic);
  11.501 +
  11.502 +    if (!vmx_apic_support(d))
  11.503 +        return;
  11.504 +
  11.505 +    s->irr &= ~irqs;
  11.506 +    service_ioapic(s);
  11.507 +}
  11.508 +
  11.509 +void vmx_vioapic_set_irq(struct domain *d, int irq, int level)
  11.510 +{
  11.511 +    vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic);
  11.512 +
  11.513 +    if (!vmx_apic_support(d))
  11.514 +        return ;
  11.515 +
  11.516 +    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_set_irq "
  11.517 +      "irq %x level %x\n", irq, level);
  11.518 +
  11.519 +    if (irq < 0 || irq >= IOAPIC_NUM_PINS) {
  11.520 +        printk("ioapic_set_irq irq %x is illegal\n", irq);
  11.521 +        domain_crash_synchronous();
  11.522 +    }
  11.523 +
  11.524 +    if (!IOAPICEnabled(s) || s->redirtbl[irq].RedirForm.mask)
  11.525 +        return;
  11.526 +
  11.527 +    ioapic_dump_redir(s, irq);
  11.528 +
  11.529 +    if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
  11.530 +        uint32_t bit = 1 << irq;
  11.531 +        if (s->redirtbl[irq].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER) {
  11.532 +            if (level)
  11.533 +                s->irr |= bit;
  11.534 +            else
  11.535 +                s->irr &= ~bit;
  11.536 +        } else {
  11.537 +            if (level)
  11.538 +                /* XXX No irr clear for edge interrupt */
  11.539 +                s->irr |= bit;
  11.540 +        }
  11.541 +    }
  11.542 +
  11.543 +    service_ioapic(s);
  11.544 +}
  11.545 +
  11.546 +/* XXX If level interrupt, use vector->irq table for performance */
  11.547 +static int get_redir_num(vmx_vioapic_t *s, int vector)
  11.548 +{
  11.549 +    int i = 0;
  11.550 +
  11.551 +    ASSERT(s);
  11.552 +
  11.553 +    for(i = 0; i < IOAPIC_NUM_PINS - 1; i++) {
  11.554 +        if (s->redirtbl[i].RedirForm.vector == vector)
  11.555 +            return i;
  11.556 +    }
  11.557 +
  11.558 +    return -1;
  11.559 +}
  11.560 +
  11.561 +void ioapic_update_EOI(struct domain *d, int vector)
  11.562 +{
  11.563 +    vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic);
  11.564 +    int redir_num;
  11.565 +
  11.566 +    if ((redir_num = get_redir_num(s, vector)) == -1) {
  11.567 +        printk("Can't find redir item for %d EOI \n", vector);
  11.568 +        return;
  11.569 +    }
  11.570 +
  11.571 +    if (!test_and_clear_bit(redir_num, &s->isr)) {
  11.572 +        printk("redir %d not set for %d  EOI\n", redir_num, vector);
  11.573 +        return;
  11.574 +    }
  11.575 +}
  11.576 +
  11.577 +int vmx_vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v)
  11.578 +{
  11.579 +    vmx_vioapic_t *s = &(v->domain->arch.vmx_platform.vmx_vioapic);
  11.580 +
  11.581 +    if (v->vcpu_id != s->lapic_count) {
  11.582 +        printk("vmx_vioapic_add_lapic "
  11.583 +           "cpu_id not match vcpu_id %x lapic_count %x\n",
  11.584 +           v->vcpu_id, s->lapic_count);
  11.585 +        domain_crash_synchronous();
  11.586 +    }
  11.587 +
  11.588 +    s->lapic_info[s->lapic_count ++] = vlapic;
  11.589 +
  11.590 +    return s->lapic_count;
  11.591 +}
  11.592 +
  11.593 +vmx_vioapic_t * vmx_vioapic_init(struct domain *d)
  11.594 +{
  11.595 +    int i = 0;
  11.596 +    vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic);
  11.597 +
  11.598 +    VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "vmx_vioapic_init\n");
  11.599 +
  11.600 +    vmx_vioapic_reset(s);
  11.601 +
  11.602 +    s->domain = d;
  11.603 +
  11.604 +    for (i = 0; i < MAX_LAPIC_NUM; i++)
  11.605 +        s->lapic_info[i] = NULL;
  11.606 +
  11.607 +    /* Remove after GFW ready */
  11.608 +    ioapic_update_config(s, IOAPIC_DEFAULT_BASE_ADDRESS, 1);
  11.609 +
  11.610 +    return s;
  11.611 +}
    12.1 --- a/xen/arch/x86/vmx_intercept.c	Mon Nov 07 16:53:25 2005 -0600
    12.2 +++ b/xen/arch/x86/vmx_intercept.c	Mon Nov 07 20:40:31 2005 -0600
    12.3 @@ -33,13 +33,15 @@
    12.4  
    12.5  #ifdef CONFIG_VMX
    12.6  
    12.7 -struct vmx_mmio_handler vmx_mmio_handers[VMX_MMIO_HANDLER_NR] =
    12.8 +extern struct vmx_mmio_handler vlapic_mmio_handler;
    12.9 +extern struct vmx_mmio_handler vioapic_mmio_handler;
   12.10 +
   12.11 +#define VMX_MMIO_HANDLER_NR 2
   12.12 +
   12.13 +struct vmx_mmio_handler *vmx_mmio_handlers[VMX_MMIO_HANDLER_NR] =
   12.14  {
   12.15 -    {
   12.16 -        .check_handler = vlapic_range,
   12.17 -        .read_handler  = vlapic_read,
   12.18 -        .write_handler = vlapic_write
   12.19 -    }
   12.20 +    &vlapic_mmio_handler,
   12.21 +    &vioapic_mmio_handler
   12.22  };
   12.23  
   12.24  static inline void vmx_mmio_access(struct vcpu *v,
   12.25 @@ -134,16 +136,16 @@ int vmx_mmio_intercept(ioreq_t *p)
   12.26  {
   12.27      struct vcpu *v = current;
   12.28      int i;
   12.29 -    struct vmx_mmio_handler *handler = vmx_mmio_handers;
   12.30  
   12.31      /* XXX currently only APIC use intercept */
   12.32      if ( !vmx_apic_support(v->domain) )
   12.33          return 0;
   12.34  
   12.35      for ( i = 0; i < VMX_MMIO_HANDLER_NR; i++ ) {
   12.36 -        if ( handler[i].check_handler(v, p->addr) ) {
   12.37 +        if ( vmx_mmio_handlers[i]->check_handler(v, p->addr) ) {
   12.38              vmx_mmio_access(v, p,
   12.39 -              handler[i].read_handler, handler[i].write_handler);
   12.40 +                            vmx_mmio_handlers[i]->read_handler,
   12.41 +                            vmx_mmio_handlers[i]->write_handler);
   12.42              return 1;
   12.43          }
   12.44      }
    13.1 --- a/xen/arch/x86/vmx_vlapic.c	Mon Nov 07 16:53:25 2005 -0600
    13.2 +++ b/xen/arch/x86/vmx_vlapic.c	Mon Nov 07 20:40:31 2005 -0600
    13.3 @@ -307,6 +307,11 @@ vlapic_EOI_set(struct vlapic *vlapic)
    13.4  
    13.5      vlapic_clear_isr(vlapic, vector);
    13.6      vlapic_update_ppr(vlapic);
    13.7 +
    13.8 +    if (test_and_clear_bit(vector, &vlapic->tmr[0])) {
    13.9 +        extern void ioapic_update_EOI(struct domain *d, int vector);
   13.10 +        ioapic_update_EOI(vlapic->domain, vector);
   13.11 +    }
   13.12  }
   13.13  
   13.14  int vlapic_check_vector(struct vlapic *vlapic,
   13.15 @@ -543,8 +548,8 @@ void vlapic_read_aligned(struct vlapic *
   13.16      }
   13.17  }
   13.18  
   13.19 -unsigned long vlapic_read(struct vcpu *v, unsigned long address,
   13.20 -            unsigned long len)
   13.21 +static unsigned long vlapic_read(struct vcpu *v, unsigned long address,
   13.22 +                                 unsigned long len)
   13.23  {
   13.24      unsigned int alignment;
   13.25      unsigned int tmp;
   13.26 @@ -585,8 +590,8 @@ unsigned long vlapic_read(struct vcpu *v
   13.27      return result;
   13.28  }
   13.29  
   13.30 -unsigned long vlapic_write(struct vcpu *v, unsigned long address,
   13.31 -                  unsigned long len, unsigned long val)
   13.32 +static void vlapic_write(struct vcpu *v, unsigned long address,
   13.33 +                         unsigned long len, unsigned long val)
   13.34  {
   13.35      struct vlapic *vlapic = VLAPIC(v);
   13.36      unsigned int offset = address - vlapic->base_address;
   13.37 @@ -758,10 +763,9 @@ unsigned long vlapic_write(struct vcpu *
   13.38          printk("Local APIC Write to read-only register\n");
   13.39          break;
   13.40      }
   13.41 -    return 1;
   13.42  }
   13.43  
   13.44 -int vlapic_range(struct vcpu *v, unsigned long addr)
   13.45 +static int vlapic_range(struct vcpu *v, unsigned long addr)
   13.46  {
   13.47      struct vlapic *vlapic = VLAPIC(v);
   13.48  
   13.49 @@ -773,6 +777,12 @@ int vlapic_range(struct vcpu *v, unsigne
   13.50      return 0;
   13.51  }
   13.52  
   13.53 +struct vmx_mmio_handler vlapic_mmio_handler = {
   13.54 +    .check_handler = vlapic_range,
   13.55 +    .read_handler = vlapic_read,
   13.56 +    .write_handler = vlapic_write
   13.57 +};
   13.58 +
   13.59  void vlapic_msr_set(struct vlapic *vlapic, uint64_t value)
   13.60  {
   13.61      /* When apic disabled */
   13.62 @@ -964,6 +974,8 @@ static int vlapic_reset(struct vlapic *v
   13.63  
   13.64      vlapic->spurious_vec = 0xff;
   13.65  
   13.66 +    vmx_vioapic_add_lapic(vlapic, v);
   13.67 +
   13.68      init_ac_timer(&vlapic->vlapic_timer,
   13.69                    vlapic_timer_fn, vlapic, v->processor);
   13.70  
    14.1 --- a/xen/arch/x86/vmx_vmcs.c	Mon Nov 07 16:53:25 2005 -0600
    14.2 +++ b/xen/arch/x86/vmx_vmcs.c	Mon Nov 07 20:40:31 2005 -0600
    14.3 @@ -28,6 +28,7 @@
    14.4  #include <asm/processor.h>
    14.5  #include <asm/msr.h>
    14.6  #include <asm/vmx.h>
    14.7 +#include <asm/vmx_vioapic.h>
    14.8  #include <asm/flushtlb.h>
    14.9  #include <xen/event.h>
   14.10  #include <xen/kernel.h>
   14.11 @@ -255,6 +256,7 @@ static void vmx_setup_platform(struct do
   14.12  
   14.13      if ( vmx_apic_support(d) ) {
   14.14          spin_lock_init(&d->arch.vmx_platform.round_robin_lock);
   14.15 +        vmx_vioapic_init(d);
   14.16      }
   14.17  }
   14.18  
    15.1 --- a/xen/include/asm-x86/vmx_intercept.h	Mon Nov 07 16:53:25 2005 -0600
    15.2 +++ b/xen/include/asm-x86/vmx_intercept.h	Mon Nov 07 20:40:31 2005 -0600
    15.3 @@ -18,10 +18,10 @@ typedef unsigned long (*vmx_mmio_read_t)
    15.4                                           unsigned long addr,
    15.5                                           unsigned long length);
    15.6  
    15.7 -typedef unsigned long (*vmx_mmio_write_t)(struct vcpu *v,
    15.8 -                                         unsigned long addr,
    15.9 -                                         unsigned long length,
   15.10 -                                         unsigned long val);
   15.11 +typedef void (*vmx_mmio_write_t)(struct vcpu *v,
   15.12 +                                 unsigned long addr,
   15.13 +                                 unsigned long length,
   15.14 +                                 unsigned long val);
   15.15  
   15.16  typedef int (*vmx_mmio_check_t)(struct vcpu *v, unsigned long addr);
   15.17  
   15.18 @@ -43,10 +43,6 @@ struct vmx_mmio_handler {
   15.19      vmx_mmio_write_t write_handler;
   15.20  };
   15.21  
   15.22 -#define VMX_MMIO_HANDLER_NR 1
   15.23 -
   15.24 -extern struct vmx_mmio_handler vmx_mmio_handers[VMX_MMIO_HANDLER_NR];
   15.25 -
   15.26  /* global io interception point in HV */
   15.27  extern int vmx_io_intercept(ioreq_t *p, int type);
   15.28  extern int register_io_handler(unsigned long addr, unsigned long size,
    16.1 --- a/xen/include/asm-x86/vmx_platform.h	Mon Nov 07 16:53:25 2005 -0600
    16.2 +++ b/xen/include/asm-x86/vmx_platform.h	Mon Nov 07 20:40:31 2005 -0600
    16.3 @@ -24,6 +24,7 @@
    16.4  #include <asm/e820.h>
    16.5  #include <asm/vmx_virpit.h>
    16.6  #include <asm/vmx_intercept.h>
    16.7 +#include <asm/vmx_vioapic.h>
    16.8  #include <public/io/vmx_vpic.h>
    16.9  
   16.10  #define MAX_OPERAND_NUM 2
   16.11 @@ -85,6 +86,7 @@ struct vmx_platform {
   16.12      struct vmx_virpit      vmx_pit;
   16.13      struct vmx_io_handler  vmx_io_handler;
   16.14      struct vmx_virpic      vmx_pic;
   16.15 +    struct vmx_vioapic      vmx_vioapic;
   16.16      unsigned char          round_info[256];
   16.17      spinlock_t             round_robin_lock;
   16.18      int                    interrupt_request;
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/xen/include/asm-x86/vmx_vioapic.h	Mon Nov 07 20:40:31 2005 -0600
    17.3 @@ -0,0 +1,136 @@
    17.4 +/*
    17.5 + *
    17.6 + *  Copyright (C) 2001  MandrakeSoft S.A.
    17.7 + *
    17.8 + *    MandrakeSoft S.A.
    17.9 + *    43, rue d'Aboukir
   17.10 + *    75002 Paris - France
   17.11 + *    http://www.linux-mandrake.com/
   17.12 + *    http://www.mandrakesoft.com/
   17.13 + *
   17.14 + *  This library is free software; you can redistribute it and/or
   17.15 + *  modify it under the terms of the GNU Lesser General Public
   17.16 + *  License as published by the Free Software Foundation; either
   17.17 + *  version 2 of the License, or (at your option) any later version.
   17.18 + *
   17.19 + *  This library is distributed in the hope that it will be useful,
   17.20 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.21 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   17.22 + *  Lesser General Public License for more details.
   17.23 + *
   17.24 + *  You should have received a copy of the GNU Lesser General Public
   17.25 + *  License along with this library; if not, write to the Free Software
   17.26 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   17.27 + */
   17.28 +
   17.29 +#ifndef _IOAPIC_H_
   17.30 +#define _IOAPIC_H_
   17.31 +
   17.32 +#include <xen/config.h>
   17.33 +#include <xen/types.h>
   17.34 +#include <xen/smp.h>
   17.35 +
   17.36 +#ifndef __ia64__
   17.37 +#define IOAPIC_VERSION_ID 0x11
   17.38 +#else
   17.39 +#define IOAPIC_VERSION_ID 0x21
   17.40 +#endif
   17.41 +
   17.42 +#define IOAPIC_NUM_PINS 24
   17.43 +#define MAX_LAPIC_NUM   32
   17.44 +
   17.45 +#define IOAPIC_LEVEL_TRIGGER 1
   17.46 +
   17.47 +#define IOAPIC_DEFAULT_BASE_ADDRESS  0xfec00000
   17.48 +#define IOAPIC_MEM_LENGTH            0x100
   17.49 +
   17.50 +#define IOAPIC_ENABLE_MASK  0x0
   17.51 +#define IOAPIC_ENABLE_FLAG  (1 << IOAPIC_ENABLE_MASK)
   17.52 +#define IOAPICEnabled(s)    (s->flags & IOAPIC_ENABLE_FLAG)
   17.53 +
   17.54 +#define IOAPIC_REG_SELECT  0x0
   17.55 +#define IOAPIC_REG_WINDOW  0x10
   17.56 +
   17.57 +#ifdef __ia64__
   17.58 +#define IOAPIC_REG_ASSERTION    0x20
   17.59 +#define IOAPIC_REG_EOI          0x40
   17.60 +#endif
   17.61 +
   17.62 +#ifndef __ia64__
   17.63 +#define IOAPIC_REG_APIC_ID 0x0
   17.64 +#define IOAPIC_REG_ARB_ID  0x2
   17.65 +#endif
   17.66 +
   17.67 +#define IOAPIC_REG_VERSION 0x1
   17.68 +
   17.69 +#ifdef __ia64__
   17.70 +typedef union RedirStatus
   17.71 +{
   17.72 +    uint64_t value;
   17.73 +    struct {
   17.74 +        uint16_t dest_id;
   17.75 +        uint8_t reserved[3];
   17.76 +        uint8_t reserve:7;
   17.77 +        uint8_t mask:1;         /* interrupt mask*/
   17.78 +        uint8_t trigmod:1;
   17.79 +        uint8_t remoteirr:1;
   17.80 +        uint8_t polarity:1;
   17.81 +        uint8_t delivestatus:1;
   17.82 +        uint8_t destmode:1;
   17.83 +        uint8_t deliver_mode:3;
   17.84 +        uint8_t vector;
   17.85 +    } RedirForm;
   17.86 +} RedirStatus;
   17.87 +#else
   17.88 +typedef union RedirStatus
   17.89 +{
   17.90 +    uint64_t value;
   17.91 +    struct {
   17.92 +        uint8_t vector;
   17.93 +        uint8_t deliver_mode:3;
   17.94 +        uint8_t destmode:1;
   17.95 +        uint8_t delivestatus:1;
   17.96 +        uint8_t polarity:1;
   17.97 +        uint8_t remoteirr:1;
   17.98 +        uint8_t trigmod:1;
   17.99 +        uint8_t mask:1;         /* interrupt mask*/
  17.100 +        uint8_t reserve:7;
  17.101 +        uint8_t reserved[4];
  17.102 +        uint8_t dest_id;
  17.103 +    } RedirForm;
  17.104 +} RedirStatus;
  17.105 +#endif
  17.106 +
  17.107 +#define IOAPIC_MEM_LENGTH    0x100
  17.108 +#define IOAPIC_ENABLE_MASK   0x0
  17.109 +#define IOAPIC_ENABLE_FLAG   (1 << IOAPIC_ENABLE_MASK)
  17.110 +#define MAX_LAPIC_NUM        32
  17.111 +
  17.112 +typedef struct vmx_vioapic {
  17.113 +    uint32_t ioregsel;
  17.114 +    uint32_t irr;
  17.115 +    uint32_t isr;           /* This is used for level trigger */
  17.116 +    uint32_t flags;
  17.117 +    uint32_t lapic_count;
  17.118 +    uint32_t id;
  17.119 +    uint32_t arb_id;
  17.120 +    unsigned long base_address;
  17.121 +    RedirStatus redirtbl[IOAPIC_NUM_PINS];
  17.122 +    struct vlapic *lapic_info[MAX_LAPIC_NUM];
  17.123 +    struct domain *domain;
  17.124 +} vmx_vioapic_t;
  17.125 +
  17.126 +vmx_vioapic_t *vmx_vioapic_init(struct domain *d);
  17.127 +
  17.128 +void vmx_vioapic_do_irqs_clear(struct domain *d, uint16_t irqs);
  17.129 +void vmx_vioapic_do_irqs(struct domain *d, uint16_t irqs);
  17.130 +void vmx_vioapic_set_irq(struct domain *d, int irq, int level);
  17.131 +
  17.132 +int vmx_vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v);
  17.133 +
  17.134 +#ifdef VMX_DOMAIN_SAVE_RESTORE
  17.135 +void ioapic_save(QEMUFile* f, void* opaque);
  17.136 +int ioapic_load(QEMUFile* f, void* opaque, int version_id);
  17.137 +#endif
  17.138 +
  17.139 +#endif
    18.1 --- a/xen/include/asm-x86/vmx_vlapic.h	Mon Nov 07 16:53:25 2005 -0600
    18.2 +++ b/xen/include/asm-x86/vmx_vlapic.h	Mon Nov 07 20:40:31 2005 -0600
    18.3 @@ -225,14 +225,6 @@ extern int vlapic_init(struct vcpu *vc);
    18.4  
    18.5  extern void vlapic_msr_set(struct vlapic *vlapic, uint64_t value);
    18.6  
    18.7 -int vlapic_range(struct vcpu *v, unsigned long addr);
    18.8 -
    18.9 -unsigned long vlapic_write(struct vcpu *v, unsigned long address,
   18.10 -                           unsigned long len, unsigned long val);
   18.11 -
   18.12 -unsigned long vlapic_read(struct vcpu *v, unsigned long address,
   18.13 -                          unsigned long len);
   18.14 -
   18.15  int vlapic_accept_pic_intr(struct vcpu *v);
   18.16  
   18.17  struct vlapic* apic_round_robin(struct domain *d,
    19.1 --- a/xen/include/asm-x86/vmx_vmcs.h	Mon Nov 07 16:53:25 2005 -0600
    19.2 +++ b/xen/include/asm-x86/vmx_vmcs.h	Mon Nov 07 20:40:31 2005 -0600
    19.3 @@ -284,7 +284,8 @@ enum vmcs_field {
    19.4  #define DBG_LEVEL_VMMU              (1 << 5)
    19.5  #define DBG_LEVEL_VLAPIC            (1 << 6)
    19.6  #define DBG_LEVEL_VLAPIC_TIMER      (1 << 7)
    19.7 -#define DBG_LEVEL_VLAPIC_INTERRUPT  (1 << 7)
    19.8 +#define DBG_LEVEL_VLAPIC_INTERRUPT  (1 << 8)
    19.9 +#define DBG_LEVEL_IOAPIC            (1 << 9)
   19.10  
   19.11  extern unsigned int opt_vmx_debug_level;
   19.12  #define VMX_DBG_LOG(level, _f, _a...)           \