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 + struct task_struct *tsk = current; 3.182 + 3.183 + task_lock(tsk); 3.184 3.185 - task_lock(tsk); 3.186 + /* 3.187 + * We aggressively remove defunct pgd from cr3. We execute unmap_vmas() 3.188 + * *much* faster this way, as no tlb flushes means bigger wrpt batches. 3.189 + */ 3.190 + if (tsk->active_mm == mm) { 3.191 + tsk->active_mm = &init_mm; 3.192 + atomic_inc(&init_mm.mm_count); 3.193 + 3.194 + switch_mm(mm, &init_mm, tsk); 3.195 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 - { 3.202 - tsk->active_mm = &init_mm; 3.203 - atomic_inc(&init_mm.mm_count); 3.204 + atomic_dec(&mm->mm_count); 3.205 + BUG_ON(atomic_read(&mm->mm_count) == 0); 3.206 + } 3.207 + 3.208 + task_unlock(tsk); 3.209 3.210 - switch_mm(mm, &init_mm, tsk); 3.211 - 3.212 - atomic_dec(&mm->mm_count); 3.213 - BUG_ON(atomic_read(&mm->mm_count) == 0); 3.214 - } 3.215 + if (test_bit(PG_pinned, &virt_to_page(mm->pgd)->flags) && 3.216 + (atomic_read(&mm->mm_count) == 1)) 3.217 + mm_unpin(mm); 3.218 +} 3.219 3.220 - task_unlock(tsk); 3.221 - 3.222 - if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) ) 3.223 - mm_unpin(mm); 3.224 -} 3.225 +/* 3.226 + * Local variables: 3.227 + * c-file-style: "linux" 3.228 + * indent-tabs-mode: t 3.229 + * c-indent-level: 8 3.230 + * c-basic-offset: 8 3.231 + * tab-width: 8 3.232 + * End: 3.233 + */
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...) \