ia64/xen-unstable
changeset 13767:9130206e27f8
[HVM] Save/restore: save RTC state.
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
author | Tim Deegan <Tim.Deegan@xensource.com> |
---|---|
date | Wed Jan 31 10:28:47 2007 +0000 (2007-01-31) |
parents | ffcd586dbaae |
children | d653e4bcead0 |
files | xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/intercept.c xen/arch/x86/hvm/rtc.c xen/include/asm-x86/hvm/support.h xen/include/asm-x86/hvm/vpt.h xen/include/public/hvm/save.h |
line diff
1.1 --- a/xen/arch/x86/hvm/hvm.c Wed Jan 31 10:27:10 2007 +0000 1.2 +++ b/xen/arch/x86/hvm/hvm.c Wed Jan 31 10:28:47 2007 +0000 1.3 @@ -254,7 +254,7 @@ int hvm_vcpu_initialise(struct vcpu *v) 1.4 return 0; 1.5 1.6 pit_init(v, cpu_khz); 1.7 - rtc_init(v, RTC_PORT(0), RTC_IRQ); 1.8 + rtc_init(v, RTC_PORT(0)); 1.9 pmtimer_init(v, ACPI_PM_TMR_BLK_ADDRESS); 1.10 hpet_init(v); 1.11
2.1 --- a/xen/arch/x86/hvm/intercept.c Wed Jan 31 10:27:10 2007 +0000 2.2 +++ b/xen/arch/x86/hvm/intercept.c Wed Jan 31 10:28:47 2007 +0000 2.3 @@ -161,10 +161,12 @@ static inline void hvm_mmio_access(struc 2.4 static struct { 2.5 hvm_save_handler save; 2.6 hvm_load_handler load; 2.7 -} hvm_sr_handlers [HVM_SAVE_CODE_MAX + 1] = {{NULL, NULL},}; 2.8 + const char *name; 2.9 +} hvm_sr_handlers [HVM_SAVE_CODE_MAX + 1] = {{NULL, NULL, "<?>"},}; 2.10 2.11 /* Init-time function to add entries to that list */ 2.12 void hvm_register_savevm(uint16_t typecode, 2.13 + const char *name, 2.14 hvm_save_handler save_state, 2.15 hvm_load_handler load_state) 2.16 { 2.17 @@ -173,6 +175,7 @@ void hvm_register_savevm(uint16_t typeco 2.18 ASSERT(hvm_sr_handlers[typecode].load == NULL); 2.19 hvm_sr_handlers[typecode].save = save_state; 2.20 hvm_sr_handlers[typecode].load = load_state; 2.21 + hvm_sr_handlers[typecode].name = name; 2.22 } 2.23 2.24 2.25 @@ -211,6 +214,7 @@ int hvm_save(struct domain *d, hvm_domai 2.26 handler = hvm_sr_handlers[i].save; 2.27 if ( handler != NULL ) 2.28 { 2.29 + gdprintk(XENLOG_INFO, "HVM save: %s\n", hvm_sr_handlers[i].name); 2.30 if ( handler(d, h) != 0 ) 2.31 { 2.32 gdprintk(XENLOG_ERR, 2.33 @@ -312,6 +316,8 @@ int hvm_load(struct domain *d, hvm_domai 2.34 } 2.35 2.36 /* Load the entry */ 2.37 + gdprintk(XENLOG_INFO, "HVM restore: %s %"PRIu16"\n", 2.38 + hvm_sr_handlers[desc->typecode].name, desc->instance); 2.39 if ( handler(d, h) != 0 ) 2.40 { 2.41 gdprintk(XENLOG_ERR,
3.1 --- a/xen/arch/x86/hvm/rtc.c Wed Jan 31 10:27:10 2007 +0000 3.2 +++ b/xen/arch/x86/hvm/rtc.c Wed Jan 31 10:28:47 2007 +0000 3.3 @@ -33,26 +33,26 @@ 3.4 void rtc_periodic_cb(struct vcpu *v, void *opaque) 3.5 { 3.6 RTCState *s = opaque; 3.7 - s->cmos_data[RTC_REG_C] |= 0xc0; 3.8 + s->hw.cmos_data[RTC_REG_C] |= 0xc0; 3.9 } 3.10 3.11 int is_rtc_periodic_irq(void *opaque) 3.12 { 3.13 RTCState *s = opaque; 3.14 3.15 - return !(s->cmos_data[RTC_REG_C] & RTC_AF || 3.16 - s->cmos_data[RTC_REG_C] & RTC_UF); 3.17 + return !(s->hw.cmos_data[RTC_REG_C] & RTC_AF || 3.18 + s->hw.cmos_data[RTC_REG_C] & RTC_UF); 3.19 } 3.20 3.21 /* Enable/configure/disable the periodic timer based on the RTC_PIE and 3.22 * RTC_RATE_SELECT settings */ 3.23 -static void rtc_timer_update(RTCState *s) 3.24 +static void rtc_timer_update(RTCState *s, struct vcpu *v) 3.25 { 3.26 int period_code; 3.27 int period; 3.28 3.29 - period_code = s->cmos_data[RTC_REG_A] & RTC_RATE_SELECT; 3.30 - if ( (period_code != 0) && (s->cmos_data[RTC_REG_B] & RTC_PIE) ) 3.31 + period_code = s->hw.cmos_data[RTC_REG_A] & RTC_RATE_SELECT; 3.32 + if ( (period_code != 0) && (s->hw.cmos_data[RTC_REG_B] & RTC_PIE) ) 3.33 { 3.34 if ( period_code <= 2 ) 3.35 period_code += 7; 3.36 @@ -62,7 +62,7 @@ static void rtc_timer_update(RTCState *s 3.37 #ifdef DEBUG_RTC 3.38 printk("HVM_RTC: period = %uns\n", period); 3.39 #endif 3.40 - create_periodic_time(current, &s->pt, period, RTC_IRQ, 0, rtc_periodic_cb, s); 3.41 + create_periodic_time(v, &s->pt, period, RTC_IRQ, 0, rtc_periodic_cb, s); 3.42 } 3.43 else 3.44 destroy_periodic_time(&s->pt); 3.45 @@ -76,24 +76,24 @@ static int rtc_ioport_write(void *opaque 3.46 3.47 if ( (addr & 1) == 0 ) 3.48 { 3.49 - s->cmos_index = data & 0x7f; 3.50 - return (s->cmos_index < RTC_SIZE); 3.51 + s->hw.cmos_index = data & 0x7f; 3.52 + return (s->hw.cmos_index < RTC_CMOS_SIZE); 3.53 } 3.54 3.55 - if (s->cmos_index >= RTC_SIZE) 3.56 + if (s->hw.cmos_index >= RTC_CMOS_SIZE) 3.57 return 0; 3.58 3.59 #ifdef DEBUG_RTC 3.60 printk("HVM_RTC: write index=0x%02x val=0x%02x\n", 3.61 - s->cmos_index, data); 3.62 + s->hw.cmos_index, data); 3.63 #endif 3.64 3.65 - switch ( s->cmos_index ) 3.66 + switch ( s->hw.cmos_index ) 3.67 { 3.68 case RTC_SECONDS_ALARM: 3.69 case RTC_MINUTES_ALARM: 3.70 case RTC_HOURS_ALARM: 3.71 - s->cmos_data[s->cmos_index] = data; 3.72 + s->hw.cmos_data[s->hw.cmos_index] = data; 3.73 break; 3.74 case RTC_SECONDS: 3.75 case RTC_MINUTES: 3.76 @@ -102,32 +102,32 @@ static int rtc_ioport_write(void *opaque 3.77 case RTC_DAY_OF_MONTH: 3.78 case RTC_MONTH: 3.79 case RTC_YEAR: 3.80 - s->cmos_data[s->cmos_index] = data; 3.81 + s->hw.cmos_data[s->hw.cmos_index] = data; 3.82 /* if in set mode, do not update the time */ 3.83 - if ( !(s->cmos_data[RTC_REG_B] & RTC_SET) ) 3.84 + if ( !(s->hw.cmos_data[RTC_REG_B] & RTC_SET) ) 3.85 rtc_set_time(s); 3.86 break; 3.87 case RTC_REG_A: 3.88 /* UIP bit is read only */ 3.89 - s->cmos_data[RTC_REG_A] = (data & ~RTC_UIP) | 3.90 - (s->cmos_data[RTC_REG_A] & RTC_UIP); 3.91 - rtc_timer_update(s); 3.92 + s->hw.cmos_data[RTC_REG_A] = (data & ~RTC_UIP) | 3.93 + (s->hw.cmos_data[RTC_REG_A] & RTC_UIP); 3.94 + rtc_timer_update(s, current); 3.95 break; 3.96 case RTC_REG_B: 3.97 if ( data & RTC_SET ) 3.98 { 3.99 /* set mode: reset UIP mode */ 3.100 - s->cmos_data[RTC_REG_A] &= ~RTC_UIP; 3.101 + s->hw.cmos_data[RTC_REG_A] &= ~RTC_UIP; 3.102 data &= ~RTC_UIE; 3.103 } 3.104 else 3.105 { 3.106 /* if disabling set mode, update the time */ 3.107 - if ( s->cmos_data[RTC_REG_B] & RTC_SET ) 3.108 + if ( s->hw.cmos_data[RTC_REG_B] & RTC_SET ) 3.109 rtc_set_time(s); 3.110 } 3.111 - s->cmos_data[RTC_REG_B] = data; 3.112 - rtc_timer_update(s); 3.113 + s->hw.cmos_data[RTC_REG_B] = data; 3.114 + rtc_timer_update(s, current); 3.115 break; 3.116 case RTC_REG_C: 3.117 case RTC_REG_D: 3.118 @@ -140,7 +140,7 @@ static int rtc_ioport_write(void *opaque 3.119 3.120 static inline int to_bcd(RTCState *s, int a) 3.121 { 3.122 - if ( s->cmos_data[RTC_REG_B] & 0x04 ) 3.123 + if ( s->hw.cmos_data[RTC_REG_B] & 0x04 ) 3.124 return a; 3.125 else 3.126 return ((a / 10) << 4) | (a % 10); 3.127 @@ -148,7 +148,7 @@ static inline int to_bcd(RTCState *s, in 3.128 3.129 static inline int from_bcd(RTCState *s, int a) 3.130 { 3.131 - if ( s->cmos_data[RTC_REG_B] & 0x04 ) 3.132 + if ( s->hw.cmos_data[RTC_REG_B] & 0x04 ) 3.133 return a; 3.134 else 3.135 return ((a >> 4) * 10) + (a & 0x0f); 3.136 @@ -158,40 +158,40 @@ static void rtc_set_time(RTCState *s) 3.137 { 3.138 struct tm *tm = &s->current_tm; 3.139 3.140 - tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]); 3.141 - tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]); 3.142 - tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f); 3.143 - if ( !(s->cmos_data[RTC_REG_B] & 0x02) && 3.144 - (s->cmos_data[RTC_HOURS] & 0x80) ) 3.145 + tm->tm_sec = from_bcd(s, s->hw.cmos_data[RTC_SECONDS]); 3.146 + tm->tm_min = from_bcd(s, s->hw.cmos_data[RTC_MINUTES]); 3.147 + tm->tm_hour = from_bcd(s, s->hw.cmos_data[RTC_HOURS] & 0x7f); 3.148 + if ( !(s->hw.cmos_data[RTC_REG_B] & 0x02) && 3.149 + (s->hw.cmos_data[RTC_HOURS] & 0x80) ) 3.150 tm->tm_hour += 12; 3.151 - tm->tm_wday = from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]); 3.152 - tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]); 3.153 - tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1; 3.154 - tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + 100; 3.155 + tm->tm_wday = from_bcd(s, s->hw.cmos_data[RTC_DAY_OF_WEEK]); 3.156 + tm->tm_mday = from_bcd(s, s->hw.cmos_data[RTC_DAY_OF_MONTH]); 3.157 + tm->tm_mon = from_bcd(s, s->hw.cmos_data[RTC_MONTH]) - 1; 3.158 + tm->tm_year = from_bcd(s, s->hw.cmos_data[RTC_YEAR]) + 100; 3.159 } 3.160 3.161 static void rtc_copy_date(RTCState *s) 3.162 { 3.163 const struct tm *tm = &s->current_tm; 3.164 3.165 - s->cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec); 3.166 - s->cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min); 3.167 - if ( s->cmos_data[RTC_REG_B] & RTC_24H ) 3.168 + s->hw.cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec); 3.169 + s->hw.cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min); 3.170 + if ( s->hw.cmos_data[RTC_REG_B] & RTC_24H ) 3.171 { 3.172 /* 24 hour format */ 3.173 - s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour); 3.174 + s->hw.cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour); 3.175 } 3.176 else 3.177 { 3.178 /* 12 hour format */ 3.179 - s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour % 12); 3.180 + s->hw.cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour % 12); 3.181 if ( tm->tm_hour >= 12 ) 3.182 - s->cmos_data[RTC_HOURS] |= 0x80; 3.183 + s->hw.cmos_data[RTC_HOURS] |= 0x80; 3.184 } 3.185 - s->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(s, tm->tm_wday); 3.186 - s->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(s, tm->tm_mday); 3.187 - s->cmos_data[RTC_MONTH] = to_bcd(s, tm->tm_mon + 1); 3.188 - s->cmos_data[RTC_YEAR] = to_bcd(s, tm->tm_year % 100); 3.189 + s->hw.cmos_data[RTC_DAY_OF_WEEK] = to_bcd(s, tm->tm_wday); 3.190 + s->hw.cmos_data[RTC_DAY_OF_MONTH] = to_bcd(s, tm->tm_mday); 3.191 + s->hw.cmos_data[RTC_MONTH] = to_bcd(s, tm->tm_mon + 1); 3.192 + s->hw.cmos_data[RTC_YEAR] = to_bcd(s, tm->tm_year % 100); 3.193 } 3.194 3.195 /* month is between 0 and 11. */ 3.196 @@ -251,7 +251,7 @@ static void rtc_update_second(void *opaq 3.197 RTCState *s = opaque; 3.198 3.199 /* if the oscillator is not in normal operation, we do not update */ 3.200 - if ( (s->cmos_data[RTC_REG_A] & RTC_DIV_CTL) != RTC_REF_CLCK_32KHZ ) 3.201 + if ( (s->hw.cmos_data[RTC_REG_A] & RTC_DIV_CTL) != RTC_REF_CLCK_32KHZ ) 3.202 { 3.203 s->next_second_time += 1000000000ULL; 3.204 set_timer(&s->second_timer, s->next_second_time); 3.205 @@ -260,8 +260,8 @@ static void rtc_update_second(void *opaq 3.206 { 3.207 rtc_next_second(&s->current_tm); 3.208 3.209 - if ( !(s->cmos_data[RTC_REG_B] & RTC_SET) ) 3.210 - s->cmos_data[RTC_REG_A] |= RTC_UIP; 3.211 + if ( !(s->hw.cmos_data[RTC_REG_B] & RTC_SET) ) 3.212 + s->hw.cmos_data[RTC_REG_A] |= RTC_UIP; 3.213 3.214 /* Delay time before update cycle */ 3.215 set_timer(&s->second_timer2, s->next_second_time + 244000); 3.216 @@ -272,38 +272,38 @@ static void rtc_update_second2(void *opa 3.217 { 3.218 RTCState *s = opaque; 3.219 3.220 - if ( !(s->cmos_data[RTC_REG_B] & RTC_SET) ) 3.221 + if ( !(s->hw.cmos_data[RTC_REG_B] & RTC_SET) ) 3.222 rtc_copy_date(s); 3.223 3.224 /* check alarm */ 3.225 - if ( s->cmos_data[RTC_REG_B] & RTC_AIE ) 3.226 + if ( s->hw.cmos_data[RTC_REG_B] & RTC_AIE ) 3.227 { 3.228 - if ( ((s->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 || 3.229 - from_bcd(s, s->cmos_data[RTC_SECONDS_ALARM]) == 3.230 + if ( ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 || 3.231 + from_bcd(s, s->hw.cmos_data[RTC_SECONDS_ALARM]) == 3.232 s->current_tm.tm_sec) && 3.233 - ((s->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 || 3.234 - from_bcd(s, s->cmos_data[RTC_MINUTES_ALARM]) == 3.235 + ((s->hw.cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 || 3.236 + from_bcd(s, s->hw.cmos_data[RTC_MINUTES_ALARM]) == 3.237 s->current_tm.tm_min) && 3.238 - ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 || 3.239 - from_bcd(s, s->cmos_data[RTC_HOURS_ALARM]) == 3.240 + ((s->hw.cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 || 3.241 + from_bcd(s, s->hw.cmos_data[RTC_HOURS_ALARM]) == 3.242 s->current_tm.tm_hour) ) 3.243 { 3.244 - s->cmos_data[RTC_REG_C] |= 0xa0; 3.245 - hvm_isa_irq_deassert(s->pt.vcpu->domain, s->irq); 3.246 - hvm_isa_irq_assert(s->pt.vcpu->domain, s->irq); 3.247 + s->hw.cmos_data[RTC_REG_C] |= 0xa0; 3.248 + hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ); 3.249 + hvm_isa_irq_assert(s->pt.vcpu->domain, RTC_IRQ); 3.250 } 3.251 } 3.252 3.253 /* update ended interrupt */ 3.254 - if ( s->cmos_data[RTC_REG_B] & RTC_UIE ) 3.255 + if ( s->hw.cmos_data[RTC_REG_B] & RTC_UIE ) 3.256 { 3.257 - s->cmos_data[RTC_REG_C] |= 0x90; 3.258 - hvm_isa_irq_deassert(s->pt.vcpu->domain, s->irq); 3.259 - hvm_isa_irq_assert(s->pt.vcpu->domain, s->irq); 3.260 + s->hw.cmos_data[RTC_REG_C] |= 0x90; 3.261 + hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ); 3.262 + hvm_isa_irq_assert(s->pt.vcpu->domain, RTC_IRQ); 3.263 } 3.264 3.265 /* clear update in progress bit */ 3.266 - s->cmos_data[RTC_REG_A] &= ~RTC_UIP; 3.267 + s->hw.cmos_data[RTC_REG_A] &= ~RTC_UIP; 3.268 3.269 s->next_second_time += 1000000000ULL; 3.270 set_timer(&s->second_timer, s->next_second_time); 3.271 @@ -317,7 +317,7 @@ static uint32_t rtc_ioport_read(void *op 3.272 if ( (addr & 1) == 0 ) 3.273 return 0xff; 3.274 3.275 - switch ( s->cmos_index ) 3.276 + switch ( s->hw.cmos_index ) 3.277 { 3.278 case RTC_SECONDS: 3.279 case RTC_MINUTES: 3.280 @@ -326,24 +326,24 @@ static uint32_t rtc_ioport_read(void *op 3.281 case RTC_DAY_OF_MONTH: 3.282 case RTC_MONTH: 3.283 case RTC_YEAR: 3.284 - ret = s->cmos_data[s->cmos_index]; 3.285 + ret = s->hw.cmos_data[s->hw.cmos_index]; 3.286 break; 3.287 case RTC_REG_A: 3.288 - ret = s->cmos_data[s->cmos_index]; 3.289 + ret = s->hw.cmos_data[s->hw.cmos_index]; 3.290 break; 3.291 case RTC_REG_C: 3.292 - ret = s->cmos_data[s->cmos_index]; 3.293 - hvm_isa_irq_deassert(s->pt.vcpu->domain, s->irq); 3.294 - s->cmos_data[RTC_REG_C] = 0x00; 3.295 + ret = s->hw.cmos_data[s->hw.cmos_index]; 3.296 + hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ); 3.297 + s->hw.cmos_data[RTC_REG_C] = 0x00; 3.298 break; 3.299 default: 3.300 - ret = s->cmos_data[s->cmos_index]; 3.301 + ret = s->hw.cmos_data[s->hw.cmos_index]; 3.302 break; 3.303 } 3.304 3.305 #ifdef DEBUG_RTC 3.306 printk("HVM_RTC: read index=0x%02x val=0x%02x\n", 3.307 - s->cmos_index, ret); 3.308 + s->hw.cmos_index, ret); 3.309 #endif 3.310 3.311 return ret; 3.312 @@ -365,7 +365,7 @@ static int handle_rtc_io(ioreq_t *p) 3.313 if ( rtc_ioport_write(vrtc, p->addr, p->data & 0xFF) ) 3.314 return 1; 3.315 } 3.316 - else if ( (p->dir == 1) && (vrtc->cmos_index < RTC_SIZE) ) /* read */ 3.317 + else if ( (p->dir == 1) && (vrtc->hw.cmos_index < RTC_CMOS_SIZE) ) /* read */ 3.318 { 3.319 p->data = rtc_ioport_read(vrtc, p->addr); 3.320 return 1; 3.321 @@ -388,16 +388,47 @@ void rtc_migrate_timers(struct vcpu *v) 3.322 } 3.323 } 3.324 3.325 -void rtc_init(struct vcpu *v, int base, int irq) 3.326 +/* Save RTC hardware state */ 3.327 +static int rtc_save(struct domain *d, hvm_domain_context_t *h) 3.328 +{ 3.329 + return hvm_save_entry(RTC, 0, h, &d->arch.hvm_domain.pl_time.vrtc.hw); 3.330 +} 3.331 + 3.332 +/* Reload the hardware state from a saved domain */ 3.333 +static int rtc_load(struct domain *d, hvm_domain_context_t *h) 3.334 +{ 3.335 + RTCState *s = &d->arch.hvm_domain.pl_time.vrtc; 3.336 + 3.337 + /* Restore the registers */ 3.338 + if ( hvm_load_entry(RTC, h, &s->hw) != 0 ) 3.339 + return -EINVAL; 3.340 + 3.341 + /* Reset the wall-clock time. In normal running, this runs with host 3.342 + * time, so let's keep doing that. */ 3.343 + s->current_tm = gmtime(get_localtime(d)); 3.344 + rtc_copy_date(s); 3.345 + s->next_second_time = NOW() + 1000000000ULL; 3.346 + stop_timer(&s->second_timer); 3.347 + set_timer(&s->second_timer2, s->next_second_time); 3.348 + 3.349 + /* Reset the periodic interrupt timer based on the registers */ 3.350 + rtc_timer_update(s, d->vcpu[0]); 3.351 + 3.352 + return 0; 3.353 +} 3.354 + 3.355 +HVM_REGISTER_SAVE_RESTORE(RTC, rtc_save, rtc_load); 3.356 + 3.357 + 3.358 +void rtc_init(struct vcpu *v, int base) 3.359 { 3.360 RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc; 3.361 3.362 s->pt.vcpu = v; 3.363 - s->irq = irq; 3.364 - s->cmos_data[RTC_REG_A] = RTC_REF_CLCK_32KHZ | 6; /* ~1kHz */ 3.365 - s->cmos_data[RTC_REG_B] = RTC_24H; 3.366 - s->cmos_data[RTC_REG_C] = 0; 3.367 - s->cmos_data[RTC_REG_D] = RTC_VRT; 3.368 + s->hw.cmos_data[RTC_REG_A] = RTC_REF_CLCK_32KHZ | 6; /* ~1kHz */ 3.369 + s->hw.cmos_data[RTC_REG_B] = RTC_24H; 3.370 + s->hw.cmos_data[RTC_REG_C] = 0; 3.371 + s->hw.cmos_data[RTC_REG_D] = RTC_VRT; 3.372 3.373 s->current_tm = gmtime(get_localtime(v->domain)); 3.374 rtc_copy_date(s);
4.1 --- a/xen/include/asm-x86/hvm/support.h Wed Jan 31 10:27:10 2007 +0000 4.2 +++ b/xen/include/asm-x86/hvm/support.h Wed Jan 31 10:28:47 2007 +0000 4.3 @@ -215,17 +215,18 @@ typedef int (*hvm_load_handler) (struct 4.4 hvm_domain_context_t *h); 4.5 4.6 /* Init-time function to declare a pair of handlers for a type */ 4.7 -void hvm_register_savevm(uint16_t typecode, 4.8 +void hvm_register_savevm(uint16_t typecode, 4.9 + const char *name, 4.10 hvm_save_handler save_state, 4.11 hvm_load_handler load_state); 4.12 4.13 /* Syntactic sugar around that function */ 4.14 -#define HVM_REGISTER_SAVE_RESTORE(_x, _save, _load) \ 4.15 -static int __hvm_register_##_x##_save_and_restore(void) \ 4.16 -{ \ 4.17 - hvm_register_savevm(HVM_SAVE_CODE(_x), &_save, &_load); \ 4.18 - return 0; \ 4.19 -} \ 4.20 +#define HVM_REGISTER_SAVE_RESTORE(_x, _save, _load) \ 4.21 +static int __hvm_register_##_x##_save_and_restore(void) \ 4.22 +{ \ 4.23 + hvm_register_savevm(HVM_SAVE_CODE(_x), #_x, &_save, &_load); \ 4.24 + return 0; \ 4.25 +} \ 4.26 __initcall(__hvm_register_##_x##_save_and_restore); 4.27 4.28
5.1 --- a/xen/include/asm-x86/hvm/vpt.h Wed Jan 31 10:27:10 2007 +0000 5.2 +++ b/xen/include/asm-x86/hvm/vpt.h Wed Jan 31 10:28:47 2007 +0000 5.3 @@ -97,12 +97,11 @@ typedef struct PITState { 5.4 struct periodic_time pt[3]; 5.5 } PITState; 5.6 5.7 -#define RTC_SIZE 14 5.8 typedef struct RTCState { 5.9 - uint8_t cmos_data[RTC_SIZE]; /* Only handle time/interrupt part in HV */ 5.10 - uint8_t cmos_index; 5.11 + /* Hardware state */ 5.12 + struct hvm_hw_rtc hw; 5.13 + /* RTC's idea of the current time */ 5.14 struct tm current_tm; 5.15 - int irq; 5.16 /* second update */ 5.17 int64_t next_second_time; 5.18 struct timer second_timer; 5.19 @@ -145,7 +144,7 @@ void pit_init(struct vcpu *v, unsigned l 5.20 void pit_stop_channel0_irq(PITState * pit); 5.21 void pit_migrate_timers(struct vcpu *v); 5.22 void pit_deinit(struct domain *d); 5.23 -void rtc_init(struct vcpu *v, int base, int irq); 5.24 +void rtc_init(struct vcpu *v, int base); 5.25 void rtc_migrate_timers(struct vcpu *v); 5.26 void rtc_deinit(struct domain *d); 5.27 int is_rtc_periodic_irq(void *opaque);
6.1 --- a/xen/include/public/hvm/save.h Wed Jan 31 10:27:10 2007 +0000 6.2 +++ b/xen/include/public/hvm/save.h Wed Jan 31 10:28:47 2007 +0000 6.3 @@ -367,9 +367,24 @@ DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 8, str 6.4 6.5 6.6 /* 6.7 + * RTC 6.8 + */ 6.9 + 6.10 +#define RTC_CMOS_SIZE 14 6.11 +struct hvm_hw_rtc { 6.12 + /* CMOS bytes */ 6.13 + uint8_t cmos_data[RTC_CMOS_SIZE]; 6.14 + /* Index register for 2-part operations */ 6.15 + uint8_t cmos_index; 6.16 +}; 6.17 + 6.18 +DECLARE_HVM_SAVE_TYPE(RTC, 9, struct hvm_hw_rtc); 6.19 + 6.20 + 6.21 +/* 6.22 * Largest type-code in use 6.23 */ 6.24 -#define HVM_SAVE_CODE_MAX 8 6.25 +#define HVM_SAVE_CODE_MAX 9 6.26 6.27 6.28 /*