[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM] Place all APIC registers into one page in native format.
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |