[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] hvm: Simplify timer<->vcpu/domain conversion in RTC and PIT timer
# HG changeset patch # User Keir Fraser <keir@xxxxxxxxxxxxx> # Date 1181900191 -3600 # Node ID ba61ec7df6321221450dbe512019c43468891a02 # Parent 9a915873be8c5672bf56fd71117a9eb9e7c69fe6 hvm: Simplify timer<->vcpu/domain conversion in RTC and PIT timer models. These timers are always bound to vcpu0, where a specific vcpu matters. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/hvm/i8254.c | 123 +++++++++++++++++++++-------------------------- xen/arch/x86/hvm/rtc.c | 74 +++++++++++++++------------- 2 files changed, 96 insertions(+), 101 deletions(-) diff -r 9a915873be8c -r ba61ec7df632 xen/arch/x86/hvm/i8254.c --- a/xen/arch/x86/hvm/i8254.c Fri Jun 15 10:01:32 2007 +0100 +++ b/xen/arch/x86/hvm/i8254.c Fri Jun 15 10:36:31 2007 +0100 @@ -37,6 +37,12 @@ #include <asm/hvm/vpt.h> #include <asm/current.h> +#define domain_vpit(d) (&(d)->arch.hvm_domain.pl_time.vpit) +#define vcpu_vpit(vcpu) (domain_vpit((vcpu)->domain)) +#define vpit_domain(pit) (container_of((pit), struct domain, \ + arch.hvm_domain.pl_time.vpit)) +#define vpit_vcpu(pit) (vpit_domain(pit)->vcpu[0]) + #define RW_STATE_LSB 1 #define RW_STATE_MSB 2 #define RW_STATE_WORD0 3 @@ -45,8 +51,8 @@ static int handle_pit_io(ioreq_t *p); static int handle_pit_io(ioreq_t *p); static int handle_speaker_io(ioreq_t *p); -/* compute with 96 bit intermediate result: (a*b)/c */ -uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) +/* Compute with 96 bit intermediate result: (a*b)/c */ +static uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) { union { uint64_t ll; @@ -69,15 +75,16 @@ uint64_t muldiv64(uint64_t a, uint32_t b return res.ll; } -static int pit_get_count(PITState *s, int channel) +static int pit_get_count(PITState *pit, int channel) { uint64_t d; int counter; - struct hvm_hw_pit_channel *c = &s->hw.channels[channel]; - struct periodic_time *pt = &s->pt[channel]; - - d = muldiv64(hvm_get_guest_time(pt->vcpu) - s->count_load_time[channel], - PIT_FREQ, ticks_per_sec(pt->vcpu)); + struct hvm_hw_pit_channel *c = &pit->hw.channels[channel]; + struct vcpu *v = vpit_vcpu(pit); + + d = muldiv64(hvm_get_guest_time(v) - pit->count_load_time[channel], + PIT_FREQ, ticks_per_sec(v)); + switch ( c->mode ) { case 0: @@ -97,15 +104,15 @@ static int pit_get_count(PITState *s, in return counter; } -int pit_get_out(PITState *pit, int channel) +static int pit_get_out(PITState *pit, int channel) { struct hvm_hw_pit_channel *s = &pit->hw.channels[channel]; - uint64_t d, current_time; + uint64_t d; int out; - - current_time = hvm_get_guest_time(pit->pt[channel].vcpu); - d = muldiv64(current_time - pit->count_load_time[channel], - PIT_FREQ, ticks_per_sec(pit->pt[channel].vcpu)); + struct vcpu *v = vpit_vcpu(pit); + + d = muldiv64(hvm_get_guest_time(v) - pit->count_load_time[channel], + PIT_FREQ, ticks_per_sec(v)); switch ( s->mode ) { @@ -131,11 +138,10 @@ int pit_get_out(PITState *pit, int chann return out; } -/* val must be 0 or 1 */ -void pit_set_gate(PITState *pit, int channel, int val) +static void pit_set_gate(PITState *pit, int channel, int val) { struct hvm_hw_pit_channel *s = &pit->hw.channels[channel]; - struct periodic_time *pt = &pit->pt[channel]; + struct vcpu *v = vpit_vcpu(pit); switch ( s->mode ) { @@ -150,7 +156,7 @@ void pit_set_gate(PITState *pit, int cha case 3: /* Restart counting on rising edge. */ if ( s->gate < val ) - pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu); + pit->count_load_time[channel] = hvm_get_guest_time(v); break; } @@ -162,7 +168,7 @@ int pit_get_gate(PITState *pit, int chan return pit->hw.channels[channel].gate; } -void pit_time_fired(struct vcpu *v, void *priv) +static void pit_time_fired(struct vcpu *v, void *priv) { uint64_t *count_load_time = priv; *count_load_time = hvm_get_guest_time(v); @@ -173,9 +179,7 @@ static void pit_load_count(PITState *pit u32 period; struct hvm_hw_pit_channel *s = &pit->hw.channels[channel]; struct periodic_time *pt = &pit->pt[channel]; - struct domain *d = container_of(pit, struct domain, - arch.hvm_domain.pl_time.vpit); - struct vcpu *v; + struct vcpu *v = vpit_vcpu(pit); if ( val == 0 ) val = 0x10000; @@ -184,14 +188,8 @@ static void pit_load_count(PITState *pit s->count = val; period = DIV_ROUND((val * 1000000000ULL), PIT_FREQ); - if ( !is_hvm_domain(d) || (channel != 0) ) + if ( (v == NULL) || !is_hvm_vcpu(v) || (channel != 0) ) return; - - /* Choose a vcpu to set the timer on: current if appropriate else vcpu 0 */ - if ( pit == ¤t->domain->arch.hvm_domain.pl_time.vpit ) - v = current; - else - v = d->vcpu[0]; switch ( s->mode ) { @@ -235,9 +233,8 @@ static void pit_latch_status(PITState *s } } -static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val) -{ - PITState *pit = opaque; +static void pit_ioport_write(struct PITState *pit, uint32_t addr, uint32_t val) +{ int channel, access; struct hvm_hw_pit_channel *s; @@ -309,9 +306,8 @@ static void pit_ioport_write(void *opaqu } } -static uint32_t pit_ioport_read(void *opaque, uint32_t addr) -{ - PITState *pit = opaque; +static uint32_t pit_ioport_read(struct PITState *pit, uint32_t addr) +{ int ret, count; struct hvm_hw_pit_channel *s; @@ -371,7 +367,7 @@ static uint32_t pit_ioport_read(void *op return ret; } -void pit_stop_channel0_irq(PITState * pit) +void pit_stop_channel0_irq(PITState *pit) { destroy_periodic_time(&pit->pt[0]); } @@ -425,7 +421,7 @@ static void pit_info(PITState *pit) static int pit_save(struct domain *d, hvm_domain_context_t *h) { - PITState *pit = &d->arch.hvm_domain.pl_time.vpit; + PITState *pit = domain_vpit(d); pit_info(pit); @@ -435,7 +431,7 @@ static int pit_save(struct domain *d, hv static int pit_load(struct domain *d, hvm_domain_context_t *h) { - PITState *pit = &d->arch.hvm_domain.pl_time.vpit; + PITState *pit = domain_vpit(d); int i; /* Restore the PIT hardware state */ @@ -457,26 +453,12 @@ static int pit_load(struct domain *d, hv HVM_REGISTER_SAVE_RESTORE(PIT, pit_save, pit_load, 1, HVMSR_PER_DOM); -static void pit_reset(void *opaque) -{ - PITState *pit = opaque; +void pit_init(struct vcpu *v, unsigned long cpu_khz) +{ + PITState *pit = vcpu_vpit(v); + struct periodic_time *pt; struct hvm_hw_pit_channel *s; int i; - - for ( i = 0; i < 3; i++ ) - { - s = &pit->hw.channels[i]; - destroy_periodic_time(&pit->pt[i]); - s->mode = 0xff; /* the init mode */ - s->gate = (i != 2); - pit_load_count(pit, i, 0); - } -} - -void pit_init(struct vcpu *v, unsigned long cpu_khz) -{ - PITState *pit = &v->domain->arch.hvm_domain.pl_time.vpit; - struct periodic_time *pt; pt = &pit->pt[0]; pt[0].vcpu = v; @@ -487,20 +469,26 @@ void pit_init(struct vcpu *v, unsigned l /* register the speaker port */ register_portio_handler(v->domain, 0x61, 1, handle_speaker_io); ticks_per_sec(v) = cpu_khz * (int64_t)1000; - pit_reset(pit); + + for ( i = 0; i < 3; i++ ) + { + s = &pit->hw.channels[i]; + s->mode = 0xff; /* the init mode */ + s->gate = (i != 2); + pit_load_count(pit, i, 0); + } } void pit_deinit(struct domain *d) { - PITState *pit = &d->arch.hvm_domain.pl_time.vpit; + PITState *pit = domain_vpit(d); destroy_periodic_time(&pit->pt[0]); } /* the intercept action for PIT DM retval:0--not handled; 1--handled */ static int handle_pit_io(ioreq_t *p) { - struct vcpu *v = current; - struct PITState *vpit = &(v->domain->arch.hvm_domain.pl_time.vpit); + struct PITState *vpit = vcpu_vpit(current); if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) ) { @@ -523,16 +511,16 @@ static int handle_pit_io(ioreq_t *p) return 1; } -static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val) -{ - PITState *pit = opaque; +static void speaker_ioport_write( + struct PITState *pit, uint32_t addr, uint32_t val) +{ pit->hw.speaker_data_on = (val >> 1) & 1; pit_set_gate(pit, 2, val & 1); } -static uint32_t speaker_ioport_read(void *opaque, uint32_t addr) -{ - PITState *pit = opaque; +static uint32_t speaker_ioport_read( + struct PITState *pit, uint32_t addr) +{ /* Refresh clock toggles at about 15us. We approximate as 2^14ns. */ unsigned int refresh_clock = ((unsigned int)NOW() >> 14) & 1; return ((pit->hw.speaker_data_on << 1) | pit_get_gate(pit, 2) | @@ -541,8 +529,7 @@ static uint32_t speaker_ioport_read(void static int handle_speaker_io(ioreq_t *p) { - struct vcpu *v = current; - struct PITState *vpit = &(v->domain->arch.hvm_domain.pl_time.vpit); + struct PITState *vpit = vcpu_vpit(current); if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) ) { diff -r 9a915873be8c -r ba61ec7df632 xen/arch/x86/hvm/rtc.c --- a/xen/arch/x86/hvm/rtc.c Fri Jun 15 10:01:32 2007 +0100 +++ b/xen/arch/x86/hvm/rtc.c Fri Jun 15 10:36:31 2007 +0100 @@ -28,6 +28,12 @@ #include <asm/hvm/support.h> #include <asm/current.h> +#define domain_vrtc(d) (&(d)->arch.hvm_domain.pl_time.vrtc) +#define vcpu_vrtc(vcpu) (domain_vrtc((vcpu)->domain)) +#define vrtc_domain(rtc) (container_of((rtc), struct domain, \ + arch.hvm_domain.pl_time.vrtc)) +#define vrtc_vcpu(rtc) (vrtc_domain(rtc)->vcpu[0]) + void rtc_periodic_cb(struct vcpu *v, void *opaque) { RTCState *s = opaque; @@ -39,15 +45,15 @@ int is_rtc_periodic_irq(void *opaque) RTCState *s = opaque; return !(s->hw.cmos_data[RTC_REG_C] & RTC_AF || - s->hw.cmos_data[RTC_REG_C] & RTC_UF); + s->hw.cmos_data[RTC_REG_C] & RTC_UF); } /* Enable/configure/disable the periodic timer based on the RTC_PIE and * RTC_RATE_SELECT settings */ -static void rtc_timer_update(RTCState *s, struct vcpu *v) -{ - int period_code; - int period; +static void rtc_timer_update(RTCState *s) +{ + int period_code, period; + struct vcpu *v = vrtc_vcpu(s); period_code = s->hw.cmos_data[RTC_REG_A] & RTC_RATE_SELECT; if ( (period_code != 0) && (s->hw.cmos_data[RTC_REG_B] & RTC_PIE) ) @@ -104,7 +110,7 @@ static int rtc_ioport_write(void *opaque /* UIP bit is read only */ s->hw.cmos_data[RTC_REG_A] = (data & ~RTC_UIP) | (s->hw.cmos_data[RTC_REG_A] & RTC_UIP); - rtc_timer_update(s, current); + rtc_timer_update(s); break; case RTC_REG_B: if ( data & RTC_SET ) @@ -120,7 +126,7 @@ static int rtc_ioport_write(void *opaque rtc_set_time(s); } s->hw.cmos_data[RTC_REG_B] = data; - rtc_timer_update(s, current); + rtc_timer_update(s); break; case RTC_REG_C: case RTC_REG_D: @@ -174,11 +180,12 @@ static void rtc_copy_date(RTCState *s) static void rtc_copy_date(RTCState *s) { const struct tm *tm = &s->current_tm; - - if ( s->time_offset_seconds != s->pt.vcpu->domain->time_offset_seconds ) - { - s->current_tm = gmtime(get_localtime(s->pt.vcpu->domain)); - s->time_offset_seconds = s->pt.vcpu->domain->time_offset_seconds; + struct domain *d = vrtc_domain(s); + + if ( s->time_offset_seconds != d->time_offset_seconds ) + { + s->current_tm = gmtime(get_localtime(d)); + s->time_offset_seconds = d->time_offset_seconds; } s->hw.cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec); @@ -222,11 +229,12 @@ static void rtc_next_second(RTCState *s) { struct tm *tm = &s->current_tm; int days_in_month; - - if ( s->time_offset_seconds != s->pt.vcpu->domain->time_offset_seconds ) - { - s->current_tm = gmtime(get_localtime(s->pt.vcpu->domain)); - s->time_offset_seconds = s->pt.vcpu->domain->time_offset_seconds; + struct domain *d = vrtc_domain(s); + + if ( s->time_offset_seconds != d->time_offset_seconds ) + { + s->current_tm = gmtime(get_localtime(d)); + s->time_offset_seconds = d->time_offset_seconds; } tm->tm_sec++; @@ -292,6 +300,7 @@ static void rtc_update_second2(void *opa static void rtc_update_second2(void *opaque) { RTCState *s = opaque; + struct domain *d = vrtc_domain(s); if ( !(s->hw.cmos_data[RTC_REG_B] & RTC_SET) ) rtc_copy_date(s); @@ -310,8 +319,8 @@ static void rtc_update_second2(void *opa s->current_tm.tm_hour) ) { s->hw.cmos_data[RTC_REG_C] |= 0xa0; - hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ); - hvm_isa_irq_assert(s->pt.vcpu->domain, RTC_IRQ); + hvm_isa_irq_deassert(d, RTC_IRQ); + hvm_isa_irq_assert(d, RTC_IRQ); } } @@ -319,8 +328,8 @@ static void rtc_update_second2(void *opa if ( s->hw.cmos_data[RTC_REG_B] & RTC_UIE ) { s->hw.cmos_data[RTC_REG_C] |= 0x90; - hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ); - hvm_isa_irq_assert(s->pt.vcpu->domain, RTC_IRQ); + hvm_isa_irq_deassert(d, RTC_IRQ); + hvm_isa_irq_assert(d, RTC_IRQ); } /* clear update in progress bit */ @@ -354,8 +363,8 @@ static uint32_t rtc_ioport_read(void *op break; case RTC_REG_C: ret = s->hw.cmos_data[s->hw.cmos_index]; - hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ); - s->hw.cmos_data[RTC_REG_C] = 0x00; + hvm_isa_irq_deassert(vrtc_domain(s), RTC_IRQ); + s->hw.cmos_data[RTC_REG_C] = 0x00; break; default: ret = s->hw.cmos_data[s->hw.cmos_index]; @@ -367,8 +376,7 @@ static uint32_t rtc_ioport_read(void *op static int handle_rtc_io(ioreq_t *p) { - struct vcpu *v = current; - struct RTCState *vrtc = &v->domain->arch.hvm_domain.pl_time.vrtc; + struct RTCState *vrtc = vcpu_vrtc(current); if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) ) { @@ -392,7 +400,7 @@ static int handle_rtc_io(ioreq_t *p) void rtc_migrate_timers(struct vcpu *v) { - RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc; + RTCState *s = vcpu_vrtc(v); if ( v->vcpu_id == 0 ) { @@ -404,13 +412,14 @@ void rtc_migrate_timers(struct vcpu *v) /* Save RTC hardware state */ static int rtc_save(struct domain *d, hvm_domain_context_t *h) { - return hvm_save_entry(RTC, 0, h, &d->arch.hvm_domain.pl_time.vrtc.hw); + RTCState *s = domain_vrtc(d); + return hvm_save_entry(RTC, 0, h, &s->hw); } /* Reload the hardware state from a saved domain */ static int rtc_load(struct domain *d, hvm_domain_context_t *h) { - RTCState *s = &d->arch.hvm_domain.pl_time.vrtc; + RTCState *s = domain_vrtc(d); /* Restore the registers */ if ( hvm_load_entry(RTC, h, &s->hw) != 0 ) @@ -425,7 +434,7 @@ static int rtc_load(struct domain *d, hv set_timer(&s->second_timer2, s->next_second_time); /* Reset the periodic interrupt timer based on the registers */ - rtc_timer_update(s, d->vcpu[0]); + rtc_timer_update(s); return 0; } @@ -435,9 +444,8 @@ HVM_REGISTER_SAVE_RESTORE(RTC, rtc_save, void rtc_init(struct vcpu *v, int base) { - RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc; - - s->pt.vcpu = v; + RTCState *s = vcpu_vrtc(v); + s->hw.cmos_data[RTC_REG_A] = RTC_REF_CLCK_32KHZ | 6; /* ~1kHz */ s->hw.cmos_data[RTC_REG_B] = RTC_24H; s->hw.cmos_data[RTC_REG_C] = 0; @@ -457,7 +465,7 @@ void rtc_init(struct vcpu *v, int base) void rtc_deinit(struct domain *d) { - RTCState *s = &d->arch.hvm_domain.pl_time.vrtc; + RTCState *s = domain_vrtc(d); destroy_periodic_time(&s->pt); kill_timer(&s->second_timer); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |