[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Clean up vlapic code.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 503c4d8454e5fa2d8cbc267dd2c8c0063cc5d613 # Parent 4293d6760cef529c200766e14b13bc09a0b0b71a Clean up vlapic code. Signed-off-by: Xin Li <xin.b.li@xxxxxxxxx> Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx> diff -r 4293d6760cef -r 503c4d8454e5 xen/arch/x86/apic.c --- a/xen/arch/x86/apic.c Tue Mar 7 17:40:42 2006 +++ b/xen/arch/x86/apic.c Tue Mar 7 17:41:37 2006 @@ -892,9 +892,9 @@ return result; } -unsigned int get_apic_bus_scale(void) -{ - return bus_scale; +u32 get_apic_bus_cycle(void) +{ + return bus_cycle; } static unsigned int calibration_result; diff -r 4293d6760cef -r 503c4d8454e5 xen/arch/x86/hvm/vlapic.c --- a/xen/arch/x86/hvm/vlapic.c Tue Mar 7 17:40:42 2006 +++ b/xen/arch/x86/hvm/vlapic.c Tue Mar 7 17:41:37 2006 @@ -37,7 +37,9 @@ /* XXX remove this definition after GFW enabled */ #define VLAPIC_NO_BIOS -extern unsigned int get_apic_bus_scale(void); +extern u32 get_apic_bus_cycle(void); + +#define APIC_BUS_CYCLE_NS (((s_time_t)get_apic_bus_cycle()) / 1000) static unsigned int vlapic_lvt_mask[VLAPIC_LVT_NUM] = { @@ -50,7 +52,8 @@ result = find_highest_bit((uint32_t *)&vlapic->irr[0], INTR_LEN_32); - if (result != -1 && result < 16) { + if ( result != -1 && result < 16 ) + { printk("VLAPIC: irr on reserved bits %d\n ", result); domain_crash_synchronous(); } @@ -78,10 +81,11 @@ result = find_highest_bit((uint32_t *)&vlapic->isr[0], INTR_LEN_32); - if (result != -1 && result < 16) { + if ( result != -1 && result < 16 ) + { int i = 0; printk("VLAPIC: isr on reserved bits %d, isr is\n ", result); - for (i = 0; i < INTR_LEN_32; i += 2) + for ( i = 0; i < INTR_LEN_32; i += 2 ) printk("%d: 0x%08x%08x\n", i, vlapic->isr[i], vlapic->isr[i+1]); return -1; } @@ -97,12 +101,12 @@ tpr = (vlapic->task_priority >> 4) & 0xf; /* we want 7:4 */ isr = vlapic_find_highest_isr(vlapic); - if (isr != -1) + if ( isr != -1 ) isrv = (isr >> 4) & 0xf; /* ditto */ else isrv = 0; - if (tpr >= isrv) + if ( tpr >= isrv ) ppr = vlapic->task_priority & 0xff; else ppr = isrv << 4; /* low 4 bits of PPR have to be cleared */ @@ -110,7 +114,7 @@ vlapic->processor_priority = ppr; HVM_DBG_LOG(DBG_LEVEL_VLAPIC_INTERRUPT, - "vlapic_update_ppr: vlapic %p ppr %x isr %x isrv %x", + "vlapic %p, ppr 0x%x, isr 0x%x, isrv 0x%x.", vlapic, ppr, isr, isrv); return ppr; @@ -124,46 +128,52 @@ int result = 0; struct vlapic *target = VLAPIC(v); - HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_match_dest: " - "target %p source %p dest %x dest_mode %x short_hand %x " - "delivery_mode %x", + HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "target %p, source %p, dest 0x%x, " + "dest_mode 0x%x, short_hand 0x%x, delivery_mode 0x%x.", target, source, dest, dest_mode, short_hand, delivery_mode); - if ( unlikely(!target) && - ( (delivery_mode != VLAPIC_DELIV_MODE_INIT) && - (delivery_mode != VLAPIC_DELIV_MODE_STARTUP) && - (delivery_mode != VLAPIC_DELIV_MODE_NMI) )) { - HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_match_dest " - "uninitialized target v %p delivery_mode %x dest %x\n", - v, delivery_mode, dest); - return result; - } - - switch (short_hand) { + if ( unlikely(target == NULL) && + ((delivery_mode != VLAPIC_DELIV_MODE_INIT) && + (delivery_mode != VLAPIC_DELIV_MODE_STARTUP) && + (delivery_mode != VLAPIC_DELIV_MODE_NMI)) ) + { + HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "uninitialized target vcpu %p, " + "delivery_mode 0x%x, dest 0x%x.\n", v, delivery_mode, dest); + return result; + } + + switch ( short_hand ) { case VLAPIC_NO_SHORTHAND: - if (!dest_mode) { /* Physical */ - result = ((target ? target->id : v->vcpu_id ) == dest); - } else { /* Logical */ - if (!target) + if ( !dest_mode ) /* Physical */ + { + result = (target != NULL ? target->id : v->vcpu_id) == dest; + } + else /* Logical */ + { + if ( target == NULL ) break; - if (((target->dest_format >> 28) & 0xf) == 0xf) { /* Flat mode */ + if ( ((target->dest_format >> 28) & 0xf) == 0xf ) /* Flat mode */ + { result = (target->logical_dest >> 24) & dest; - } else { - if ((delivery_mode == VLAPIC_DELIV_MODE_LPRI) && - (dest == 0xff)) { + } + else + { + if ( (delivery_mode == VLAPIC_DELIV_MODE_LPRI) && + (dest == 0xff) ) + { /* What shall we do now? */ printk("Broadcast IPI with lowest priority " "delivery mode\n"); domain_crash_synchronous(); } result = (target->logical_dest == (dest & 0xf)) ? - ((target->logical_dest >> 4) & (dest >> 4)) : 0; + ((target->logical_dest >> 4) & (dest >> 4)) : 0; } } break; case VLAPIC_SHORTHAND_SELF: - if (target == source) + if ( target == source ) result = 1; break; @@ -172,7 +182,7 @@ break; case VLAPIC_SHORTHAND_EXCLUDE_SELF: - if (target != source) + if ( target != source ) result = 1; break; @@ -190,27 +200,30 @@ static int vlapic_accept_irq(struct vcpu *v, int delivery_mode, int vector, int level, int trig_mode) { - int result = 0; + int result = 0; struct vlapic *vlapic = VLAPIC(v); - switch (delivery_mode) { + switch ( delivery_mode ) { case VLAPIC_DELIV_MODE_FIXED: case VLAPIC_DELIV_MODE_LPRI: /* FIXME add logic for vcpu on reset */ - if (unlikely(!vlapic || !vlapic_enabled(vlapic))) - return result; - - if (test_and_set_bit(vector, &vlapic->irr[0])) { + if ( unlikely(vlapic == NULL || !vlapic_enabled(vlapic)) ) + break; + + if ( test_and_set_bit(vector, &vlapic->irr[0]) ) + { printk("<vlapic_accept_irq>" - "level trig mode repeatedly for vector %d\n", vector); - result = 0; - } else { - if (level) { - printk("<vlapic_accept_irq> level trig mode for vector %d\n", vector); - set_bit(vector, &vlapic->tmr[0]); - } - } - evtchn_set_pending(vlapic->vcpu, iopacket_port(vlapic->vcpu)); + "level trig mode repeatedly for vector %d\n", vector); + break; + } + + if ( level ) + { + printk("<vlapic_accept_irq> level trig mode for vector %d\n", + vector); + set_bit(vector, &vlapic->tmr[0]); + } + evtchn_set_pending(v, iopacket_port(v)); result = 1; break; @@ -225,11 +238,15 @@ break; case VLAPIC_DELIV_MODE_INIT: - if ( !level && trig_mode == 1 ) { //Deassert + if ( !level && trig_mode == 1 ) //Deassert + { printk("This hvm_vlapic is for P4, no work for De-assert init\n"); - } else { + } + else + { /* FIXME How to check the situation after vcpu reset? */ - if ( test_and_clear_bit(_VCPUF_initialised, &v->vcpu_flags) ) { + if ( test_and_clear_bit(_VCPUF_initialised, &v->vcpu_flags) ) + { printk("Reset hvm vcpu not supported yet\n"); domain_crash_synchronous(); } @@ -247,7 +264,8 @@ v->arch.hvm_vcpu.init_sipi_sipi_state = HVM_VCPU_INIT_SIPI_SIPI_STATE_NORM; - if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) ) { + if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) ) + { printk("SIPI for initialized vcpu vcpuid %x\n", v->vcpu_id); domain_crash_synchronous(); } @@ -257,7 +275,7 @@ break; default: - printk("TODO: not support interrup type %x\n", delivery_mode); + printk("TODO: not support interrupt type %x\n", delivery_mode); domain_crash_synchronous(); break; } @@ -276,13 +294,15 @@ int next, old; struct vlapic* target = NULL; - if (dest_mode == 0) { //Physical mode - printk("<apic_round_robin> lowest priority for physical mode\n"); + if ( dest_mode == 0 ) //Physical mode + { + printk("<apic_round_robin> lowest priority for physical mode.\n"); return NULL; } - if (!bitmap) { - printk("<apic_round_robin> no bit on bitmap\n"); + if ( !bitmap ) + { + printk("<apic_round_robin> no bit set in bitmap.\n"); return NULL; } @@ -292,10 +312,12 @@ do { /* the vcpu array is arranged according to vcpu_id */ - if (test_bit(next, &bitmap)) { + if ( test_bit(next, &bitmap) ) + { target = d->vcpu[next]->arch.hvm_vcpu.vlapic; - if (!target || !vlapic_enabled(target)) { + if ( target == NULL || !vlapic_enabled(target) ) + { printk("warning: targe round robin local apic disabled\n"); /* XXX should we domain crash?? Or should we return NULL */ } @@ -303,48 +325,47 @@ } next ++; - if (!d->vcpu[next] || - !test_bit(_VCPUF_initialised, &d->vcpu[next]->vcpu_flags) || - next == MAX_VIRT_CPUS) + if ( !d->vcpu[next] || + !test_bit(_VCPUF_initialised, &d->vcpu[next]->vcpu_flags) || + next == MAX_VIRT_CPUS ) next = 0; - }while(next != old); + } while ( next != old ); d->arch.hvm_domain.round_info[vector] = next; spin_unlock(&d->arch.hvm_domain.round_robin_lock); + return target; } -void -vlapic_EOI_set(struct vlapic *vlapic) +void vlapic_EOI_set(struct vlapic *vlapic) { int vector = vlapic_find_highest_isr(vlapic); /* Not every write EOI will has correpsoning ISR, one example is when Kernel check timer on setup_IO_APIC */ - if (vector == -1) { + if ( vector == -1 ) return ; - } - - vlapic_clear_isr(vlapic, vector); + + clear_bit(vector, &vlapic->isr[0]); vlapic_update_ppr(vlapic); - if (test_and_clear_bit(vector, &vlapic->tmr[0])) + if ( test_and_clear_bit(vector, &vlapic->tmr[0]) ) 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)) { + if ( (dm == VLAPIC_DELIV_MODE_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 fail\n"); + vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR), 0, 0); + printk("<vlapic_check_vector>: check failed.\n"); return 0; } return 1; } - void vlapic_ipi(struct vlapic *vlapic) { @@ -360,68 +381,47 @@ struct vcpu *v = NULL; uint32_t lpr_map; - HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_ipi: " - "icr_high %x icr_low %x " - "short_hand %x dest %x trig_mode %x level %x " - "dest_mode %x delivery_mode %x vector %x", - vlapic->icr_high, vlapic->icr_low, - short_hand, dest, trig_mode, level, dest_mode, - delivery_mode, vector); - - for_each_vcpu ( vlapic->domain, v ) { - if (vlapic_match_dest(v, vlapic, short_hand, - dest, dest_mode, delivery_mode)) { - if (delivery_mode == VLAPIC_DELIV_MODE_LPRI) { + 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, + trig_mode, level, dest_mode, delivery_mode, vector); + + for_each_vcpu ( vlapic->domain, v ) + { + if ( vlapic_match_dest(v, vlapic, short_hand, + dest, dest_mode, delivery_mode) ) + { + if ( delivery_mode == VLAPIC_DELIV_MODE_LPRI ) set_bit(v->vcpu_id, &lpr_map); - } else + else vlapic_accept_irq(v, delivery_mode, vector, level, trig_mode); } } - if (delivery_mode == VLAPIC_DELIV_MODE_LPRI) { + if ( delivery_mode == VLAPIC_DELIV_MODE_LPRI ) + { v = vlapic->vcpu; target = apic_round_robin(v->domain, dest_mode, vector, lpr_map); - if (target) + if ( target ) vlapic_accept_irq(target->vcpu, delivery_mode, vector, level, trig_mode); } } -static void vlapic_begin_timer(struct vlapic *vlapic) -{ - s_time_t cur = NOW(), offset; - - offset = vlapic->timer_current * - (262144 / get_apic_bus_scale()) * vlapic->timer_divide_counter; - vlapic->vlapic_timer.expires = cur + offset; - - set_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires ); - - HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_begin_timer: " - "bus_scale %x now %08x%08x expire %08x%08x " - "offset %08x%08x current %x", - get_apic_bus_scale(), (uint32_t)(cur >> 32), (uint32_t)cur, - (uint32_t)(vlapic->vlapic_timer.expires >> 32), - (uint32_t) vlapic->vlapic_timer.expires, - (uint32_t)(offset >> 32), (uint32_t)offset, - vlapic->timer_current); -} - -void vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset, +static void vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset, unsigned int len, unsigned int *result) { - if (len != 4) { - HVM_DBG_LOG(DBG_LEVEL_VLAPIC, - "local apic read with len=%d (should be 4)", len); - } + if ( len != 4 ) + printk("<vlapic_read_aligned> read with len=%d (should be 4).\n", len); *result = 0; - switch (offset) { + switch ( offset ) { case APIC_ID: - *result = (vlapic->id) << 24; + *result = vlapic->id << 24; break; case APIC_LVR: @@ -433,7 +433,7 @@ break; case APIC_ARBPRI: - printk("Access local APIC ARBPRI register which is for P6\n"); + printk("access local APIC ARBPRI register which is for P6\n"); break; case APIC_PROCPRI: @@ -489,7 +489,7 @@ break; case APIC_ESR: - if (vlapic->err_write_count) + if ( vlapic->err_write_count ) *result = vlapic->err_status; break; @@ -501,51 +501,59 @@ *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 */ + 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; - break; - - case APIC_TMCCT: //Timer CCR - { - uint32_t counter; - s_time_t passed, cur = NOW(); - - if (cur <= vlapic->timer_current_update) { - passed = ~0x0LL - vlapic->timer_current_update + cur; - HVM_DBG_LOG(DBG_LEVEL_VLAPIC,"time elapsed"); - }else - passed = cur - vlapic->timer_current_update; - - counter = (passed * get_apic_bus_scale()) / (262144* vlapic->timer_divide_counter); - if (vlapic->timer_current > counter) - *result = vlapic->timer_current - counter; - else { - if (!vlapic_lvt_timer_period(vlapic)) - *result = 0; - //FIXME should we add interrupt here? + *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 - //*result = counter % vlapic->timer_initial; - *result = vlapic->timer_initial - (counter - vlapic->timer_current); + { + do { + vlapic->timer_current_count += vlapic->timer_initial_count; + } while ( vlapic->timer_current_count < 0 ); + } } - vlapic->timer_current = *result; - vlapic->timer_current_update = NOW(); + + *result = vlapic->timer_current_count; + vlapic->timer_current_update = now; HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, - "initial %x timer current %x " - "update %08x%08x cur %08x%08x offset %d", - vlapic->timer_initial, vlapic->timer_current, - (uint32_t)(vlapic->timer_current_update >> 32), - (uint32_t)vlapic->timer_current_update , - (uint32_t)(cur >> 32), (uint32_t)cur, counter); + "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; @@ -554,7 +562,7 @@ break; default: - printk("Read local APIC address %x not implemented\n",offset); + printk("Read local APIC address 0x%x not implemented\n", offset); *result = 0; break; } @@ -569,17 +577,16 @@ struct vlapic *vlapic = VLAPIC(v); unsigned int offset = address - vlapic->base_address; - if ( len != 4) { - /* some bugs on kernel cause read this with byte*/ + /* some bugs on kernel cause read this with byte*/ + if ( len != 4 ) HVM_DBG_LOG(DBG_LEVEL_VLAPIC, - "Local APIC read with len = %lx, should be 4 instead\n", + "read with len=0x%lx, should be 4 instead.\n", len); - } alignment = offset & 0x3; vlapic_read_aligned(vlapic, offset & ~0x3, 4, &tmp); - switch (len) { + switch ( len ) { case 1: result = *((unsigned char *)&tmp + alignment); break; @@ -593,14 +600,14 @@ break; default: - printk("Local APIC read with len = %lx, should be 4 instead\n", len); + printk("Local APIC read with len=0x%lx, should be 4 instead.\n", len); domain_crash_synchronous(); break; } - HVM_DBG_LOG(DBG_LEVEL_VLAPIC, - "vlapic_read offset %x with length %lx and the result is %lx", - offset, len, result); + HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "offset 0x%x with length 0x%lx, " + "and the result is 0x%lx.", offset, len, result); + return result; } @@ -610,40 +617,42 @@ struct vlapic *vlapic = VLAPIC(v); unsigned int offset = address - vlapic->base_address; - if (offset != 0xb0) + if ( offset != 0xb0 ) HVM_DBG_LOG(DBG_LEVEL_VLAPIC, - "vlapic_write offset %x with length %lx source %lx", - offset, len, val); + "offset 0x%x with length 0x%lx, and value is 0x%lx.", + offset, len, val); /* * According to IA 32 Manual, all resgiters should be accessed with * 32 bits alignment. */ - if (len != 4) { + if ( len != 4 ) + { unsigned int tmp; unsigned char alignment; /* Some kernel do will access with byte/word alignment*/ printk("Notice: Local APIC write with len = %lx\n",len); alignment = offset & 0x3; - tmp = vlapic_read(v, offset & (~0x3), 4); - switch (len) { + tmp = vlapic_read(v, offset & ~0x3, 4); + switch ( len ) { case 1: /* XXX the saddr is a tmp variable from caller, so should be ok - But we should still change the following ref to val to + But we should still change the following ref to val to local variable later */ - val = (tmp & ~(0xff << alignment)) | - ((val & 0xff) << alignment); + val = (tmp & ~(0xff << alignment)) | + ((val & 0xff) << alignment); break; case 2: - if (alignment != 0x0 && alignment != 0x2) { + if ( alignment != 0x0 && alignment != 0x2 ) + { printk("alignment error for vlapic with len == 2\n"); - domain_crash_synchronous(); + domain_crash_synchronous(); } val = (tmp & ~(0xffff << alignment)) | - ((val & 0xffff) << alignment); + ((val & 0xffff) << alignment); break; case 3: @@ -661,7 +670,7 @@ offset &= 0xff0; - switch (offset) { + switch ( offset ) { case APIC_ID: /* Local APIC ID */ vlapic->id = ((val) >> 24) & VAPIC_ID_MASK; break; @@ -685,9 +694,10 @@ case APIC_SPIV: vlapic->spurious_vec = val & 0x1ff; - if (!(vlapic->spurious_vec & 0x100)) { - int i = 0; - for (i = 0; i < VLAPIC_LVT_NUM; i++) + if ( !(vlapic->spurious_vec & 0x100) ) + { + int i; + for ( i = 0; i < VLAPIC_LVT_NUM; i++ ) vlapic->lvt[i] |= 0x10000; vlapic->status |= VLAPIC_SOFTWARE_DISABLE_MASK; } @@ -697,7 +707,7 @@ case APIC_ESR: vlapic->err_write_count = !vlapic->err_write_count; - if (!vlapic->err_write_count) + if ( !vlapic->err_write_count ) vlapic->err_status = 0; break; @@ -711,30 +721,32 @@ vlapic->icr_high = val & 0xff000000; 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 + 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 { int vt = (offset - APIC_LVTT) >> 4; vlapic->lvt[vt] = val & vlapic_lvt_mask[vt]; - if (vlapic->status & VLAPIC_SOFTWARE_DISABLE_MASK) + if ( vlapic->status & VLAPIC_SOFTWARE_DISABLE_MASK ) vlapic->lvt[vt] |= VLAPIC_LVT_BIT_MASK; /* 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 (!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)) { + vlapic_lvt_vector(vlapic, vt)); + + 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 ) + 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); } else clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); @@ -744,33 +756,42 @@ break; case APIC_TMICT: - if (vlapic_timer_active(vlapic)) - stop_timer(&(vlapic->vlapic_timer)); - - vlapic->timer_initial = val; - vlapic->timer_current = val; - vlapic->timer_current_update = NOW(); - - vlapic_begin_timer(vlapic); - - HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "timer_init %x timer_current %x" - "timer_current_update %08x%08x", - vlapic->timer_initial, vlapic->timer_current, - (uint32_t)(vlapic->timer_current_update >> 32), - (uint32_t)vlapic->timer_current_update); + { + 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; + + offset = APIC_BUS_CYCLE_NS * + vlapic->timer_divide_count * + vlapic->timer_initial_count; + vlapic->vlapic_timer.expires = now + offset; + + set_timer(&vlapic->vlapic_timer, vlapic->vlapic_timer.expires); + + HVM_DBG_LOG(DBG_LEVEL_VLAPIC, + "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, + offset, vlapic->vlapic_timer.expires); + } break; case APIC_TDCR: { - //FIXME clean this code - unsigned char tmp1,tmp2; - tmp1 = (val & 0xf); - tmp2 = ((tmp1 & 0x3 )|((tmp1 & 0x8) >>1)) + 1; - vlapic->timer_divide_counter = 0x1<<tmp2; - - HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, - "timer divider is 0x%x", - vlapic->timer_divide_counter); + unsigned int tmp1, tmp2; + + tmp1 = val & 0xf; + tmp2 = ((tmp1 & 0x3) | ((tmp1 & 0x8) >> 1)) + 1; + vlapic->timer_divide_count = 0x1 << (tmp2 & 0x7); + + HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, "timer divide count is 0x%x", + vlapic->timer_divide_count); } break; @@ -784,9 +805,9 @@ { struct vlapic *vlapic = VLAPIC(v); - if (vlapic_global_enabled(vlapic) && - (addr >= vlapic->base_address) && - (addr <= (vlapic->base_address + VLOCAL_APIC_MEM_LENGTH))) + if ( vlapic_global_enabled(vlapic) && + (addr >= vlapic->base_address) && + (addr <= vlapic->base_address + VLOCAL_APIC_MEM_LENGTH) ) return 1; return 0; @@ -801,23 +822,21 @@ void vlapic_msr_set(struct vlapic *vlapic, uint64_t value) { /* When apic disabled */ - if (!vlapic) + if ( vlapic == NULL ) return; - if (vlapic->vcpu_id) + if ( vlapic->vcpu_id ) value &= ~MSR_IA32_APICBASE_BSP; vlapic->apic_base_msr = value; vlapic->base_address = vlapic_get_base_address(vlapic); - if (!(value & 0x800)) + if ( !(value & 0x800) ) set_bit(_VLAPIC_GLOB_DISABLE, &vlapic->status ); HVM_DBG_LOG(DBG_LEVEL_VLAPIC, - "apic base msr = 0x%08x%08x,\nbase address = 0x%lx", - (uint32_t)(vlapic->apic_base_msr >> 32), - (uint32_t)vlapic->apic_base_msr, - vlapic->base_address); + "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) @@ -827,42 +846,51 @@ void vlapic_timer_fn(void *data) { - struct vlapic *vlapic; - - vlapic = data; - if (!vlapic_enabled(vlapic)) return; - - vlapic->timer_current_update = NOW(); - - if (vlapic_lvt_timer_enabled(vlapic)) { - if (!vlapic_irr_status(vlapic, - vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER))) { - test_and_set_bit(vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER), - &vlapic->irr[0]); - } - else - vlapic->intr_pending_count[vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER)]++; - evtchn_set_pending(vlapic->vcpu, iopacket_port(vlapic->vcpu)); - } - - vlapic->timer_current_update = NOW(); - if (vlapic_lvt_timer_period(vlapic)) { + struct vlapic *vlapic = data; + struct vcpu *v; + uint32_t timer_vector; + s_time_t now; + + if ( unlikely(!vlapic_enabled(vlapic) || + !vlapic_lvt_timer_enabled(vlapic)) ) + return; + + v = vlapic->vcpu; + timer_vector = vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER); + now = NOW(); + + vlapic->timer_current_update = now; + + if ( test_and_set_bit(timer_vector, &vlapic->irr[0]) ) + vlapic->intr_pending_count[timer_vector]++; + + if ( vlapic_lvt_timer_period(vlapic) ) + { s_time_t offset; - vlapic->timer_current = vlapic->timer_initial; - offset = vlapic->timer_current * (262144/get_apic_bus_scale()) * vlapic->timer_divide_counter; - vlapic->vlapic_timer.expires = NOW() + offset; - set_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires); - }else { - vlapic->timer_current = 0; - } + vlapic->timer_current_count = vlapic->timer_initial_count; + + offset = APIC_BUS_CYCLE_NS * + vlapic->timer_divide_count * + vlapic->timer_initial_count; + vlapic->vlapic_timer.expires = now + offset; + set_timer(&vlapic->vlapic_timer, vlapic->vlapic_timer.expires); + } + else + vlapic->timer_current_count = 0; + +#if 0 + if ( test_bit(_VCPUF_running, &v->vcpu_flags) ) + { + /* TODO: add guest time handling here */ + } +#endif HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, - "vlapic_timer_fn: now: %08x%08x expire %08x%08x init %x current %x", - (uint32_t)(NOW() >> 32),(uint32_t)NOW(), - (uint32_t)(vlapic->vlapic_timer.expires >> 32), - (uint32_t)vlapic->vlapic_timer.expires, - vlapic->timer_initial,vlapic->timer_current); + "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); } #if 0 @@ -873,7 +901,7 @@ int type; type = __fls(vlapic->direct_intr.deliver_mode); - if (type == -1) + if ( type == -1 ) return -1; *mode = type; @@ -881,31 +909,35 @@ } #endif -int -vlapic_accept_pic_intr(struct vcpu *v) +int vlapic_accept_pic_intr(struct vcpu *v) { struct vlapic *vlapic = VLAPIC(v); return vlapic ? test_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status) : 1; } -int cpu_get_apic_interrupt(struct vcpu* v, int *mode) +int cpu_get_apic_interrupt(struct vcpu *v, int *mode) { struct vlapic *vlapic = VLAPIC(v); - if (vlapic && vlapic_enabled(vlapic)) { + if ( vlapic && vlapic_enabled(vlapic) ) + { int highest_irr = vlapic_find_highest_irr(vlapic); - if (highest_irr != -1 && highest_irr >= vlapic->processor_priority) { - if (highest_irr < 0x10) { + if ( highest_irr != -1 && highest_irr >= vlapic->processor_priority ) + { + if ( highest_irr < 0x10 ) + { + uint32_t err_vector; + vlapic->err_status |= 0x20; - /* XXX What will happen if this vector illegal stil */ + err_vector = vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR); + HVM_DBG_LOG(DBG_LEVEL_VLAPIC, - "hvm_intr_assist: illegal vector number %x err_status %x", - highest_irr, vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR)); - - set_bit(vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR), &vlapic->irr[0]); - highest_irr = vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR); + "Sending an illegal vector 0x%x.", highest_irr); + + set_bit(err_vector, &vlapic->irr[0]); + highest_irr = err_vector; } *mode = VLAPIC_DELIV_MODE_FIXED; @@ -915,29 +947,29 @@ return -1; } -void vlapic_post_injection(struct vcpu *v, int vector, int deliver_mode) { - struct vlapic *vlapic = VLAPIC(v); - - if (!vlapic) +void vlapic_post_injection(struct vcpu *v, int vector, int deliver_mode) +{ + struct vlapic *vlapic = VLAPIC(v); + + if ( unlikely(vlapic == NULL) ) return; - switch (deliver_mode) { + switch ( deliver_mode ) { case VLAPIC_DELIV_MODE_FIXED: case VLAPIC_DELIV_MODE_LPRI: - vlapic_set_isr(vlapic, vector); - vlapic_clear_irr(vlapic, vector); + set_bit(vector, &vlapic->isr[0]); + clear_bit(vector, &vlapic->irr[0]); vlapic_update_ppr(vlapic); - if (vector == vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER)) { + if ( vector == vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER) ) + { vlapic->intr_pending_count[vector]--; - if (vlapic->intr_pending_count[vector] > 0) - test_and_set_bit(vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER), - &vlapic->irr[0]); - } - - break; - /*XXX deal with these later */ - + if ( vlapic->intr_pending_count[vector] > 0 ) + test_and_set_bit(vector, &vlapic->irr[0]); + } + break; + + /*XXX deal with these later */ case VLAPIC_DELIV_MODE_RESERVED: printk("Ignore deliver mode 3 in vlapic_post_injection\n"); break; @@ -950,7 +982,7 @@ break; default: - printk("<vlapic_post_injection> error deliver mode\n"); + printk("<vlapic_post_injection> invalid deliver mode\n"); break; } } @@ -978,12 +1010,12 @@ vlapic->apic_base_msr = VLAPIC_BASE_MSR_INIT_VALUE; - if (apic_id == 0) + if ( apic_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++) + for ( i = 0; i < VLAPIC_LVT_NUM; i++ ) vlapic->lvt[i] = VLAPIC_LVT_BIT_MASK; vlapic->dest_format = 0xffffffffU; @@ -1000,18 +1032,18 @@ * XXX According to mp sepcific, BIOS will enable LVT0/1, * remove it after BIOS enabled */ - if (!v->vcpu_id) { + if ( !v->vcpu_id ) + { vlapic->lvt[VLAPIC_LVT_LINT0] = 0x700; vlapic->lvt[VLAPIC_LVT_LINT1] = 0x500; set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); } #endif - HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_reset: " - "vcpu=%p id=%d vlapic_apic_base_msr=%08x%08x " - "vlapic_base_address=%0lx", - v, vlapic->id, (uint32_t)(vlapic->apic_base_msr >> 32), - (uint32_t)vlapic->apic_base_msr, vlapic->base_address); + 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); return 1; } @@ -1025,7 +1057,8 @@ HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_init %d", v->vcpu_id); vlapic = xmalloc_bytes(sizeof(struct vlapic)); - if (!vlapic) { + if ( vlapic == NULL ) + { printk("malloc vlapic error for vcpu %x\n", v->vcpu_id); return -ENOMEM; } diff -r 4293d6760cef -r 503c4d8454e5 xen/include/asm-x86/hvm/support.h --- a/xen/include/asm-x86/hvm/support.h Tue Mar 7 17:40:42 2006 +++ b/xen/include/asm-x86/hvm/support.h Tue Mar 7 17:41:37 2006 @@ -122,9 +122,9 @@ extern unsigned int opt_hvm_debug_level; #define HVM_DBG_LOG(level, _f, _a...) \ - if ((level) & opt_hvm_debug_level) \ - printk("[HVM:%d.%d] " _f "\n", \ - current->domain->domain_id, current->vcpu_id, ## _a) + if ( (level) & opt_hvm_debug_level ) \ + printk("[HVM:%d.%d] <%s> " _f "\n", \ + current->domain->domain_id, current->vcpu_id, __func__, ## _a) #else #define HVM_DBG_LOG(level, _f, _a...) #endif diff -r 4293d6760cef -r 503c4d8454e5 xen/include/asm-x86/hvm/vlapic.h --- a/xen/include/asm-x86/hvm/vlapic.h Tue Mar 7 17:40:42 2006 +++ b/xen/include/asm-x86/hvm/vlapic.h Tue Mar 7 17:41:37 2006 @@ -101,15 +101,14 @@ #define VLAPIC_LVT_BIT_TRIG (1 << 15) #define VLAPIC_LVT_TIMERMODE (1 << 17) -#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 - +#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 #define VLAPIC_NO_SHORTHAND 0x0 @@ -118,41 +117,29 @@ #define VLAPIC_SHORTHAND_EXCLUDE_SELF 0x3 #define vlapic_lvt_timer_enabled(vlapic) \ - (!(vlapic->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_BIT_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_isr_status(vlapic,vector) \ - test_bit(vector, &vlapic->isr[0]) - -#define vlapic_irr_status(vlapic,vector) \ - test_bit(vector, &vlapic->irr[0]) - -#define vlapic_set_isr(vlapic,vector) \ - test_and_set_bit(vector, &vlapic->isr[0]) - -#define vlapic_set_irr(vlapic,vector) \ - test_and_set_bit(vector, &vlapic->irr[0]) - -#define vlapic_clear_irr(vlapic,vector) \ - clear_bit(vector, &vlapic->irr[0]) -#define vlapic_clear_isr(vlapic,vector) \ - clear_bit(vector, &vlapic->isr[0]) - -#define vlapic_enabled(vlapic) \ - (!(vlapic->status & \ - (VLAPIC_GLOB_DISABLE_MASK | VLAPIC_SOFTWARE_DISABLE_MASK))) - -#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) + (!((vlapic)->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_BIT_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_GLOB_DISABLE 0x0 +#define VLAPIC_GLOB_DISABLE_MASK 0x1 +#define VLAPIC_SOFTWARE_DISABLE_MASK 0x2 +#define _VLAPIC_BSP_ACCEPT_PIC 0x3 + +#define vlapic_enabled(vlapic) \ + (!((vlapic)->status & \ + (VLAPIC_GLOB_DISABLE_MASK | VLAPIC_SOFTWARE_DISABLE_MASK))) + +#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) typedef struct direct_intr_info { int deliver_mode; @@ -163,10 +150,6 @@ { //FIXME check what would be 64 bit on EM64T uint32_t version; -#define _VLAPIC_GLOB_DISABLE 0x0 -#define VLAPIC_GLOB_DISABLE_MASK 0x1 -#define VLAPIC_SOFTWARE_DISABLE_MASK 0x2 -#define _VLAPIC_BSP_ACCEPT_PIC 0x3 uint32_t status; uint32_t id; uint32_t vcpu_id; @@ -180,10 +163,10 @@ uint32_t dest_format; uint32_t spurious_vec; uint32_t lvt[6]; - uint32_t timer_initial; - uint32_t timer_current; + uint32_t timer_initial_count; + uint32_t timer_current_count; uint32_t timer_divconf; - uint32_t timer_divide_counter; + uint32_t timer_divide_count; struct timer vlapic_timer; int intr_pending_count[MAX_VECTOR]; s_time_t timer_current_update; @@ -203,16 +186,16 @@ int ret; ret = test_and_set_bit(vec, &t->irr[0]); - if (trig) - test_and_set_bit(vec, &t->tmr[0]); + if ( trig ) + set_bit(vec, &t->tmr[0]); /* We may need to wake up target vcpu, besides set pending bit here */ return ret; } -static inline int vlapic_timer_active(struct vlapic *vlapic) -{ - return active_timer(&(vlapic->vlapic_timer)); +static inline int vlapic_timer_active(struct vlapic *vlapic) +{ + return active_timer(&vlapic->vlapic_timer); } int vlapic_find_highest_irr(struct vlapic *vlapic); @@ -244,6 +227,7 @@ uint32_t bitmap); s_time_t get_apictime_scheduled(struct vcpu *v); + int hvm_apic_support(struct domain *d); #endif /* __ASM_X86_HVM_VLAPIC_H__ */ diff -r 4293d6760cef -r 503c4d8454e5 xen/include/asm-x86/hvm/vpit.h --- a/xen/include/asm-x86/hvm/vpit.h Tue Mar 7 17:40:42 2006 +++ b/xen/include/asm-x86/hvm/vpit.h Tue Mar 7 17:41:37 2006 @@ -38,8 +38,8 @@ struct hvm_virpit { /* for simulation of counter 0 in mode 2 */ u64 period_cycles; /* pit frequency in cpu cycles */ - u64 inject_point; /* the time inject virt intr */ u64 shift; /* save the value of offset - drift */ + s_time_t inject_point; /* the time inject virt intr */ s_time_t scheduled; /* scheduled timer interrupt */ struct timer pit_timer; /* periodic timer for mode 2*/ unsigned int channel; /* the pit channel, counter 0~2 */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |