# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID a6cb8ba24a914854c56d002132c13649306274ec
# Parent 637b6d60e792aaebe147fc900be4d27ddeb9bf74
[HVM] Place all APIC registers into one page in native format.
With this change we can re-use code at include/asm-x86/apicdef.h,
making the code much cleaner. Also it help for future enhancement.
This patch does not change any logic except the change to
CONTROL_REG_ACCESS_NUM, which should be 0xf for CR8 access.
Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx
---
xen/arch/x86/hvm/i8259.c | 4
xen/arch/x86/hvm/svm/intr.c | 18 -
xen/arch/x86/hvm/vioapic.c | 37 +-
xen/arch/x86/hvm/vlapic.c | 555 ++++++++++++++++--------------------
xen/arch/x86/hvm/vmx/io.c | 17 -
xen/arch/x86/hvm/vmx/vmx.c | 2
xen/include/asm-ia64/vmx_platform.h | 11
xen/include/asm-x86/hvm/support.h | 2
xen/include/asm-x86/hvm/vlapic.h | 113 ++-----
xen/include/asm-x86/hvm/vmx/vmx.h | 2
10 files changed, 346 insertions(+), 415 deletions(-)
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/arch/x86/hvm/i8259.c
--- a/xen/arch/x86/hvm/i8259.c Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/arch/x86/hvm/i8259.c Wed Aug 02 10:07:03 2006 +0100
@@ -590,7 +590,7 @@ int cpu_get_pic_interrupt(struct vcpu *v
/* read the irq from the PIC */
intno = pic_read_irq(s);
- *type = VLAPIC_DELIV_MODE_EXT;
+ *type = APIC_DM_EXTINT;
return intno;
}
@@ -598,7 +598,7 @@ int is_pit_irq(struct vcpu *v, int irq,
{
int pit_vec;
- if (type == VLAPIC_DELIV_MODE_EXT)
+ if (type == APIC_DM_EXTINT)
pit_vec = v->domain->arch.hvm_domain.vpic.pics[0].irq_base;
else
pit_vec =
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/arch/x86/hvm/svm/intr.c Wed Aug 02 10:07:03 2006 +0100
@@ -76,7 +76,7 @@ interrupt_post_injection(struct vcpu * v
switch(type)
{
- case VLAPIC_DELIV_MODE_EXT:
+ case APIC_DM_EXTINT:
break;
default:
@@ -112,7 +112,7 @@ asmlinkage void svm_intr_assist(void)
struct hvm_domain *plat=&v->domain->arch.hvm_domain;
struct periodic_time *pt = &plat->pl_time.periodic_tm;
struct hvm_virpic *pic= &plat->vpic;
- int intr_type = VLAPIC_DELIV_MODE_EXT;
+ int intr_type = APIC_DM_EXTINT;
int intr_vector = -1;
int re_injecting = 0;
unsigned long rflags;
@@ -172,9 +172,9 @@ asmlinkage void svm_intr_assist(void)
/* have we got an interrupt to inject? */
if (intr_vector >= 0) {
switch (intr_type) {
- case VLAPIC_DELIV_MODE_EXT:
- case VLAPIC_DELIV_MODE_FIXED:
- case VLAPIC_DELIV_MODE_LPRI:
+ case APIC_DM_EXTINT:
+ case APIC_DM_FIXED:
+ case APIC_DM_LOWEST:
/* Re-injecting a PIT interruptt? */
if (re_injecting &&
is_pit_irq(v, intr_vector, intr_type)) {
@@ -185,10 +185,10 @@ asmlinkage void svm_intr_assist(void)
svm_inject_extint(v, intr_vector, VMX_DELIVER_NO_ERROR_CODE);
interrupt_post_injection(v, intr_vector, intr_type);
break;
- case VLAPIC_DELIV_MODE_SMI:
- case VLAPIC_DELIV_MODE_NMI:
- case VLAPIC_DELIV_MODE_INIT:
- case VLAPIC_DELIV_MODE_STARTUP:
+ case APIC_DM_SMI:
+ case APIC_DM_NMI:
+ case APIC_DM_INIT:
+ case APIC_DM_STARTUP:
default:
printk("Unsupported interrupt type: %d\n", intr_type);
BUG();
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/arch/x86/hvm/vioapic.c Wed Aug 02 10:07:03 2006 +0100
@@ -197,7 +197,7 @@ static void hvm_vioapic_write_indirect(s
redir_content = ((redir_content >> 32) << 32) |
(val & 0xffffffff);
s->redirtbl[redir_index].value = redir_content;
- hvm_vioapic_update_imr(s, redir_index);
+ hvm_vioapic_update_imr(s, redir_index);
} else {
printk("hvm_vioapic_write_indirect "
"error register %x\n", s->ioregsel);
@@ -295,8 +295,8 @@ static int ioapic_inj_irq(hvm_vioapic_t
vector, trig_mode, delivery_mode);
switch (delivery_mode) {
- case VLAPIC_DELIV_MODE_FIXED:
- case VLAPIC_DELIV_MODE_LPRI:
+ case dest_Fixed:
+ case dest_LowestPrio:
if (vlapic_set_irq(target, vector, trig_mode) && (trig_mode == 1))
printk("<ioapic_inj_irq> level interrupt happen before cleared\n");
result = 1;
@@ -314,6 +314,7 @@ static int ioapic_match_logical_addr(hvm
static int ioapic_match_logical_addr(hvm_vioapic_t *s, int number, uint8_t
dest)
{
int result = 0;
+ uint32_t logical_dest = vlapic_get_reg(s->lapic_info[number], APIC_LDR);
ASSERT(s && s->lapic_info[number]);
@@ -321,17 +322,17 @@ static int ioapic_match_logical_addr(hvm
"number %i dest %x\n",
number, dest);
- switch (((s->lapic_info[number]->dest_format >> 28) & 0xf)) {
- case 0xf:
+ switch (vlapic_get_reg(s->lapic_info[number], APIC_DFR))
+ {
+ case APIC_DFR_FLAT:
result =
- (dest & ((s->lapic_info[number]->logical_dest >> 24) & 0xff)) != 0;
- break;
- case 0x0:
+ (dest & GET_APIC_LOGICAL_ID(logical_dest)) != 0;
+ break;
+ case APIC_DFR_CLUSTER:
/* Should we support flat cluster mode ?*/
- if ( ((s->lapic_info[number]->logical_dest >> 28)
+ if ( (GET_APIC_LOGICAL_ID(logical_dest) >> 4
== ((dest >> 0x4) & 0xf)) &&
- (((s->lapic_info[number]->logical_dest >> 24) & 0xf)
- & (dest & 0xf)) )
+ (logical_dest & (dest & 0xf)) )
result = 1;
break;
default:
@@ -410,7 +411,7 @@ static void ioapic_deliver(hvm_vioapic_t
}
switch (delivery_mode) {
- case VLAPIC_DELIV_MODE_LPRI:
+ case dest_LowestPrio:
{
struct vlapic* target;
@@ -430,8 +431,8 @@ static void ioapic_deliver(hvm_vioapic_t
break;
}
- case VLAPIC_DELIV_MODE_FIXED:
- case VLAPIC_DELIV_MODE_EXT:
+ case dest_Fixed:
+ case dest_ExtINT:
{
uint8_t bit;
for (bit = 0; bit < s->lapic_count; bit++) {
@@ -452,10 +453,10 @@ static void ioapic_deliver(hvm_vioapic_t
break;
}
- case VLAPIC_DELIV_MODE_SMI:
- case VLAPIC_DELIV_MODE_NMI:
- case VLAPIC_DELIV_MODE_INIT:
- case VLAPIC_DELIV_MODE_STARTUP:
+ case dest_SMI:
+ case dest_NMI:
+ case dest_INIT:
+ case dest__reserved_2:
default:
printk("Not support delivey mode %d\n", delivery_mode);
break;
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/arch/x86/hvm/vlapic.c Wed Aug 02 10:07:03 2006 +0100
@@ -43,35 +43,43 @@ extern u32 get_apic_bus_cycle(void);
static unsigned int vlapic_lvt_mask[VLAPIC_LVT_NUM] =
{
- 0x310ff, 0x117ff, 0x117ff, 0x1f7ff, 0x1f7ff, 0x117ff
+ /* LVTT */
+ LVT_MASK | APIC_LVT_TIMER_PERIODIC,
+ /* LVTTHMR */
+ LVT_MASK | APIC_MODE_MASK,
+ /* LVTPC */
+ LVT_MASK | APIC_MODE_MASK,
+ /* LVT0-1 */
+ LINT_MASK, LINT_MASK,
+ /* LVTERR */
+ LVT_MASK
};
+int hvm_apic_support(struct domain *d)
+{
+ return d->arch.hvm_domain.apic_enabled;
+}
+
int vlapic_find_highest_irr(struct vlapic *vlapic)
{
int result;
- result = find_highest_bit(vlapic->irr, MAX_VECTOR);
-
- if ( result != -1 && result < 16 )
- {
- printk("VLAPIC: irr on reserved bits %d\n ", result);
- domain_crash_synchronous();
- }
-
- return result;
-}
-
-int hvm_apic_support(struct domain *d)
-{
- return d->arch.hvm_domain.apic_enabled;
+ result = find_highest_bit((unsigned long *)(vlapic->regs + APIC_IRR),
+ MAX_VECTOR);
+
+ ASSERT( result == -1 || result > 16);
+
+ return result;
}
s_time_t get_apictime_scheduled(struct vcpu *v)
{
struct vlapic *vlapic = VLAPIC(v);
- if ( !hvm_apic_support(v->domain) || !vlapic_lvt_timer_enabled(vlapic) )
+ if ( !hvm_apic_support(v->domain) ||
+ !vlapic_lvt_enabled(vlapic, APIC_LVTT) )
return -1;
+
return vlapic->vlapic_timer.expires;
}
@@ -79,16 +87,10 @@ int vlapic_find_highest_isr(struct vlapi
{
int result;
- result = find_highest_bit(vlapic->isr, MAX_VECTOR);
-
- if ( result != -1 && result < 16 )
- {
- int i = 0;
- printk("VLAPIC: isr on reserved bits %d, isr is\n ", result);
- for ( i = 0; i < ARRAY_SIZE(vlapic->isr); i++ )
- printk("%d: %p\n", i, (void *)vlapic->isr[i]);
- return -1;
- }
+ result = find_highest_bit((unsigned long *)(vlapic->regs + APIC_ISR),
+ MAX_VECTOR);
+
+ ASSERT( result == -1 || result > 16);
return result;
}
@@ -98,20 +100,21 @@ uint32_t vlapic_update_ppr(struct vlapic
uint32_t tpr, isrv, ppr;
int isr;
- tpr = (vlapic->task_priority >> 4) & 0xf; /* we want 7:4 */
+ tpr = vlapic_get_reg(vlapic, APIC_TASKPRI);
isr = vlapic_find_highest_isr(vlapic);
+
if ( isr != -1 )
isrv = (isr >> 4) & 0xf; /* ditto */
else
isrv = 0;
- if ( tpr >= isrv )
- ppr = vlapic->task_priority & 0xff;
+ if ( (tpr >> 4) >= isrv )
+ ppr = tpr & 0xff;
else
ppr = isrv << 4; /* low 4 bits of PPR have to be cleared */
- vlapic->processor_priority = ppr;
+ vlapic_set_reg(vlapic, APIC_PROCPRI, ppr);
HVM_DBG_LOG(DBG_LEVEL_VLAPIC_INTERRUPT,
"vlapic %p, ppr 0x%x, isr 0x%x, isrv 0x%x.",
@@ -133,9 +136,9 @@ static int vlapic_match_dest(struct vcpu
target, source, dest, dest_mode, short_hand, delivery_mode);
if ( unlikely(target == NULL) &&
- ((delivery_mode != VLAPIC_DELIV_MODE_INIT) &&
- (delivery_mode != VLAPIC_DELIV_MODE_STARTUP) &&
- (delivery_mode != VLAPIC_DELIV_MODE_NMI)) )
+ ((delivery_mode != APIC_DM_INIT) &&
+ (delivery_mode != APIC_DM_STARTUP) &&
+ (delivery_mode != APIC_DM_NMI)) )
{
HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "uninitialized target vcpu %p, "
"delivery_mode 0x%x, dest 0x%x.\n", v, delivery_mode,
dest);
@@ -143,22 +146,27 @@ static int vlapic_match_dest(struct vcpu
}
switch ( short_hand ) {
- case VLAPIC_NO_SHORTHAND:
+ case APIC_DEST_NOSHORT: /* no shorthand */
if ( !dest_mode ) /* Physical */
{
- result = (target != NULL ? target->id : v->vcpu_id) == dest;
+ result = ( ((target != NULL) ?
+ GET_APIC_ID(vlapic_get_reg(target, APIC_ID)):
+ v->vcpu_id)) == dest;
}
else /* Logical */
{
+ uint32_t ldr = vlapic_get_reg(target, APIC_LDR);
+
if ( target == NULL )
break;
- if ( ((target->dest_format >> 28) & 0xf) == 0xf ) /* Flat mode */
+ /* Flat mode */
+ if ( vlapic_get_reg(target, APIC_DFR) == APIC_DFR_FLAT)
{
- result = (target->logical_dest >> 24) & dest;
+ result = GET_APIC_LOGICAL_ID(ldr) & dest;
}
else
{
- if ( (delivery_mode == VLAPIC_DELIV_MODE_LPRI) &&
+ if ( (delivery_mode == APIC_DM_LOWEST) &&
(dest == 0xff) )
{
/* What shall we do now? */
@@ -166,22 +174,22 @@ static int vlapic_match_dest(struct vcpu
"delivery mode\n");
domain_crash_synchronous();
}
- result = (target->logical_dest == (dest & 0xf)) ?
- ((target->logical_dest >> 4) & (dest >> 4)) : 0;
+ result = (GET_APIC_LOGICAL_ID(ldr) == (dest & 0xf)) ?
+ (GET_APIC_LOGICAL_ID(ldr) >> 4) & (dest >> 4) : 0;
}
}
break;
- case VLAPIC_SHORTHAND_SELF:
+ case APIC_DEST_SELF:
if ( target == source )
result = 1;
break;
- case VLAPIC_SHORTHAND_INCLUDE_SELF:
+ case APIC_DEST_ALLINC:
result = 1;
break;
- case VLAPIC_SHORTHAND_EXCLUDE_SELF:
+ case APIC_DEST_ALLBUT:
if ( target != source )
result = 1;
break;
@@ -204,13 +212,13 @@ static int vlapic_accept_irq(struct vcpu
struct vlapic *vlapic = VLAPIC(v);
switch ( delivery_mode ) {
- case VLAPIC_DELIV_MODE_FIXED:
- case VLAPIC_DELIV_MODE_LPRI:
+ case APIC_DM_FIXED:
+ case APIC_DM_LOWEST:
/* FIXME add logic for vcpu on reset */
if ( unlikely(vlapic == NULL || !vlapic_enabled(vlapic)) )
break;
- if ( test_and_set_bit(vector, &vlapic->irr[0]) && level)
+ if ( test_and_set_bit(vector, vlapic->regs + APIC_IRR) )
{
HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
"level trig mode repeatedly for vector %d\n", vector);
@@ -221,25 +229,25 @@ static int vlapic_accept_irq(struct vcpu
{
HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
"level trig mode for vector %d\n", vector);
- set_bit(vector, &vlapic->tmr[0]);
+ set_bit(vector, vlapic->regs + APIC_TMR);
}
evtchn_set_pending(v, iopacket_port(v));
result = 1;
break;
- case VLAPIC_DELIV_MODE_RESERVED:
+ case APIC_DM_REMRD:
printk("Ignore deliver mode 3 in vlapic_accept_irq\n");
break;
- case VLAPIC_DELIV_MODE_SMI:
- case VLAPIC_DELIV_MODE_NMI:
+ case APIC_DM_SMI:
+ case APIC_DM_NMI:
/* Fixme */
printk("TODO: for guest SMI/NMI\n");
break;
- case VLAPIC_DELIV_MODE_INIT:
- if ( !level && trig_mode == 1 ) //Deassert
+ case APIC_DM_INIT:
+ if ( level && !(trig_mode & APIC_INT_ASSERT) ) //Deassert
printk("This hvm_vlapic is for P4, no work for De-assert init\n");
else
{
@@ -255,7 +263,7 @@ static int vlapic_accept_irq(struct vcpu
}
break;
- case VLAPIC_DELIV_MODE_STARTUP:
+ case APIC_DM_STARTUP:
if ( v->arch.hvm_vcpu.init_sipi_sipi_state ==
HVM_VCPU_INIT_SIPI_SIPI_STATE_NORM )
break;
@@ -346,22 +354,23 @@ void vlapic_EOI_set(struct vlapic *vlapi
if ( vector == -1 )
return ;
- clear_bit(vector, &vlapic->isr[0]);
+ clear_bit(vector, vlapic->regs + APIC_ISR);
vlapic_update_ppr(vlapic);
- if ( test_and_clear_bit(vector, &vlapic->tmr[0]) )
+ if ( test_and_clear_bit(vector, vlapic->regs + APIC_TMR) )
ioapic_update_EOI(vlapic->domain, vector);
}
-int vlapic_check_vector(struct vlapic *vlapic,
- unsigned char dm, int vector)
-{
- if ( (dm == VLAPIC_DELIV_MODE_FIXED) && (vector < 16) )
+static int vlapic_check_vector(struct vlapic *vlapic,
+ uint32_t dm, uint32_t vector)
+{
+ if ( (dm == APIC_DM_FIXED) && (vector < 16) )
{
vlapic->err_status |= 0x40;
- vlapic_accept_irq(vlapic->vcpu, VLAPIC_DELIV_MODE_FIXED,
- vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR), 0, 0);
- printk("<vlapic_check_vector>: check failed.\n");
+ vlapic_accept_irq(vlapic->vcpu, APIC_DM_FIXED,
+ vlapic_lvt_vector(vlapic, APIC_LVTERR), 0, 0);
+ printk("<vlapic_check_vector>: check failed "
+ " dm %x vector %x\n", dm, vector);
return 0;
}
return 1;
@@ -369,13 +378,16 @@ int vlapic_check_vector(struct vlapic *v
void vlapic_ipi(struct vlapic *vlapic)
{
- unsigned int dest = (vlapic->icr_high >> 24) & 0xff;
- unsigned int short_hand = (vlapic->icr_low >> 18) & 3;
- unsigned int trig_mode = (vlapic->icr_low >> 15) & 1;
- unsigned int level = (vlapic->icr_low >> 14) & 1;
- unsigned int dest_mode = (vlapic->icr_low >> 11) & 1;
- unsigned int delivery_mode = (vlapic->icr_low >> 8) & 7;
- unsigned int vector = (vlapic->icr_low & 0xff);
+ uint32_t icr_low = vlapic_get_reg(vlapic, APIC_ICR);
+ uint32_t icr_high = vlapic_get_reg(vlapic, APIC_ICR2);
+
+ unsigned int dest = GET_APIC_DEST_FIELD(icr_high);
+ unsigned int short_hand = icr_low & APIC_SHORT_MASK;
+ unsigned int trig_mode = icr_low & APIC_INT_ASSERT;
+ unsigned int level = icr_low & APIC_INT_LEVELTRIG;
+ unsigned int dest_mode = icr_low & APIC_DEST_MASK;
+ unsigned int delivery_mode = icr_low & APIC_MODE_MASK;
+ unsigned int vector = icr_low & APIC_VECTOR_MASK;
struct vlapic *target;
struct vcpu *v = NULL;
@@ -384,7 +396,7 @@ void vlapic_ipi(struct vlapic *vlapic)
HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "icr_high 0x%x, icr_low 0x%x, "
"short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, "
"dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x.",
- vlapic->icr_high, vlapic->icr_low, short_hand, dest,
+ icr_high, icr_low, short_hand, dest,
trig_mode, level, dest_mode, delivery_mode, vector);
for_each_vcpu ( vlapic->domain, v )
@@ -392,7 +404,7 @@ void vlapic_ipi(struct vlapic *vlapic)
if ( vlapic_match_dest(v, vlapic, short_hand,
dest, dest_mode, delivery_mode) )
{
- if ( delivery_mode == VLAPIC_DELIV_MODE_LPRI )
+ if ( delivery_mode == APIC_DM_LOWEST)
set_bit(v->vcpu_id, &lpr_map);
else
vlapic_accept_irq(v, delivery_mode,
@@ -400,7 +412,7 @@ void vlapic_ipi(struct vlapic *vlapic)
}
}
- if ( delivery_mode == VLAPIC_DELIV_MODE_LPRI )
+ if ( delivery_mode == APIC_DM_LOWEST)
{
v = vlapic->vcpu;
target = apic_round_robin(v->domain, dest_mode, vector, lpr_map);
@@ -411,158 +423,73 @@ void vlapic_ipi(struct vlapic *vlapic)
}
}
+static uint32_t vlapic_get_tmcct(struct vlapic *vlapic)
+{
+ uint32_t counter_passed;
+ s_time_t passed, now = NOW();
+ uint32_t tmcct = vlapic_get_reg(vlapic, APIC_TMCCT);
+
+ ASSERT(vlapic != NULL);
+
+ if ( unlikely(now <= vlapic->timer_last_update) )
+ {
+ passed = ~0x0LL - vlapic->timer_last_update + now;
+ HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "time elapsed.");
+ }
+ else
+ passed = now - vlapic->timer_last_update;
+
+ counter_passed = passed /
+ (APIC_BUS_CYCLE_NS * vlapic->timer_divide_count);
+
+ tmcct -= counter_passed;
+
+ if ( tmcct <= 0 )
+ {
+ if ( unlikely(!vlapic_lvtt_period(vlapic)) )
+ {
+ tmcct = 0;
+ // FIXME: should we add interrupt here?
+ }
+ else
+ {
+ do {
+ tmcct += vlapic_get_reg(vlapic, APIC_TMICT);
+ } while ( tmcct < 0 );
+ }
+ }
+
+ vlapic->timer_last_update = now;
+ vlapic_set_reg(vlapic, APIC_TMCCT, tmcct);
+
+ HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER,
+ "timer initial count 0x%x, timer current count 0x%x, "
+ "update 0x%016"PRIx64", now 0x%016"PRIx64", offset 0x%x.",
+ vlapic_get_reg(vlapic, APIC_TMICT),
+ vlapic_get_reg(vlapic, APIC_TMCCT),
+ vlapic->timer_last_update, now, counter_passed);
+
+ return tmcct;
+}
+
static void vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset,
unsigned int len, unsigned int *result)
{
- if ( len != 4 )
- printk("<vlapic_read_aligned> read with len=%d (should be 4).\n", len);
+ ASSERT(len == 4 && offset > 0 && offset <= APIC_TDCR);
*result = 0;
switch ( offset ) {
- case APIC_ID:
- *result = vlapic->id << 24;
- break;
-
- case APIC_LVR:
- *result = vlapic->version;
- break;
-
- case APIC_TASKPRI:
- *result = vlapic->task_priority;
- break;
-
case APIC_ARBPRI:
printk("access local APIC ARBPRI register which is for P6\n");
break;
- case APIC_PROCPRI:
- *result = vlapic->processor_priority;
- break;
-
- case APIC_EOI: /* EOI is write only */
- break;
-
- case APIC_LDR:
- *result = vlapic->logical_dest;
- break;
-
- case APIC_DFR:
- *result = vlapic->dest_format;
- break;
-
- case APIC_SPIV:
- *result = vlapic->spurious_vec;
- break;
-
- case APIC_ISR:
- case 0x110:
- case 0x120:
- case 0x130:
- case 0x140:
- case 0x150:
- case 0x160:
- case 0x170:
- *result = vlapic->isr[(offset - APIC_ISR) >> 4];
- break;
-
- case APIC_TMR:
- case 0x190:
- case 0x1a0:
- case 0x1b0:
- case 0x1c0:
- case 0x1d0:
- case 0x1e0:
- case 0x1f0:
- *result = vlapic->tmr[(offset - APIC_TMR) >> 4];
- break;
-
- case APIC_IRR:
- case 0x210:
- case 0x220:
- case 0x230:
- case 0x240:
- case 0x250:
- case 0x260:
- case 0x270:
- *result = vlapic->irr[(offset - APIC_IRR) >> 4];
- break;
-
- case APIC_ESR:
- if ( vlapic->err_write_count )
- *result = vlapic->err_status;
- break;
-
- case APIC_ICR:
- *result = vlapic->icr_low;
- break;
-
- case APIC_ICR2:
- *result = vlapic->icr_high;
- break;
-
- case APIC_LVTT: /* LVT Timer Reg */
- case APIC_LVTTHMR: /* LVT Thermal Monitor */
- case APIC_LVTPC: /* LVT Performance Counter */
- case APIC_LVT0: /* LVT LINT0 Reg */
- case APIC_LVT1: /* LVT Lint1 Reg */
- case APIC_LVTERR: /* LVT Error Reg */
- *result = vlapic->lvt[(offset - APIC_LVTT) >> 4];
- break;
-
- case APIC_TMICT:
- *result = vlapic->timer_initial_count;
- break;
-
case APIC_TMCCT: //Timer CCR
- {
- uint32_t counter_passed;
- s_time_t passed, now = NOW();
-
- if ( unlikely(now <= vlapic->timer_current_update) )
- {
- passed = ~0x0LL - vlapic->timer_current_update + now;
- HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "time elapsed.");
- }
- else
- passed = now - vlapic->timer_current_update;
-
- counter_passed = passed /
- (APIC_BUS_CYCLE_NS * vlapic->timer_divide_count);
- vlapic->timer_current_count -= counter_passed;
- if ( vlapic->timer_current_count <= 0 )
- {
- if ( unlikely(!vlapic_lvt_timer_period(vlapic)) )
- {
- vlapic->timer_current_count = 0;
- // FIXME: should we add interrupt here?
- }
- else
- {
- do {
- vlapic->timer_current_count +=
vlapic->timer_initial_count;
- } while ( vlapic->timer_current_count < 0 );
- }
- }
-
- *result = vlapic->timer_current_count;
- vlapic->timer_current_update = now;
-
- HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER,
- "timer initial count 0x%x, timer current count 0x%x, "
- "update 0x%016"PRIx64", now 0x%016"PRIx64", offset
0x%x.",
- vlapic->timer_initial_count,
vlapic->timer_current_count,
- vlapic->timer_current_update, now, counter_passed);
- }
- break;
-
- case APIC_TDCR:
- *result = vlapic->timer_divconf;
+ *result = vlapic_get_tmcct(vlapic);
break;
default:
- printk("Read local APIC address 0x%x not implemented\n", offset);
- *result = 0;
+ *result = vlapic_get_reg(vlapic, offset);
break;
}
}
@@ -575,6 +502,9 @@ static unsigned long vlapic_read(struct
unsigned long result;
struct vlapic *vlapic = VLAPIC(v);
unsigned int offset = address - vlapic->base_address;
+
+ if ( offset > APIC_TDCR)
+ return 0;
/* some bugs on kernel cause read this with byte*/
if ( len != 4 )
@@ -671,11 +601,11 @@ static void vlapic_write(struct vcpu *v,
switch ( offset ) {
case APIC_ID: /* Local APIC ID */
- vlapic->id = ((val) >> 24) & VAPIC_ID_MASK;
+ vlapic_set_reg(vlapic, APIC_ID, val);
break;
case APIC_TASKPRI:
- vlapic->task_priority = val & 0xff;
+ vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
vlapic_update_ppr(vlapic);
break;
@@ -684,24 +614,41 @@ static void vlapic_write(struct vcpu *v,
break;
case APIC_LDR:
- vlapic->logical_dest = val & VAPIC_LDR_MASK;
+ vlapic_set_reg(vlapic, APIC_LDR, val & APIC_LDR_MASK);
break;
case APIC_DFR:
- vlapic->dest_format = val ;
+ vlapic_set_reg(vlapic, APIC_DFR, val);
break;
case APIC_SPIV:
- vlapic->spurious_vec = val & 0x1ff;
- if ( !(vlapic->spurious_vec & 0x100) )
+ vlapic_set_reg(vlapic, APIC_SPIV, val & 0x1ff);
+
+ if ( !( val & APIC_SPIV_APIC_ENABLED) )
{
int i;
+ uint32_t lvt_val;
+
+ vlapic->status |= VLAPIC_SOFTWARE_DISABLE_MASK;
+
for ( i = 0; i < VLAPIC_LVT_NUM; i++ )
- vlapic->lvt[i] |= 0x10000;
- vlapic->status |= VLAPIC_SOFTWARE_DISABLE_MASK;
+ {
+ lvt_val = vlapic_get_reg(vlapic, APIC_LVT1 + 0x10 * i);
+ vlapic_set_reg(vlapic, APIC_LVTT + 0x10 * i,
+ lvt_val | APIC_LVT_MASKED);
+ }
+
+ if ( (vlapic_get_reg(vlapic, APIC_LVT0) & APIC_MODE_MASK)
+ == APIC_DM_EXTINT )
+ clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
}
else
+ {
vlapic->status &= ~VLAPIC_SOFTWARE_DISABLE_MASK;
+ if ( (vlapic_get_reg(vlapic, APIC_LVT0) & APIC_MODE_MASK)
+ == APIC_DM_EXTINT )
+ set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
+ }
break;
case APIC_ESR:
@@ -712,12 +659,12 @@ static void vlapic_write(struct vcpu *v,
case APIC_ICR:
/* No delay here, so we always clear the pending bit*/
- vlapic->icr_low = val & ~(1 << 12);
+ vlapic_set_reg(vlapic, APIC_ICR, val & ~(1 << 12));
vlapic_ipi(vlapic);
break;
case APIC_ICR2:
- vlapic->icr_high = val & 0xff000000;
+ vlapic_set_reg(vlapic, APIC_ICR2, val & 0xff000000);
break;
case APIC_LVTT: // LVT Timer Reg
@@ -727,26 +674,25 @@ static void vlapic_write(struct vcpu *v,
case APIC_LVT1: // LVT Lint1 Reg
case APIC_LVTERR: // LVT Error Reg
{
- int vt = (offset - APIC_LVTT) >> 4;
-
- vlapic->lvt[vt] = val & vlapic_lvt_mask[vt];
if ( vlapic->status & VLAPIC_SOFTWARE_DISABLE_MASK )
- vlapic->lvt[vt] |= VLAPIC_LVT_BIT_MASK;
+ val |= APIC_LVT_MASKED;
+
+ val &= vlapic_lvt_mask[(offset - APIC_LVTT) >> 4];
+
+ vlapic_set_reg(vlapic, offset, val);
/* On hardware, when write vector less than 0x20 will error */
- vlapic_check_vector(vlapic, vlapic_lvt_dm(vlapic->lvt[vt]),
- vlapic_lvt_vector(vlapic, vt));
+ if ( !(val & APIC_LVT_MASKED) )
+ vlapic_check_vector(vlapic, vlapic_lvt_dm(vlapic, offset),
+ vlapic_lvt_vector(vlapic, offset));
if ( !vlapic->vcpu_id && (offset == APIC_LVT0) )
{
- if ( (vlapic->lvt[VLAPIC_LVT_LINT0] & VLAPIC_LVT_BIT_DELIMOD)
- == 0x700 )
- {
- if ( vlapic->lvt[VLAPIC_LVT_LINT0] & VLAPIC_LVT_BIT_MASK )
+ if ( (val & APIC_MODE_MASK) == APIC_DM_EXTINT )
+ if ( val & APIC_LVT_MASKED)
clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
else
set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
- }
else
clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
}
@@ -758,16 +704,14 @@ static void vlapic_write(struct vcpu *v,
{
s_time_t now = NOW(), offset;
- if ( vlapic_timer_active(vlapic) )
- stop_timer(&vlapic->vlapic_timer);
-
- vlapic->timer_initial_count = val;
- vlapic->timer_current_count = val;
- vlapic->timer_current_update = now;
+ stop_timer(&vlapic->vlapic_timer);
+
+ vlapic_set_reg(vlapic, APIC_TMICT, val);
+ vlapic_set_reg(vlapic, APIC_TMCCT, val);
+ vlapic->timer_last_update = now;
offset = APIC_BUS_CYCLE_NS *
- vlapic->timer_divide_count *
- vlapic->timer_initial_count;
+ vlapic->timer_divide_count * val;
set_timer(&vlapic->vlapic_timer, now + offset);
@@ -775,7 +719,8 @@ static void vlapic_write(struct vcpu *v,
"bus cycle is %"PRId64"ns, now 0x%016"PRIx64", "
"timer initial count 0x%x, offset 0x%016"PRIx64", "
"expire @ 0x%016"PRIx64".",
- APIC_BUS_CYCLE_NS, now, vlapic->timer_initial_count,
+ APIC_BUS_CYCLE_NS, now,
+ vlapic_get_reg(vlapic, APIC_TMICT),
offset, now + offset);
}
break;
@@ -787,6 +732,8 @@ static void vlapic_write(struct vcpu *v,
tmp1 = val & 0xf;
tmp2 = ((tmp1 & 0x3) | ((tmp1 & 0x8) >> 1)) + 1;
vlapic->timer_divide_count = 0x1 << (tmp2 & 0x7);
+
+ vlapic_set_reg(vlapic, APIC_TDCR, val);
HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, "timer divide count is 0x%x",
vlapic->timer_divide_count);
@@ -827,19 +774,18 @@ void vlapic_msr_set(struct vlapic *vlapi
value &= ~MSR_IA32_APICBASE_BSP;
vlapic->apic_base_msr = value;
- vlapic->base_address = vlapic_get_base_address(vlapic);
-
- if ( !(value & 0x800) )
+ vlapic->base_address = vlapic->apic_base_msr &
+ MSR_IA32_APICBASE_BASE;
+
+ /* with FSB delivery interrupt, we can restart APIC functionality */
+ if ( !(value & MSR_IA32_APICBASE_ENABLE) )
set_bit(_VLAPIC_GLOB_DISABLE, &vlapic->status );
+ else
+ clear_bit(_VLAPIC_GLOB_DISABLE, &vlapic->status);
HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
"apic base msr is 0x%016"PRIx64", and base address is 0x%lx.",
vlapic->apic_base_msr, vlapic->base_address);
-}
-
-static inline int vlapic_get_init_id(struct vcpu *v)
-{
- return v->vcpu_id;
}
void vlapic_timer_fn(void *data)
@@ -850,31 +796,32 @@ void vlapic_timer_fn(void *data)
s_time_t now;
if ( unlikely(!vlapic_enabled(vlapic) ||
- !vlapic_lvt_timer_enabled(vlapic)) )
+ !vlapic_lvt_enabled(vlapic, APIC_LVTT)) )
return;
v = vlapic->vcpu;
- timer_vector = vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER);
+ timer_vector = vlapic_lvt_vector(vlapic, APIC_LVTT);
now = NOW();
- vlapic->timer_current_update = now;
-
- if ( test_and_set_bit(timer_vector, &vlapic->irr[0]) )
+ vlapic->timer_last_update = now;
+
+ if ( test_and_set_bit(timer_vector, vlapic->regs + APIC_IRR ))
vlapic->intr_pending_count[timer_vector]++;
- if ( vlapic_lvt_timer_period(vlapic) )
+ if ( vlapic_lvtt_period(vlapic) )
{
s_time_t offset;
-
- vlapic->timer_current_count = vlapic->timer_initial_count;
+ uint32_t tmict = vlapic_get_reg(vlapic, APIC_TMICT);
+
+ vlapic_set_reg(vlapic, APIC_TMCCT, tmict);
offset = APIC_BUS_CYCLE_NS *
- vlapic->timer_divide_count *
- vlapic->timer_initial_count;
+ vlapic->timer_divide_count * tmict;
+
set_timer(&vlapic->vlapic_timer, now + offset);
}
else
- vlapic->timer_current_count = 0;
+ vlapic_set_reg(vlapic, APIC_TMCCT, 0);
#if 0
if ( test_bit(_VCPUF_running, &v->vcpu_flags) )
@@ -887,8 +834,8 @@ void vlapic_timer_fn(void *data)
"now 0x%016"PRIx64", expire @ 0x%016"PRIx64", "
"timer initial count 0x%x, timer current count 0x%x.",
now, vlapic->vlapic_timer.expires,
- vlapic->timer_initial_count,
- vlapic->timer_current_count);
+ vlapic_get_reg(vlapic, APIC_TMICT),
+ vlapic_get_reg(vlapic, APIC_TMCCT));
}
#if 0
@@ -923,23 +870,23 @@ int cpu_get_apic_interrupt(struct vcpu *
int highest_irr = vlapic_find_highest_irr(vlapic);
if ( highest_irr != -1 &&
- ( (highest_irr & 0xF0) > vlapic->processor_priority ) )
+ ( (highest_irr & 0xF0) > vlapic_get_reg(vlapic, APIC_PROCPRI) ) )
{
if ( highest_irr < 0x10 )
{
uint32_t err_vector;
vlapic->err_status |= 0x20;
- err_vector = vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR);
+ err_vector = vlapic_lvt_vector(vlapic, APIC_LVTERR);
HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
"Sending an illegal vector 0x%x.", highest_irr);
- set_bit(err_vector, &vlapic->irr[0]);
+ set_bit(err_vector, vlapic->regs + APIC_IRR);
highest_irr = err_vector;
}
- *mode = VLAPIC_DELIV_MODE_FIXED;
+ *mode = APIC_DM_FIXED;
return highest_irr;
}
}
@@ -954,7 +901,7 @@ int cpu_has_apic_interrupt(struct vcpu*
int highest_irr = vlapic_find_highest_irr(vlapic);
if ( highest_irr != -1 &&
- ( (highest_irr & 0xF0) > vlapic->processor_priority ) ) {
+ ( (highest_irr & 0xF0) > vlapic_get_reg(vlapic, APIC_PROCPRI) ) )
{
return 1;
}
}
@@ -969,30 +916,30 @@ void vlapic_post_injection(struct vcpu *
return;
switch ( deliver_mode ) {
- case VLAPIC_DELIV_MODE_FIXED:
- case VLAPIC_DELIV_MODE_LPRI:
- set_bit(vector, &vlapic->isr[0]);
- clear_bit(vector, &vlapic->irr[0]);
+ case APIC_DM_FIXED:
+ case APIC_DM_LOWEST:
+ set_bit(vector, vlapic->regs + APIC_ISR);
+ clear_bit(vector, vlapic->regs + APIC_IRR);
vlapic_update_ppr(vlapic);
- if ( vector == vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER) )
+ if ( vector == vlapic_lvt_vector(vlapic, APIC_LVTT) )
{
vlapic->intr_pending_count[vector]--;
if ( vlapic->intr_pending_count[vector] > 0 )
- test_and_set_bit(vector, &vlapic->irr[0]);
+ test_and_set_bit(vector, vlapic->regs + APIC_IRR);
}
break;
/*XXX deal with these later */
- case VLAPIC_DELIV_MODE_RESERVED:
+ case APIC_DM_REMRD:
printk("Ignore deliver mode 3 in vlapic_post_injection\n");
break;
- case VLAPIC_DELIV_MODE_SMI:
- case VLAPIC_DELIV_MODE_NMI:
- case VLAPIC_DELIV_MODE_INIT:
- case VLAPIC_DELIV_MODE_STARTUP:
- vlapic->direct_intr.deliver_mode &= ~(1 << deliver_mode);
+ case APIC_DM_SMI:
+ case APIC_DM_NMI:
+ case APIC_DM_INIT:
+ case APIC_DM_STARTUP:
+ vlapic->direct_intr.deliver_mode &= deliver_mode;
break;
default:
@@ -1004,7 +951,7 @@ static int vlapic_reset(struct vlapic *v
static int vlapic_reset(struct vlapic *vlapic)
{
struct vcpu *v;
- int apic_id, i;
+ int i;
ASSERT( vlapic != NULL );
@@ -1012,29 +959,28 @@ static int vlapic_reset(struct vlapic *v
ASSERT( v != NULL );
- apic_id = v->vcpu_id;
-
vlapic->domain = v->domain;
- vlapic->id = apic_id;
-
vlapic->vcpu_id = v->vcpu_id;
- vlapic->version = VLAPIC_VERSION;
-
- vlapic->apic_base_msr = VLAPIC_BASE_MSR_INIT_VALUE;
-
- if ( apic_id == 0 )
+ vlapic_set_reg(vlapic, APIC_ID, v->vcpu_id << 24);
+
+ vlapic_set_reg(vlapic, APIC_LVR, VLAPIC_VERSION);
+
+ for ( i = 0; i < VLAPIC_LVT_NUM; i++ )
+ vlapic_set_reg(vlapic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED);
+
+ vlapic_set_reg(vlapic, APIC_DFR, 0xffffffffU);
+
+ vlapic_set_reg(vlapic, APIC_SPIV, 0xff);
+
+ vlapic->apic_base_msr = MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
+
+ if ( v->vcpu_id == 0 )
vlapic->apic_base_msr |= MSR_IA32_APICBASE_BSP;
- vlapic->base_address = vlapic_get_base_address(vlapic);
-
- for ( i = 0; i < VLAPIC_LVT_NUM; i++ )
- vlapic->lvt[i] = VLAPIC_LVT_BIT_MASK;
-
- vlapic->dest_format = 0xffffffffU;
-
- vlapic->spurious_vec = 0xff;
+ vlapic->base_address = vlapic->apic_base_msr &
+ MSR_IA32_APICBASE_BASE;
hvm_vioapic_add_lapic(vlapic, v);
@@ -1048,8 +994,8 @@ static int vlapic_reset(struct vlapic *v
*/
if ( !v->vcpu_id )
{
- vlapic->lvt[VLAPIC_LVT_LINT0] = 0x700;
- vlapic->lvt[VLAPIC_LVT_LINT1] = 0x500;
+ vlapic_set_reg(vlapic, APIC_LVT0, APIC_MODE_EXTINT << 8);
+ vlapic_set_reg(vlapic, APIC_LVT1, APIC_MODE_NMI << 8);
set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
}
#endif
@@ -1057,7 +1003,8 @@ static int vlapic_reset(struct vlapic *v
HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
"vcpu=%p, id=%d, vlapic_apic_base_msr=0x%016"PRIx64", "
"base_address=0x%0lx.",
- v, vlapic->id, vlapic->apic_base_msr, vlapic->base_address);
+ v, GET_APIC_ID(vlapic_get_reg(vlapic, APIC_ID)),
+ vlapic->apic_base_msr, vlapic->base_address);
return 1;
}
@@ -1079,6 +1026,18 @@ int vlapic_init(struct vcpu *v)
memset(vlapic, 0, sizeof(struct vlapic));
+ vlapic->regs_page = alloc_domheap_page(NULL);
+ if ( vlapic->regs_page == NULL )
+ {
+ printk("malloc vlapic regs error for vcpu %x\n", v->vcpu_id);
+ xfree(vlapic);
+ return -ENOMEM;
+ }
+
+ vlapic->regs = map_domain_page_global(page_to_mfn(vlapic->regs_page));
+
+ memset(vlapic->regs, 0, PAGE_SIZE);
+
VLAPIC(v) = vlapic;
vlapic->vcpu = v;
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/io.c Wed Aug 02 10:07:03 2006 +0100
@@ -81,7 +81,7 @@ interrupt_post_injection(struct vcpu * v
switch(type)
{
- case VLAPIC_DELIV_MODE_EXT:
+ case APIC_DM_EXTINT:
break;
default:
@@ -198,16 +198,17 @@ asmlinkage void vmx_intr_assist(void)
highest_vector = cpu_get_interrupt(v, &intr_type);
switch (intr_type) {
- case VLAPIC_DELIV_MODE_EXT:
- case VLAPIC_DELIV_MODE_FIXED:
- case VLAPIC_DELIV_MODE_LPRI:
+ case APIC_DM_EXTINT:
+ case APIC_DM_FIXED:
+ case APIC_DM_LOWEST:
vmx_inject_extint(v, highest_vector, VMX_DELIVER_NO_ERROR_CODE);
TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0);
break;
- case VLAPIC_DELIV_MODE_SMI:
- case VLAPIC_DELIV_MODE_NMI:
- case VLAPIC_DELIV_MODE_INIT:
- case VLAPIC_DELIV_MODE_STARTUP:
+
+ case APIC_DM_SMI:
+ case APIC_DM_NMI:
+ case APIC_DM_INIT:
+ case APIC_DM_STARTUP:
default:
printk("Unsupported interrupt type\n");
BUG();
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Aug 02 10:07:03 2006 +0100
@@ -137,6 +137,8 @@ static void vmx_relinquish_guest_resourc
if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) )
{
kill_timer(&VLAPIC(v)->vlapic_timer);
+ unmap_domain_page_global(VLAPIC(v)->regs);
+ free_domheap_page(VLAPIC(v)->regs_page);
xfree(VLAPIC(v));
}
}
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/include/asm-ia64/vmx_platform.h
--- a/xen/include/asm-ia64/vmx_platform.h Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/include/asm-ia64/vmx_platform.h Wed Aug 02 10:07:03 2006 +0100
@@ -59,6 +59,17 @@ static inline int vlapic_set_irq(struct
return vmx_vcpu_pend_interrupt(t->vcpu, vec);
}
+enum ioapic_irq_destination_types {
+ dest_Fixed = 0,
+ dest_LowestPrio = 1,
+ dest_SMI = 2,
+ dest__reserved_1 = 3,
+ dest_NMI = 4,
+ dest_INIT = 5,
+ dest__reserved_2 = 6,
+ dest_ExtINT = 7
+};
+
/* As long as we register vlsapic to ioapic controller, it's said enabled */
#define vlapic_enabled(l) 1
#define hvm_apic_support(d) 1
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/include/asm-x86/hvm/support.h
--- a/xen/include/asm-x86/hvm/support.h Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/include/asm-x86/hvm/support.h Wed Aug 02 10:07:03 2006 +0100
@@ -29,7 +29,7 @@
#ifndef NDEBUG
#define HVM_DEBUG 1
#else
-#define HVM_DEBUG 0
+#define HVM_DEBUG 1
#endif
#define hvm_guest(v) ((v)->arch.guest_context.flags & VGCF_HVM_GUEST)
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/include/asm-x86/hvm/vlapic.h Wed Aug 02 10:07:03 2006 +0100
@@ -33,58 +33,31 @@ static __inline__ int find_highest_bit(u
#define VLAPIC(v) (v->arch.hvm_vcpu.vlapic)
-#define VAPIC_ID_MASK 0xff
-#define VAPIC_LDR_MASK (VAPIC_ID_MASK << 24)
#define VLAPIC_VERSION 0x00050014
-#define VLAPIC_BASE_MSR_MASK 0x00000000fffff900ULL
-#define VLAPIC_BASE_MSR_INIT_BASE_ADDR 0xfee00000U
-#define VLAPIC_BASE_MSR_BASE_ADDR_MASK 0xfffff000U
-#define VLAPIC_BASE_MSR_INIT_VALUE (VLAPIC_BASE_MSR_INIT_BASE_ADDR | \
- MSR_IA32_APICBASE_ENABLE)
#define VLOCAL_APIC_MEM_LENGTH (1 << 12)
-#define VLAPIC_LVT_TIMER 0
-#define VLAPIC_LVT_THERMAL 1
-#define VLAPIC_LVT_PERFORM 2
-#define VLAPIC_LVT_LINT0 3
-#define VLAPIC_LVT_LINT1 4
-#define VLAPIC_LVT_ERROR 5
#define VLAPIC_LVT_NUM 6
-#define VLAPIC_LVT_BIT_MASK (1 << 16)
-#define VLAPIC_LVT_BIT_VECTOR 0xff
-#define VLAPIC_LVT_BIT_DELIMOD (0x7 << 8)
-#define VLAPIC_LVT_BIT_DELISTATUS (1 << 12)
-#define VLAPIC_LVT_BIT_POLARITY (1 << 13)
-#define VLAPIC_LVT_BIT_IRR (1 << 14)
-#define VLAPIC_LVT_BIT_TRIG (1 << 15)
-#define VLAPIC_LVT_TIMERMODE (1 << 17)
+#define VLAPIC_ID(vlapic) \
+ (GET_APIC_ID(vlapic_get_reg(vlapic, APIC_ID)))
-#define VLAPIC_DELIV_MODE_FIXED 0x0
-#define VLAPIC_DELIV_MODE_LPRI 0x1
-#define VLAPIC_DELIV_MODE_SMI 0x2
-#define VLAPIC_DELIV_MODE_RESERVED 0x3
-#define VLAPIC_DELIV_MODE_NMI 0x4
-#define VLAPIC_DELIV_MODE_INIT 0x5
-#define VLAPIC_DELIV_MODE_STARTUP 0x6
-#define VLAPIC_DELIV_MODE_EXT 0x7
+/* followed define is not in apicdef.h */
+#define APIC_SHORT_MASK 0xc0000
+#define APIC_DEST_NOSHORT 0x0
+#define APIC_DEST_MASK 0x800
+#define vlapic_lvt_enabled(vlapic, lvt_type) \
+ (!(vlapic_get_reg(vlapic, lvt_type) & APIC_LVT_MASKED))
-#define VLAPIC_NO_SHORTHAND 0x0
-#define VLAPIC_SHORTHAND_SELF 0x1
-#define VLAPIC_SHORTHAND_INCLUDE_SELF 0x2
-#define VLAPIC_SHORTHAND_EXCLUDE_SELF 0x3
+#define vlapic_lvt_vector(vlapic, lvt_type) \
+ (vlapic_get_reg(vlapic, lvt_type) & APIC_VECTOR_MASK)
-#define vlapic_lvt_timer_enabled(vlapic) \
- (!((vlapic)->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_BIT_MASK))
+#define vlapic_lvt_dm(vlapic, lvt_type) \
+ (vlapic_get_reg(vlapic, lvt_type) & APIC_MODE_MASK)
-#define vlapic_lvt_vector(vlapic, type) \
- ((vlapic)->lvt[(type)] & VLAPIC_LVT_BIT_VECTOR)
-
-#define vlapic_lvt_dm(value) (((value) >> 8) && 7)
-#define vlapic_lvt_timer_period(vlapic) \
- ((vlapic)->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_TIMERMODE)
+#define vlapic_lvtt_period(vlapic) \
+ (vlapic_get_reg(vlapic, APIC_LVTT) & APIC_LVT_TIMER_PERIODIC)
#define _VLAPIC_GLOB_DISABLE 0x0
#define VLAPIC_GLOB_DISABLE_MASK 0x1
@@ -98,8 +71,12 @@ static __inline__ int find_highest_bit(u
#define vlapic_global_enabled(vlapic) \
(!(test_bit(_VLAPIC_GLOB_DISABLE, &(vlapic)->status)))
-#define VLAPIC_IRR(t) ((t)->irr[0])
-#define VLAPIC_ID(t) ((t)->id)
+#define LVT_MASK \
+ APIC_LVT_MASKED | APIC_SEND_PENDING | APIC_VECTOR_MASK
+
+#define LINT_MASK \
+ LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY |\
+ APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER
typedef struct direct_intr_info {
int deliver_mode;
@@ -109,72 +86,52 @@ typedef struct direct_intr_info {
#define MAX_VECTOR 256
struct vlapic {
- uint32_t version;
uint32_t status;
- uint32_t id;
uint32_t vcpu_id;
+ uint64_t apic_base_msr;
unsigned long base_address;
- unsigned long isr[BITS_TO_LONGS(MAX_VECTOR)];
- unsigned long irr[BITS_TO_LONGS(MAX_VECTOR)];
- unsigned long tmr[BITS_TO_LONGS(MAX_VECTOR)];
- uint32_t task_priority;
- uint32_t processor_priority;
- uint32_t logical_dest;
- uint32_t dest_format;
- uint32_t spurious_vec;
- uint32_t lvt[6];
- uint32_t timer_initial_count;
- uint32_t timer_current_count;
- uint32_t timer_divconf;
uint32_t timer_divide_count;
struct timer vlapic_timer;
int intr_pending_count[MAX_VECTOR];
- s_time_t timer_current_update;
- uint32_t icr_high;
- uint32_t icr_low;
+ s_time_t timer_last_update;
direct_intr_info_t direct_intr;
uint32_t err_status;
- unsigned long init_ticks;
uint32_t err_write_count;
- uint64_t apic_base_msr;
struct vcpu *vcpu;
struct domain *domain;
+ struct page_info *regs_page;
+ void *regs;
};
-static inline int vlapic_set_irq(struct vlapic *t, uint8_t vec, uint8_t trig)
+static inline int vlapic_set_irq(struct vlapic *vlapic,
+ uint8_t vec, uint8_t trig)
{
int ret;
- ret = test_and_set_bit(vec, &t->irr[0]);
+ ret = test_and_set_bit(vec, vlapic->regs + APIC_IRR);
if ( trig )
- set_bit(vec, &t->tmr[0]);
+ set_bit(vec, vlapic->regs + APIC_TMR);
/* We may need to wake up target vcpu, besides set pending bit here */
return ret;
}
-static inline int vlapic_timer_active(struct vlapic *vlapic)
+static inline uint32_t vlapic_get_reg(struct vlapic *vlapic, uint32_t reg)
{
- return active_timer(&vlapic->vlapic_timer);
+ return *( (uint32_t *)(vlapic->regs + reg));
}
-int vlapic_find_highest_irr(struct vlapic *vlapic);
+static inline void vlapic_set_reg(struct vlapic *vlapic,
+ uint32_t reg, uint32_t val)
+{
+ *((uint32_t *)(vlapic->regs + reg)) = val;
+}
-int vlapic_find_highest_isr(struct vlapic *vlapic);
-
-static uint32_t inline vlapic_get_base_address(struct vlapic *vlapic)
-{
- return (vlapic->apic_base_msr & VLAPIC_BASE_MSR_BASE_ADDR_MASK);
-}
void vlapic_post_injection(struct vcpu* v, int vector, int deliver_mode);
int cpu_has_apic_interrupt(struct vcpu* v);
int cpu_get_apic_interrupt(struct vcpu* v, int *mode);
-
-extern uint32_t vlapic_update_ppr(struct vlapic *vlapic);
-
-int vlapic_update(struct vcpu *v);
extern int vlapic_init(struct vcpu *vc);
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Wed Aug 02 10:07:03 2006 +0100
@@ -153,7 +153,7 @@ extern unsigned int cpu_rev;
/*
* Exit Qualifications for MOV for Control Register Access
*/
-#define CONTROL_REG_ACCESS_NUM 0x7 /* 2:0, number of control
register */
+#define CONTROL_REG_ACCESS_NUM 0xf /* 3:0, number of control
register */
#define CONTROL_REG_ACCESS_TYPE 0x30 /* 5:4, access type */
#define CONTROL_REG_ACCESS_REG 0xf00 /* 10:8, general purpose
register */
#define LMSW_SOURCE_DATA (0xFFFF << 16) /* 16:31 lmsw source */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|