[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] This patch add virtual IOAPIC support for VMX guest.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 9bb7a75f120fcd7db6b9e9dd1bc3700701168ada # Parent 781b6dd73e4c66ab0f05cd03a045b47e429510cc This patch add virtual IOAPIC support for VMX guest. Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx> Signed-off-by: Xin Li <xin.b.li@xxxxxxxxx> Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx> Signed-off-by: Jun Nakajima <jun.nakajima@xxxxxxxxx> diff -r 781b6dd73e4c -r 9bb7a75f120f xen/arch/x86/dm/i8259.c --- a/xen/arch/x86/dm/i8259.c Mon Nov 7 15:35:46 2005 +++ b/xen/arch/x86/dm/i8259.c Mon Nov 7 15:36:27 2005 @@ -33,6 +33,7 @@ #include <asm/vmx.h> #include <public/io/vmx_vpic.h> #include <asm/current.h> +#include <asm/vmx_vioapic.h> #include <asm/vmx_vlapic.h> /* set irq level. If an edge is detected, then the IRR is set to 1 */ @@ -124,6 +125,7 @@ { struct vmx_virpic *s = opaque; + vmx_vioapic_set_irq(current->domain, irq, level); pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); /* used for IOAPIC irqs */ if (s->alt_irq_func) @@ -135,6 +137,7 @@ { s->pics[1].irr |= (uint8_t)(irqs >> 8); s->pics[0].irr |= (uint8_t) irqs; + vmx_vioapic_do_irqs(current->domain, irqs); pic_update_irq(s); } @@ -142,6 +145,7 @@ { s->pics[1].irr &= ~(uint8_t)(irqs >> 8); s->pics[0].irr &= ~(uint8_t) irqs; + vmx_vioapic_do_irqs_clear(current->domain, irqs); pic_update_irq(s); } @@ -521,7 +525,13 @@ int is_pit_irq(struct vcpu *v, int irq, int type) { - int pit_vec = v->domain->arch.vmx_platform.vmx_pic.pics[0].irq_base; + int pit_vec; + + if (type == VLAPIC_DELIV_MODE_EXT) + pit_vec = v->domain->arch.vmx_platform.vmx_pic.pics[0].irq_base; + else + pit_vec = + v->domain->arch.vmx_platform.vmx_vioapic.redirtbl[0].RedirForm.vector; return (irq == pit_vec); } diff -r 781b6dd73e4c -r 9bb7a75f120f xen/arch/x86/vmx_intercept.c --- a/xen/arch/x86/vmx_intercept.c Mon Nov 7 15:35:46 2005 +++ b/xen/arch/x86/vmx_intercept.c Mon Nov 7 15:36:27 2005 @@ -34,12 +34,14 @@ #ifdef CONFIG_VMX extern struct vmx_mmio_handler vlapic_mmio_handler; - -#define VMX_MMIO_HANDLER_NR 1 +extern struct vmx_mmio_handler vioapic_mmio_handler; + +#define VMX_MMIO_HANDLER_NR 2 struct vmx_mmio_handler *vmx_mmio_handlers[VMX_MMIO_HANDLER_NR] = { - &vlapic_mmio_handler + &vlapic_mmio_handler, + &vioapic_mmio_handler }; static inline void vmx_mmio_access(struct vcpu *v, diff -r 781b6dd73e4c -r 9bb7a75f120f xen/arch/x86/vmx_vlapic.c --- a/xen/arch/x86/vmx_vlapic.c Mon Nov 7 15:35:46 2005 +++ b/xen/arch/x86/vmx_vlapic.c Mon Nov 7 15:36:27 2005 @@ -307,6 +307,11 @@ vlapic_clear_isr(vlapic, vector); vlapic_update_ppr(vlapic); + + if (test_and_clear_bit(vector, &vlapic->tmr[0])) { + extern void ioapic_update_EOI(struct domain *d, int vector); + ioapic_update_EOI(vlapic->domain, vector); + } } int vlapic_check_vector(struct vlapic *vlapic, @@ -969,6 +974,8 @@ vlapic->spurious_vec = 0xff; + vmx_vioapic_add_lapic(vlapic, v); + init_ac_timer(&vlapic->vlapic_timer, vlapic_timer_fn, vlapic, v->processor); diff -r 781b6dd73e4c -r 9bb7a75f120f xen/arch/x86/vmx_vmcs.c --- a/xen/arch/x86/vmx_vmcs.c Mon Nov 7 15:35:46 2005 +++ b/xen/arch/x86/vmx_vmcs.c Mon Nov 7 15:36:27 2005 @@ -28,6 +28,7 @@ #include <asm/processor.h> #include <asm/msr.h> #include <asm/vmx.h> +#include <asm/vmx_vioapic.h> #include <asm/flushtlb.h> #include <xen/event.h> #include <xen/kernel.h> @@ -255,6 +256,7 @@ if ( vmx_apic_support(d) ) { spin_lock_init(&d->arch.vmx_platform.round_robin_lock); + vmx_vioapic_init(d); } } diff -r 781b6dd73e4c -r 9bb7a75f120f xen/include/asm-x86/vmx_platform.h --- a/xen/include/asm-x86/vmx_platform.h Mon Nov 7 15:35:46 2005 +++ b/xen/include/asm-x86/vmx_platform.h Mon Nov 7 15:36:27 2005 @@ -24,6 +24,7 @@ #include <asm/e820.h> #include <asm/vmx_virpit.h> #include <asm/vmx_intercept.h> +#include <asm/vmx_vioapic.h> #include <public/io/vmx_vpic.h> #define MAX_OPERAND_NUM 2 @@ -85,6 +86,7 @@ struct vmx_virpit vmx_pit; struct vmx_io_handler vmx_io_handler; struct vmx_virpic vmx_pic; + struct vmx_vioapic vmx_vioapic; unsigned char round_info[256]; spinlock_t round_robin_lock; int interrupt_request; diff -r 781b6dd73e4c -r 9bb7a75f120f xen/include/asm-x86/vmx_vmcs.h --- a/xen/include/asm-x86/vmx_vmcs.h Mon Nov 7 15:35:46 2005 +++ b/xen/include/asm-x86/vmx_vmcs.h Mon Nov 7 15:36:27 2005 @@ -284,7 +284,8 @@ #define DBG_LEVEL_VMMU (1 << 5) #define DBG_LEVEL_VLAPIC (1 << 6) #define DBG_LEVEL_VLAPIC_TIMER (1 << 7) -#define DBG_LEVEL_VLAPIC_INTERRUPT (1 << 7) +#define DBG_LEVEL_VLAPIC_INTERRUPT (1 << 8) +#define DBG_LEVEL_IOAPIC (1 << 9) extern unsigned int opt_vmx_debug_level; #define VMX_DBG_LOG(level, _f, _a...) \ diff -r 781b6dd73e4c -r 9bb7a75f120f xen/arch/x86/dm/vmx_vioapic.c --- /dev/null Mon Nov 7 15:35:46 2005 +++ b/xen/arch/x86/dm/vmx_vioapic.c Mon Nov 7 15:36:27 2005 @@ -0,0 +1,608 @@ +/* +* Copyright (C) 2001 MandrakeSoft S.A. +* +* MandrakeSoft S.A. +* 43, rue d'Aboukir +* 75002 Paris - France +* http://www.linux-mandrake.com/ +* http://www.mandrakesoft.com/ +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* +* Yunhong Jiang <yunhong.jiang@xxxxxxxxx> +* Ported to xen by using virtual IRQ line. +*/ + +#include <asm/vmx_vioapic.h> +#include <asm/vmx_platform.h> + +#include <xen/config.h> +#include <xen/types.h> +#include <xen/mm.h> +#include <xen/xmalloc.h> +#include <xen/lib.h> +#include <xen/errno.h> +#include <xen/sched.h> +#include <public/io/ioreq.h> +#include <asm/vmx.h> +#include <public/io/vmx_vpic.h> +#include <asm/current.h> + +static void ioapic_enable(vmx_vioapic_t *s, uint8_t enable) +{ + if (enable) + s->flags |= IOAPIC_ENABLE_FLAG; + else + s->flags &= ~IOAPIC_ENABLE_FLAG; +} + +static void ioapic_dump_redir(vmx_vioapic_t *s, uint8_t entry) +{ + ASSERT(s); + + RedirStatus redir = s->redirtbl[entry]; + + VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_dump_redir " + "entry %x vector %x deliver_mod %x destmode %x delivestatus %x " + "polarity %x remote_irr %x trigmod %x mask %x dest_id %x\n", + entry, redir.RedirForm.vector, redir.RedirForm.deliver_mode, + redir.RedirForm.destmode, redir.RedirForm.delivestatus, + redir.RedirForm.polarity, redir.RedirForm.remoteirr, + redir.RedirForm.trigmod, redir.RedirForm.mask, + redir.RedirForm.dest_id); +} + +#ifdef VMX_DOMAIN_SAVE_RESTORE +void ioapic_save(QEMUFile* f, void* opaque) +{ + printk("no implementation for ioapic_save\n"); +} + +int ioapic_load(QEMUFile* f, void* opaque, int version_id) +{ + printk("no implementation for ioapic_load\n"); + return 0; +} +#endif + +static unsigned long vmx_vioapic_read_indirect(struct vmx_vioapic *s, + unsigned long addr, + unsigned long length) +{ + unsigned long result = 0; + + ASSERT(s); + + switch (s->ioregsel) { + case IOAPIC_REG_VERSION: + result = ((((IOAPIC_NUM_PINS-1) & 0xff) << 16) + | (IOAPIC_VERSION_ID & 0x0f)); + break; + +#ifndef __ia64__ + case IOAPIC_REG_APIC_ID: + result = ((s->id & 0xf) << 24); + break; + + case IOAPIC_REG_ARB_ID: + /* XXX how arb_id used on p4? */ + result = ((s->id & 0xf) << 24); + break; +#endif + + default: + { + uint32_t redir_index = 0; + uint64_t redir_content = 0; + + redir_index = (s->ioregsel - 0x10) >> 1; + + if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS) { + redir_content = s->redirtbl[redir_index].value; + + result = (s->ioregsel & 0x1)? + (redir_content >> 32) & 0xffffffff : + redir_content & 0xffffffff; + } else { + printk("upic_mem_readl:undefined ioregsel %x\n", + s->ioregsel); + domain_crash_synchronous(); + } + break; + } + } /* switch */ + + return result; +} + +static unsigned long vmx_vioapic_read(struct vcpu *v, + unsigned long addr, + unsigned long length) +{ + struct vmx_vioapic *s = &(v->domain->arch.vmx_platform.vmx_vioapic); + uint32_t result = 0; + + VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "vmx_vioapic_read addr %lx\n", addr); + + ASSERT(s); + + addr &= 0xff; + + switch (addr) { + case IOAPIC_REG_SELECT: + result = s->ioregsel; + break; + + case IOAPIC_REG_WINDOW: + result = vmx_vioapic_read_indirect(s, addr, length); + break; + + default: + break; + } + + return result; +} + +static void vmx_vioapic_write_indirect(struct vmx_vioapic *s, + unsigned long addr, + unsigned long length, + unsigned long val) +{ + switch (s->ioregsel) { + case IOAPIC_REG_VERSION: + printk("vmx_vioapic_write_indirect: version register read only\n"); + break; + +#ifndef __ia64__ + case IOAPIC_REG_APIC_ID: + s->id = (val >> 24) & 0xf; + break; + + case IOAPIC_REG_ARB_ID: + s->arb_id = val; + break; +#endif + + default: + { + uint32_t redir_index = 0; + + VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "vmx_vioapic_write_indirect " + "change redir index %x val %lx\n", + redir_index, val); + + redir_index = (s->ioregsel - 0x10) >> 1; + + if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS) { + uint64_t redir_content; + + redir_content = s->redirtbl[redir_index].value; + + if (s->ioregsel & 0x1) + redir_content = (((uint64_t)val & 0xffffffff) << 32) | + (redir_content & 0xffffffff); + else + redir_content = ((redir_content >> 32) << 32) | + (val & 0xffffffff); + s->redirtbl[redir_index].value = redir_content; + } else { + printk("vmx_vioapic_write_indirect " + "error register %x\n", s->ioregsel); + } + break; + } + } /* switch */ +} + +static void vmx_vioapic_write(struct vcpu *v, + unsigned long addr, + unsigned long length, + unsigned long val) +{ + vmx_vioapic_t *s = &(v->domain->arch.vmx_platform.vmx_vioapic); + + ASSERT(s); + + addr &= 0xff; + + switch (addr) { + case IOAPIC_REG_SELECT: + s->ioregsel = val; + break; + + case IOAPIC_REG_WINDOW: + vmx_vioapic_write_indirect(s, addr, length, val); + break; + +#ifdef __ia64__ + case IOAPIC_REG_EOI: + ioapic_update_EOI(v->domain, val); + break; +#endif + + default: + break; + } +} + +static int vmx_vioapic_range(struct vcpu *v, unsigned long addr) +{ + vmx_vioapic_t *s = &(v->domain->arch.vmx_platform.vmx_vioapic); + + if ((s->flags & IOAPIC_ENABLE_FLAG) && + (addr >= s->base_address && + (addr <= s->base_address + IOAPIC_MEM_LENGTH))) + return 1; + else + return 0; +} + +struct vmx_mmio_handler vioapic_mmio_handler = { + .check_handler = vmx_vioapic_range, + .read_handler = vmx_vioapic_read, + .write_handler = vmx_vioapic_write +}; + +static void vmx_vioapic_reset(vmx_vioapic_t *s) +{ + int i; + + memset(s, 0, sizeof(vmx_vioapic_t)); + + for (i = 0; i < IOAPIC_NUM_PINS; i++) + s->redirtbl[i].RedirForm.mask = 0x1; +} + +static void ioapic_update_config(vmx_vioapic_t *s, + unsigned long address, + uint8_t enable) +{ + ASSERT(s); + + ioapic_enable(s, enable); + + if (address != s->base_address) + s->base_address = address; +} + +static int ioapic_inj_irq(vmx_vioapic_t *s, + struct vlapic * target, + uint8_t vector, + uint8_t trig_mode, + uint8_t delivery_mode) +{ + int result = 0; + + ASSERT(s && target); + + VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_inj_irq " + "irq %d trig %d delive mode %d\n", + vector, trig_mode, delivery_mode); + + switch (delivery_mode) { + case VLAPIC_DELIV_MODE_FIXED: + case VLAPIC_DELIV_MODE_LPRI: + if (test_and_set_bit(vector, &target->irr[0]) && trig_mode == 1) { + /* the level interrupt should not happen before it is cleard */ + printk("<ioapic_inj_irq> level interrupt happen before cleard\n"); + } + if (trig_mode) + test_and_set_bit(vector, &target->tmr[0]); + result = 1; + break; + default: + printk("<ioapic_inj_irq> error delivery mode %d\n", + delivery_mode); + break; + } + + return result; +} + +#ifndef __ia64__ +static int ioapic_match_logical_addr(vmx_vioapic_t *s, int number, uint8_t dest) +{ + int result = 0; + + ASSERT(s && s->lapic_info[number]); + + VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_match_logical_addr " + "number %i dest %x\n", + number, dest); + + switch (((s->lapic_info[number]->dest_format >> 28) & 0xf)) { + case 0xf: + result = + (dest & ((s->lapic_info[number]->logical_dest >> 24) & 0xff)) != 0; + break; + case 0x0: + /* Should we support flat cluster mode ?*/ + if ( ((s->lapic_info[number]->logical_dest >> 28) + == ((dest >> 0x4) & 0xf)) && + (((s->lapic_info[number]->logical_dest >> 24) & 0xf) + & (dest & 0xf)) ) + result = 1; + break; + default: + printk("error DFR value for %x local apic\n", number); + break; + } + + return result; +} +#else +extern int ioapic_match_logical_addr(vmx_vioapic_t *s, int number, uint8_t dest); +#endif + +static uint32_t ioapic_get_delivery_bitmask(vmx_vioapic_t *s, + uint16_t dest, + uint8_t dest_mode, + uint8_t vector, + uint8_t delivery_mode) +{ + uint32_t mask = 0; + int i; + + VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask " + "dest %d dest_mode %d " + "vector %d del_mode %d, lapic_count %d\n", + dest, dest_mode, vector, delivery_mode, s->lapic_count); + + ASSERT(s); + + if (dest_mode == 0) { /* Physical mode */ + for (i = 0; i < s->lapic_count; i++) { + if (s->lapic_info[i]->id == dest) { + mask = 1 << i; + break; + } + } + } else { + /* logical destination. call match_logical_addr for each APIC. */ + if (dest != 0) { + for (i=0; i< s->lapic_count; i++) { + if ( s->lapic_info[i] && + ioapic_match_logical_addr(s, i, dest) ) { + mask |= (1<<i); + } + } + } + } + + VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask " + "mask %x\n", mask); + + return mask; +} + +static void ioapic_deliver(vmx_vioapic_t *s, int irqno) +{ + uint16_t dest = s->redirtbl[irqno].RedirForm.dest_id; + uint8_t dest_mode = s->redirtbl[irqno].RedirForm.destmode; + uint8_t delivery_mode = s->redirtbl[irqno].RedirForm.deliver_mode; + uint8_t vector = s->redirtbl[irqno].RedirForm.vector; + uint8_t trig_mode = s->redirtbl[irqno].RedirForm.trigmod; + uint32_t deliver_bitmask; + + VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "IOAPIC deliver: " + "dest %x dest_mode %x delivery_mode %x vector %x trig_mode %x\n", + dest, dest_mode, delivery_mode, vector, trig_mode); + + deliver_bitmask = + ioapic_get_delivery_bitmask(s, dest, dest_mode, vector, delivery_mode); + + if (!deliver_bitmask) { + VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver " + "no target on destination\n"); + + return; + } + + switch (delivery_mode) { + case VLAPIC_DELIV_MODE_LPRI: + { + struct vlapic* target; + + target = apic_round_robin( + s->domain, dest_mode, vector, deliver_bitmask); + ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode); + break; + } + + case VLAPIC_DELIV_MODE_FIXED: + case VLAPIC_DELIV_MODE_EXT: + { + uint8_t bit; + for (bit = 0; bit < s->lapic_count; bit++) { + if (deliver_bitmask & (1 << bit)) { + if (s->lapic_info[bit]) { + ioapic_inj_irq(s, s->lapic_info[bit], + vector, trig_mode, delivery_mode); + } + } + } + break; + } + + case VLAPIC_DELIV_MODE_SMI: + case VLAPIC_DELIV_MODE_NMI: + case VLAPIC_DELIV_MODE_INIT: + case VLAPIC_DELIV_MODE_STARTUP: + default: + printk("Not support delivey mode %d\n", delivery_mode); + break; + } +} + +static int ioapic_get_highest_irq(vmx_vioapic_t *s) +{ + uint32_t irqs; + + ASSERT(s); + + irqs = s->irr & ~s->isr; + return __fls(irqs); +} + + +static void service_ioapic(vmx_vioapic_t *s) +{ + int irqno; + + while ((irqno = ioapic_get_highest_irq(s)) != -1) { + + VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "service_ioapic " + "highest irqno %x\n", irqno); + + if (!s->redirtbl[irqno].RedirForm.mask) { + ioapic_deliver(s, irqno); + } + + if (s->redirtbl[irqno].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER) { + s->isr |= (1 << irqno); + } + + s->irr &= ~(1 << irqno); + } +} + +void vmx_vioapic_do_irqs(struct domain *d, uint16_t irqs) +{ + vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic); + + if (!vmx_apic_support(d)) + return; + + s->irr |= irqs; + service_ioapic(s); +} + +void vmx_vioapic_do_irqs_clear(struct domain *d, uint16_t irqs) +{ + vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic); + + if (!vmx_apic_support(d)) + return; + + s->irr &= ~irqs; + service_ioapic(s); +} + +void vmx_vioapic_set_irq(struct domain *d, int irq, int level) +{ + vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic); + + if (!vmx_apic_support(d)) + return ; + + VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_set_irq " + "irq %x level %x\n", irq, level); + + if (irq < 0 || irq >= IOAPIC_NUM_PINS) { + printk("ioapic_set_irq irq %x is illegal\n", irq); + domain_crash_synchronous(); + } + + if (!IOAPICEnabled(s) || s->redirtbl[irq].RedirForm.mask) + return; + + ioapic_dump_redir(s, irq); + + if (irq >= 0 && irq < IOAPIC_NUM_PINS) { + uint32_t bit = 1 << irq; + if (s->redirtbl[irq].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER) { + if (level) + s->irr |= bit; + else + s->irr &= ~bit; + } else { + if (level) + /* XXX No irr clear for edge interrupt */ + s->irr |= bit; + } + } + + service_ioapic(s); +} + +/* XXX If level interrupt, use vector->irq table for performance */ +static int get_redir_num(vmx_vioapic_t *s, int vector) +{ + int i = 0; + + ASSERT(s); + + for(i = 0; i < IOAPIC_NUM_PINS - 1; i++) { + if (s->redirtbl[i].RedirForm.vector == vector) + return i; + } + + return -1; +} + +void ioapic_update_EOI(struct domain *d, int vector) +{ + vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic); + int redir_num; + + if ((redir_num = get_redir_num(s, vector)) == -1) { + printk("Can't find redir item for %d EOI \n", vector); + return; + } + + if (!test_and_clear_bit(redir_num, &s->isr)) { + printk("redir %d not set for %d EOI\n", redir_num, vector); + return; + } +} + +int vmx_vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v) +{ + vmx_vioapic_t *s = &(v->domain->arch.vmx_platform.vmx_vioapic); + + if (v->vcpu_id != s->lapic_count) { + printk("vmx_vioapic_add_lapic " + "cpu_id not match vcpu_id %x lapic_count %x\n", + v->vcpu_id, s->lapic_count); + domain_crash_synchronous(); + } + + s->lapic_info[s->lapic_count ++] = vlapic; + + return s->lapic_count; +} + +vmx_vioapic_t * vmx_vioapic_init(struct domain *d) +{ + int i = 0; + vmx_vioapic_t *s = &(d->arch.vmx_platform.vmx_vioapic); + + VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "vmx_vioapic_init\n"); + + vmx_vioapic_reset(s); + + s->domain = d; + + for (i = 0; i < MAX_LAPIC_NUM; i++) + s->lapic_info[i] = NULL; + + /* Remove after GFW ready */ + ioapic_update_config(s, IOAPIC_DEFAULT_BASE_ADDRESS, 1); + + return s; +} diff -r 781b6dd73e4c -r 9bb7a75f120f xen/include/asm-x86/vmx_vioapic.h --- /dev/null Mon Nov 7 15:35:46 2005 +++ b/xen/include/asm-x86/vmx_vioapic.h Mon Nov 7 15:36:27 2005 @@ -0,0 +1,136 @@ +/* + * + * Copyright (C) 2001 MandrakeSoft S.A. + * + * MandrakeSoft S.A. + * 43, rue d'Aboukir + * 75002 Paris - France + * http://www.linux-mandrake.com/ + * http://www.mandrakesoft.com/ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _IOAPIC_H_ +#define _IOAPIC_H_ + +#include <xen/config.h> +#include <xen/types.h> +#include <xen/smp.h> + +#ifndef __ia64__ +#define IOAPIC_VERSION_ID 0x11 +#else +#define IOAPIC_VERSION_ID 0x21 +#endif + +#define IOAPIC_NUM_PINS 24 +#define MAX_LAPIC_NUM 32 + +#define IOAPIC_LEVEL_TRIGGER 1 + +#define IOAPIC_DEFAULT_BASE_ADDRESS 0xfec00000 +#define IOAPIC_MEM_LENGTH 0x100 + +#define IOAPIC_ENABLE_MASK 0x0 +#define IOAPIC_ENABLE_FLAG (1 << IOAPIC_ENABLE_MASK) +#define IOAPICEnabled(s) (s->flags & IOAPIC_ENABLE_FLAG) + +#define IOAPIC_REG_SELECT 0x0 +#define IOAPIC_REG_WINDOW 0x10 + +#ifdef __ia64__ +#define IOAPIC_REG_ASSERTION 0x20 +#define IOAPIC_REG_EOI 0x40 +#endif + +#ifndef __ia64__ +#define IOAPIC_REG_APIC_ID 0x0 +#define IOAPIC_REG_ARB_ID 0x2 +#endif + +#define IOAPIC_REG_VERSION 0x1 + +#ifdef __ia64__ +typedef union RedirStatus +{ + uint64_t value; + struct { + uint16_t dest_id; + uint8_t reserved[3]; + uint8_t reserve:7; + uint8_t mask:1; /* interrupt mask*/ + uint8_t trigmod:1; + uint8_t remoteirr:1; + uint8_t polarity:1; + uint8_t delivestatus:1; + uint8_t destmode:1; + uint8_t deliver_mode:3; + uint8_t vector; + } RedirForm; +} RedirStatus; +#else +typedef union RedirStatus +{ + uint64_t value; + struct { + uint8_t vector; + uint8_t deliver_mode:3; + uint8_t destmode:1; + uint8_t delivestatus:1; + uint8_t polarity:1; + uint8_t remoteirr:1; + uint8_t trigmod:1; + uint8_t mask:1; /* interrupt mask*/ + uint8_t reserve:7; + uint8_t reserved[4]; + uint8_t dest_id; + } RedirForm; +} RedirStatus; +#endif + +#define IOAPIC_MEM_LENGTH 0x100 +#define IOAPIC_ENABLE_MASK 0x0 +#define IOAPIC_ENABLE_FLAG (1 << IOAPIC_ENABLE_MASK) +#define MAX_LAPIC_NUM 32 + +typedef struct vmx_vioapic { + uint32_t ioregsel; + uint32_t irr; + uint32_t isr; /* This is used for level trigger */ + uint32_t flags; + uint32_t lapic_count; + uint32_t id; + uint32_t arb_id; + unsigned long base_address; + RedirStatus redirtbl[IOAPIC_NUM_PINS]; + struct vlapic *lapic_info[MAX_LAPIC_NUM]; + struct domain *domain; +} vmx_vioapic_t; + +vmx_vioapic_t *vmx_vioapic_init(struct domain *d); + +void vmx_vioapic_do_irqs_clear(struct domain *d, uint16_t irqs); +void vmx_vioapic_do_irqs(struct domain *d, uint16_t irqs); +void vmx_vioapic_set_irq(struct domain *d, int irq, int level); + +int vmx_vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v); + +#ifdef VMX_DOMAIN_SAVE_RESTORE +void ioapic_save(QEMUFile* f, void* opaque); +int ioapic_load(QEMUFile* f, void* opaque, int version_id); +#endif + +#endif _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |