This patch add virtual IOAPIC support for VMX guest.

Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Signed-off-by: Xin Li <xin.b.li@intel.com>
Signed-off-by: Eddie Dong <eddie.dong@intel.com>
Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2005-11-07 16:36:27 +01:00
1 parent 27ec4c403f
commit 4fe21ad371
8 files changed
+772 -4

No files matched your search

+11 -1
View File
@@ -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 @@ void pic_set_irq_new(void *opaque, int irq, int level)
{
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 @@ void do_pic_irqs (struct vmx_virpic *s, uint16_t irqs)
{
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 @@ void do_pic_irqs_clear (struct vmx_virpic *s, uint16_t irqs)
{
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 cpu_get_pic_interrupt(struct vcpu *v, int *type)
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);
}
+608
View File
@@ -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@intel.com>
* 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;
}
+4 -2
View File
@@ -34,12 +34,14 @@
#ifdef CONFIG_VMX
extern struct vmx_mmio_handler vlapic_mmio_handler;
extern struct vmx_mmio_handler vioapic_mmio_handler;
#define VMX_MMIO_HANDLER_NR 1
#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,
+7
View File
@@ -307,6 +307,11 @@ vlapic_EOI_set(struct vlapic *vlapic)
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 @@ static int vlapic_reset(struct vlapic *vlapic)
vlapic->spurious_vec = 0xff;
vmx_vioapic_add_lapic(vlapic, v);
init_ac_timer(&vlapic->vlapic_timer,
vlapic_timer_fn, vlapic, v->processor);
+2
View File
@@ -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 @@ static void vmx_setup_platform(struct domain* d)
if ( vmx_apic_support(d) ) {
spin_lock_init(&d->arch.vmx_platform.round_robin_lock);
vmx_vioapic_init(d);
}
}
+2
View File
@@ -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_platform {
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;
+136
View File
@@ -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
+2 -1
View File
@@ -284,7 +284,8 @@ enum vmcs_field {
#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...) \
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.