1 /*
2 * QEMU MC146818 RTC emulation
3 *
4 * Copyright (c) 2003-2004 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25 #include <asm/mc146818rtc.h>
26 #include <asm/hvm/vpt.h>
27 #include <asm/hvm/io.h>
28 #include <asm/hvm/support.h>
29 #include <asm/current.h>
30 #include <xen/trace.h>
31
32 #define USEC_PER_SEC 1000000UL
33 #define NS_PER_USEC 1000UL
34 #define NS_PER_SEC 1000000000ULL
35
36 #define SEC_PER_MIN 60
37 #define SEC_PER_HOUR 3600
38 #define MIN_PER_HOUR 60
39 #define HOUR_PER_DAY 24
40
41 #define domain_vrtc(x) (&(x)->arch.hvm_domain.pl_time->vrtc)
42 #define vcpu_vrtc(x) (domain_vrtc((x)->domain))
43 #define vrtc_domain(x) (container_of(x, struct pl_time, vrtc)->domain)
44 #define vrtc_vcpu(x) (pt_global_vcpu_target(vrtc_domain(x)))
45 #define epoch_year 1900
46 #define get_year(x) (x + epoch_year)
47
48 enum rtc_mode {
49 rtc_mode_no_ack,
50 rtc_mode_strict
51 };
52
53 /* This must be in sync with how hvmloader sets the ACPI WAET flags. */
54 #define mode_is(d, m) ((void)(d), rtc_mode_##m == rtc_mode_no_ack)
55 #define rtc_mode_is(s, m) mode_is(vrtc_domain(s), m)
56
57 static void rtc_copy_date(RTCState *s);
58 static void rtc_set_time(RTCState *s);
59 static inline int from_bcd(RTCState *s, int a);
60 static inline int convert_hour(RTCState *s, int hour);
61
rtc_update_irq(RTCState * s)62 static void rtc_update_irq(RTCState *s)
63 {
64 ASSERT(spin_is_locked(&s->lock));
65
66 if ( rtc_mode_is(s, strict) && (s->hw.cmos_data[RTC_REG_C] & RTC_IRQF) )
67 return;
68
69 /* IRQ is raised if any source is both raised & enabled */
70 if ( !(s->hw.cmos_data[RTC_REG_B] &
71 s->hw.cmos_data[RTC_REG_C] &
72 (RTC_PF | RTC_AF | RTC_UF)) )
73 return;
74
75 s->hw.cmos_data[RTC_REG_C] |= RTC_IRQF;
76 if ( rtc_mode_is(s, no_ack) )
77 hvm_isa_irq_deassert(vrtc_domain(s), RTC_IRQ);
78 hvm_isa_irq_assert(vrtc_domain(s), RTC_IRQ, NULL);
79 }
80
81 /* Called by the VPT code after it's injected a PF interrupt for us.
82 * Fix up the register state to reflect what happened. */
rtc_pf_callback(struct vcpu * v,void * opaque)83 static void rtc_pf_callback(struct vcpu *v, void *opaque)
84 {
85 RTCState *s = opaque;
86
87 spin_lock(&s->lock);
88
89 if ( !rtc_mode_is(s, no_ack)
90 && (s->hw.cmos_data[RTC_REG_C] & RTC_IRQF)
91 && ++(s->pt_dead_ticks) >= 10 )
92 {
93 /* VM is ignoring its RTC; no point in running the timer */
94 TRACE_0D(TRC_HVM_EMUL_RTC_STOP_TIMER);
95 destroy_periodic_time(&s->pt);
96 s->period = 0;
97 }
98
99 s->hw.cmos_data[RTC_REG_C] |= RTC_PF|RTC_IRQF;
100
101 spin_unlock(&s->lock);
102 }
103
104 /* Check whether the REG_C.PF bit should have been set by a tick since
105 * the last time we looked. This is used to track ticks when REG_B.PIE
106 * is clear; when PIE is set, PF ticks are handled by the VPT callbacks. */
check_for_pf_ticks(RTCState * s)107 static void check_for_pf_ticks(RTCState *s)
108 {
109 s_time_t now;
110
111 if ( s->period == 0 || (s->hw.cmos_data[RTC_REG_B] & RTC_PIE) )
112 return;
113
114 now = NOW();
115 if ( (now - s->start_time) / s->period
116 != (s->check_ticks_since - s->start_time) / s->period )
117 s->hw.cmos_data[RTC_REG_C] |= RTC_PF;
118
119 s->check_ticks_since = now;
120 }
121
122 /* Enable/configure/disable the periodic timer based on the RTC_PIE and
123 * RTC_RATE_SELECT settings */
rtc_timer_update(RTCState * s)124 static void rtc_timer_update(RTCState *s)
125 {
126 int period_code, period, delta;
127 struct vcpu *v = vrtc_vcpu(s);
128
129 ASSERT(spin_is_locked(&s->lock));
130
131 s->pt_dead_ticks = 0;
132
133 period_code = s->hw.cmos_data[RTC_REG_A] & RTC_RATE_SELECT;
134 switch ( s->hw.cmos_data[RTC_REG_A] & RTC_DIV_CTL )
135 {
136 case RTC_REF_CLCK_32KHZ:
137 if ( (period_code != 0) && (period_code <= 2) )
138 period_code += 7;
139 /* fall through */
140 case RTC_REF_CLCK_1MHZ:
141 case RTC_REF_CLCK_4MHZ:
142 if ( period_code != 0 )
143 {
144 period = 1 << (period_code - 1); /* period in 32 Khz cycles */
145 period = DIV_ROUND(period * 1000000000ULL, 32768); /* in ns */
146 if ( period != s->period )
147 {
148 s_time_t now = NOW();
149
150 s->period = period;
151 if ( v->domain->arch.hvm_domain.params[HVM_PARAM_VPT_ALIGN] )
152 delta = 0;
153 else
154 delta = period - ((now - s->start_time) % period);
155 if ( s->hw.cmos_data[RTC_REG_B] & RTC_PIE )
156 {
157 TRACE_2D(TRC_HVM_EMUL_RTC_START_TIMER, delta, period);
158 create_periodic_time(v, &s->pt, delta, period,
159 RTC_IRQ, rtc_pf_callback, s);
160 }
161 else
162 s->check_ticks_since = now;
163 }
164 break;
165 }
166 /* fall through */
167 default:
168 TRACE_0D(TRC_HVM_EMUL_RTC_STOP_TIMER);
169 destroy_periodic_time(&s->pt);
170 s->period = 0;
171 break;
172 }
173 }
174
175 /* handle update-ended timer */
check_update_timer(RTCState * s)176 static void check_update_timer(RTCState *s)
177 {
178 uint64_t next_update_time, expire_time;
179 uint64_t guest_usec;
180 struct domain *d = vrtc_domain(s);
181 stop_timer(&s->update_timer);
182 stop_timer(&s->update_timer2);
183
184 ASSERT(spin_is_locked(&s->lock));
185
186 if (!(s->hw.cmos_data[RTC_REG_C] & RTC_UF) &&
187 !(s->hw.cmos_data[RTC_REG_B] & RTC_SET))
188 {
189 s->use_timer = 1;
190 guest_usec = get_localtime_us(d) % USEC_PER_SEC;
191 if (guest_usec >= (USEC_PER_SEC - 244))
192 {
193 /* RTC is in update cycle */
194 s->hw.cmos_data[RTC_REG_A] |= RTC_UIP;
195 next_update_time = (USEC_PER_SEC - guest_usec) * NS_PER_USEC;
196 expire_time = NOW() + next_update_time;
197 /* release lock before set timer */
198 spin_unlock(&s->lock);
199 set_timer(&s->update_timer2, expire_time);
200 /* fetch lock again */
201 spin_lock(&s->lock);
202 }
203 else
204 {
205 next_update_time = (USEC_PER_SEC - guest_usec - 244) * NS_PER_USEC;
206 expire_time = NOW() + next_update_time;
207 s->next_update_time = expire_time;
208 /* release lock before set timer */
209 spin_unlock(&s->lock);
210 set_timer(&s->update_timer, expire_time);
211 /* fetch lock again */
212 spin_lock(&s->lock);
213 }
214 }
215 else
216 s->use_timer = 0;
217 }
218
rtc_update_timer(void * opaque)219 static void rtc_update_timer(void *opaque)
220 {
221 RTCState *s = opaque;
222
223 spin_lock(&s->lock);
224 if (!(s->hw.cmos_data[RTC_REG_B] & RTC_SET))
225 {
226 s->hw.cmos_data[RTC_REG_A] |= RTC_UIP;
227 set_timer(&s->update_timer2, s->next_update_time + 244000UL);
228 }
229 spin_unlock(&s->lock);
230 }
231
rtc_update_timer2(void * opaque)232 static void rtc_update_timer2(void *opaque)
233 {
234 RTCState *s = opaque;
235
236 spin_lock(&s->lock);
237 if (!(s->hw.cmos_data[RTC_REG_B] & RTC_SET))
238 {
239 s->hw.cmos_data[RTC_REG_C] |= RTC_UF;
240 s->hw.cmos_data[RTC_REG_A] &= ~RTC_UIP;
241 rtc_update_irq(s);
242 check_update_timer(s);
243 }
244 spin_unlock(&s->lock);
245 }
246
247 /* handle alarm timer */
alarm_timer_update(RTCState * s)248 static void alarm_timer_update(RTCState *s)
249 {
250 uint64_t next_update_time, next_alarm_sec;
251 uint64_t expire_time;
252 int32_t alarm_sec, alarm_min, alarm_hour, cur_hour, cur_min, cur_sec;
253 int32_t hour, min;
254 struct domain *d = vrtc_domain(s);
255
256 ASSERT(spin_is_locked(&s->lock));
257
258 stop_timer(&s->alarm_timer);
259
260 if (!(s->hw.cmos_data[RTC_REG_C] & RTC_AF) &&
261 !(s->hw.cmos_data[RTC_REG_B] & RTC_SET))
262 {
263 s->current_tm = gmtime(get_localtime(d));
264 rtc_copy_date(s);
265
266 alarm_sec = from_bcd(s, s->hw.cmos_data[RTC_SECONDS_ALARM]);
267 alarm_min = from_bcd(s, s->hw.cmos_data[RTC_MINUTES_ALARM]);
268 alarm_hour = convert_hour(s, s->hw.cmos_data[RTC_HOURS_ALARM]);
269
270 cur_sec = from_bcd(s, s->hw.cmos_data[RTC_SECONDS]);
271 cur_min = from_bcd(s, s->hw.cmos_data[RTC_MINUTES]);
272 cur_hour = convert_hour(s, s->hw.cmos_data[RTC_HOURS]);
273
274 next_update_time = USEC_PER_SEC - (get_localtime_us(d) % USEC_PER_SEC);
275 next_update_time = next_update_time * NS_PER_USEC + NOW();
276
277 if ((s->hw.cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0)
278 {
279 if ((s->hw.cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0)
280 {
281 if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0)
282 next_alarm_sec = 1;
283 else if (cur_sec < alarm_sec)
284 next_alarm_sec = alarm_sec - cur_sec;
285 else
286 next_alarm_sec = alarm_sec + SEC_PER_MIN - cur_sec;
287 }
288 else
289 {
290 if (cur_min < alarm_min)
291 {
292 min = alarm_min - cur_min;
293 next_alarm_sec = min * SEC_PER_MIN - cur_sec;
294 if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0)
295 next_alarm_sec += 0;
296 else
297 next_alarm_sec += alarm_sec;
298 }
299 else if (cur_min == alarm_min)
300 {
301 if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0)
302 next_alarm_sec = 1;
303 else if (cur_sec < alarm_sec)
304 next_alarm_sec = alarm_sec - cur_sec;
305 else
306 {
307 min = alarm_min + MIN_PER_HOUR - cur_min;
308 next_alarm_sec =
309 alarm_sec + min * SEC_PER_MIN - cur_sec;
310 }
311 }
312 else
313 {
314 min = alarm_min + MIN_PER_HOUR - cur_min;
315 next_alarm_sec = min * SEC_PER_MIN - cur_sec;
316 if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0)
317 next_alarm_sec += 0;
318 else
319 next_alarm_sec += alarm_sec;
320 }
321 }
322 }
323 else
324 {
325 if (cur_hour < alarm_hour)
326 {
327 hour = alarm_hour - cur_hour;
328 next_alarm_sec = hour * SEC_PER_HOUR -
329 cur_min * SEC_PER_MIN - cur_sec;
330 if ((s->hw.cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0)
331 {
332 if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0)
333 next_alarm_sec += 0;
334 else
335 next_alarm_sec += alarm_sec;
336 }
337 else
338 {
339 next_alarm_sec += alarm_min * SEC_PER_MIN;
340 if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0)
341 next_alarm_sec += 0;
342 else
343 next_alarm_sec += alarm_sec;
344 }
345 }
346 else if (cur_hour == alarm_hour)
347 {
348 if ((s->hw.cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0)
349 {
350 if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0)
351 next_alarm_sec = 1;
352 else if (cur_sec < alarm_sec)
353 next_alarm_sec = alarm_sec - cur_sec;
354 else
355 next_alarm_sec = alarm_sec + SEC_PER_MIN - cur_sec;
356 }
357 else if (cur_min < alarm_min)
358 {
359 min = alarm_min - cur_min;
360 next_alarm_sec = min * SEC_PER_MIN - cur_sec;
361 if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0)
362 next_alarm_sec += 0;
363 else
364 next_alarm_sec += alarm_sec;
365 }
366 else if (cur_min == alarm_min)
367 {
368 if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0)
369 next_alarm_sec = 1;
370 else if (cur_sec < alarm_sec)
371 next_alarm_sec = alarm_sec - cur_sec;
372 else
373 {
374 hour = alarm_hour + HOUR_PER_DAY - cur_hour;
375 next_alarm_sec = hour * SEC_PER_HOUR -
376 cur_min * SEC_PER_MIN - cur_sec;
377 next_alarm_sec += alarm_min * SEC_PER_MIN + alarm_sec;
378 }
379 }
380 else
381 {
382 hour = alarm_hour + HOUR_PER_DAY - cur_hour;
383 next_alarm_sec = hour * SEC_PER_HOUR -
384 cur_min * SEC_PER_MIN - cur_sec;
385 next_alarm_sec += alarm_min * SEC_PER_MIN;
386 if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0)
387 next_alarm_sec += 0;
388 else
389 next_alarm_sec += alarm_sec;
390 }
391 }
392 else
393 {
394 hour = alarm_hour + HOUR_PER_DAY - cur_hour;
395 next_alarm_sec = hour * SEC_PER_HOUR -
396 cur_min * SEC_PER_MIN - cur_sec;
397 if ((s->hw.cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0)
398 {
399 if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0)
400 next_alarm_sec += 0;
401 else
402 next_alarm_sec += alarm_sec;
403 }
404 else
405 {
406 next_alarm_sec += alarm_min * SEC_PER_MIN;
407 if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0)
408 next_alarm_sec += 0;
409 else
410 next_alarm_sec += alarm_sec;
411 }
412 }
413 }
414 expire_time = (next_alarm_sec - 1) * NS_PER_SEC + next_update_time;
415 /* release lock before set timer */
416 spin_unlock(&s->lock);
417 set_timer(&s->alarm_timer, expire_time);
418 /* fetch lock again */
419 spin_lock(&s->lock);
420 }
421 }
422
rtc_alarm_cb(void * opaque)423 static void rtc_alarm_cb(void *opaque)
424 {
425 RTCState *s = opaque;
426
427 spin_lock(&s->lock);
428 if (!(s->hw.cmos_data[RTC_REG_B] & RTC_SET))
429 {
430 s->hw.cmos_data[RTC_REG_C] |= RTC_AF;
431 rtc_update_irq(s);
432 alarm_timer_update(s);
433 }
434 spin_unlock(&s->lock);
435 }
436
rtc_ioport_write(void * opaque,uint32_t addr,uint32_t data)437 static int rtc_ioport_write(void *opaque, uint32_t addr, uint32_t data)
438 {
439 RTCState *s = opaque;
440 struct domain *d = vrtc_domain(s);
441 uint32_t orig;
442
443 spin_lock(&s->lock);
444
445 if ( (addr & 1) == 0 )
446 {
447 data &= 0x7f;
448 s->hw.cmos_index = data;
449 spin_unlock(&s->lock);
450 return (data < RTC_CMOS_SIZE);
451 }
452
453 if ( s->hw.cmos_index >= RTC_CMOS_SIZE )
454 {
455 spin_unlock(&s->lock);
456 return 0;
457 }
458
459 orig = s->hw.cmos_data[s->hw.cmos_index];
460 switch ( s->hw.cmos_index )
461 {
462 case RTC_SECONDS_ALARM:
463 case RTC_MINUTES_ALARM:
464 case RTC_HOURS_ALARM:
465 s->hw.cmos_data[s->hw.cmos_index] = data;
466 alarm_timer_update(s);
467 break;
468 case RTC_SECONDS:
469 case RTC_MINUTES:
470 case RTC_HOURS:
471 case RTC_DAY_OF_WEEK:
472 case RTC_DAY_OF_MONTH:
473 case RTC_MONTH:
474 case RTC_YEAR:
475 /* if in set mode, just write the register */
476 if ( (s->hw.cmos_data[RTC_REG_B] & RTC_SET) )
477 s->hw.cmos_data[s->hw.cmos_index] = data;
478 else
479 {
480 /* Fetch the current time and update just this field. */
481 s->current_tm = gmtime(get_localtime(d));
482 rtc_copy_date(s);
483 s->hw.cmos_data[s->hw.cmos_index] = data;
484 rtc_set_time(s);
485 }
486 alarm_timer_update(s);
487 break;
488 case RTC_REG_A:
489 /* UIP bit is read only */
490 s->hw.cmos_data[RTC_REG_A] = (data & ~RTC_UIP) | (orig & RTC_UIP);
491 if ( (data ^ orig) & ~RTC_UIP )
492 rtc_timer_update(s);
493 break;
494 case RTC_REG_B:
495 if ( data & RTC_SET )
496 {
497 /* set mode: reset UIP mode */
498 s->hw.cmos_data[RTC_REG_A] &= ~RTC_UIP;
499 /* adjust cmos before stopping */
500 if (!(orig & RTC_SET))
501 {
502 s->current_tm = gmtime(get_localtime(d));
503 rtc_copy_date(s);
504 }
505 }
506 else
507 {
508 /* if disabling set mode, update the time */
509 if ( orig & RTC_SET )
510 rtc_set_time(s);
511 }
512 check_for_pf_ticks(s);
513 s->hw.cmos_data[RTC_REG_B] = data;
514 /*
515 * If the interrupt is already set when the interrupt becomes
516 * enabled, raise an interrupt immediately.
517 */
518 rtc_update_irq(s);
519 if ( (data ^ orig) & RTC_PIE )
520 {
521 TRACE_0D(TRC_HVM_EMUL_RTC_STOP_TIMER);
522 destroy_periodic_time(&s->pt);
523 s->period = 0;
524 rtc_timer_update(s);
525 }
526 if ( (data ^ orig) & RTC_SET )
527 check_update_timer(s);
528 if ( (data ^ orig) & (RTC_24H | RTC_DM_BINARY | RTC_SET) )
529 alarm_timer_update(s);
530 break;
531 case RTC_REG_C:
532 case RTC_REG_D:
533 /* cannot write to them */
534 break;
535 }
536
537 spin_unlock(&s->lock);
538
539 return 1;
540 }
541
to_bcd(RTCState * s,int a)542 static inline int to_bcd(RTCState *s, int a)
543 {
544 if ( s->hw.cmos_data[RTC_REG_B] & RTC_DM_BINARY )
545 return a;
546 else
547 return ((a / 10) << 4) | (a % 10);
548 }
549
from_bcd(RTCState * s,int a)550 static inline int from_bcd(RTCState *s, int a)
551 {
552 if ( s->hw.cmos_data[RTC_REG_B] & RTC_DM_BINARY )
553 return a;
554 else
555 return ((a >> 4) * 10) + (a & 0x0f);
556 }
557
558 /* Hours in 12 hour mode are in 1-12 range, not 0-11.
559 * So we need convert it before using it*/
convert_hour(RTCState * s,int raw)560 static inline int convert_hour(RTCState *s, int raw)
561 {
562 int hour = from_bcd(s, raw & 0x7f);
563
564 if (!(s->hw.cmos_data[RTC_REG_B] & RTC_24H))
565 {
566 hour %= 12;
567 if (raw & 0x80)
568 hour += 12;
569 }
570 return hour;
571 }
572
rtc_set_time(RTCState * s)573 static void rtc_set_time(RTCState *s)
574 {
575 struct tm *tm = &s->current_tm;
576 struct domain *d = vrtc_domain(s);
577 unsigned long before, after; /* XXX s_time_t */
578
579 ASSERT(spin_is_locked(&s->lock));
580
581 before = mktime(get_year(tm->tm_year), tm->tm_mon + 1, tm->tm_mday,
582 tm->tm_hour, tm->tm_min, tm->tm_sec);
583
584 tm->tm_sec = from_bcd(s, s->hw.cmos_data[RTC_SECONDS]);
585 tm->tm_min = from_bcd(s, s->hw.cmos_data[RTC_MINUTES]);
586 tm->tm_hour = convert_hour(s, s->hw.cmos_data[RTC_HOURS]);
587 tm->tm_wday = from_bcd(s, s->hw.cmos_data[RTC_DAY_OF_WEEK]);
588 tm->tm_mday = from_bcd(s, s->hw.cmos_data[RTC_DAY_OF_MONTH]);
589 tm->tm_mon = from_bcd(s, s->hw.cmos_data[RTC_MONTH]) - 1;
590 tm->tm_year = from_bcd(s, s->hw.cmos_data[RTC_YEAR]) + 100;
591
592 after = mktime(get_year(tm->tm_year), tm->tm_mon + 1, tm->tm_mday,
593 tm->tm_hour, tm->tm_min, tm->tm_sec);
594
595 /* We use the guest's setting of the RTC to define the local-time
596 * offset for this domain. */
597 d->time_offset_seconds += (after - before);
598 update_domain_wallclock_time(d);
599 /* Also tell qemu-dm about it so it will be remembered for next boot. */
600 send_timeoffset_req(after - before);
601 }
602
rtc_copy_date(RTCState * s)603 static void rtc_copy_date(RTCState *s)
604 {
605 const struct tm *tm = &s->current_tm;
606
607 ASSERT(spin_is_locked(&s->lock));
608
609 s->hw.cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
610 s->hw.cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min);
611 if ( s->hw.cmos_data[RTC_REG_B] & RTC_24H )
612 {
613 /* 24 hour format */
614 s->hw.cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour);
615 }
616 else
617 {
618 /* 12 hour format */
619 int h = (tm->tm_hour % 12) ? tm->tm_hour % 12 : 12;
620 s->hw.cmos_data[RTC_HOURS] = to_bcd(s, h);
621 if ( tm->tm_hour >= 12 )
622 s->hw.cmos_data[RTC_HOURS] |= 0x80;
623 }
624 s->hw.cmos_data[RTC_DAY_OF_WEEK] = to_bcd(s, tm->tm_wday);
625 s->hw.cmos_data[RTC_DAY_OF_MONTH] = to_bcd(s, tm->tm_mday);
626 s->hw.cmos_data[RTC_MONTH] = to_bcd(s, tm->tm_mon + 1);
627 s->hw.cmos_data[RTC_YEAR] = to_bcd(s, tm->tm_year % 100);
628 }
629
update_in_progress(RTCState * s)630 static int update_in_progress(RTCState *s)
631 {
632 uint64_t guest_usec;
633 struct domain *d = vrtc_domain(s);
634
635 if (s->hw.cmos_data[RTC_REG_B] & RTC_SET)
636 return 0;
637
638 guest_usec = get_localtime_us(d);
639 /* UIP bit will be set at last 244us of every second. */
640 if ((guest_usec % USEC_PER_SEC) >= (USEC_PER_SEC - 244))
641 return 1;
642
643 return 0;
644 }
645
rtc_ioport_read(RTCState * s,uint32_t addr)646 static uint32_t rtc_ioport_read(RTCState *s, uint32_t addr)
647 {
648 int ret;
649 struct domain *d = vrtc_domain(s);
650
651 if ( (addr & 1) == 0 )
652 return 0xff;
653
654 spin_lock(&s->lock);
655
656 switch ( s->hw.cmos_index )
657 {
658 case RTC_SECONDS:
659 case RTC_MINUTES:
660 case RTC_HOURS:
661 case RTC_DAY_OF_WEEK:
662 case RTC_DAY_OF_MONTH:
663 case RTC_MONTH:
664 case RTC_YEAR:
665 /* if not in set mode, adjust cmos before reading*/
666 if (!(s->hw.cmos_data[RTC_REG_B] & RTC_SET))
667 {
668 s->current_tm = gmtime(get_localtime(d));
669 rtc_copy_date(s);
670 }
671 ret = s->hw.cmos_data[s->hw.cmos_index];
672 break;
673 case RTC_REG_A:
674 ret = s->hw.cmos_data[s->hw.cmos_index];
675 if ((s->use_timer == 0) && update_in_progress(s))
676 ret |= RTC_UIP;
677 break;
678 case RTC_REG_C:
679 check_for_pf_ticks(s);
680 ret = s->hw.cmos_data[s->hw.cmos_index];
681 s->hw.cmos_data[RTC_REG_C] = 0x00;
682 if ( ret & RTC_IRQF )
683 hvm_isa_irq_deassert(d, RTC_IRQ);
684 check_update_timer(s);
685 alarm_timer_update(s);
686 s->pt_dead_ticks = 0;
687 break;
688 default:
689 ret = s->hw.cmos_data[s->hw.cmos_index];
690 break;
691 }
692
693 spin_unlock(&s->lock);
694
695 return ret;
696 }
697
handle_rtc_io(int dir,unsigned int port,unsigned int bytes,uint32_t * val)698 static int handle_rtc_io(
699 int dir, unsigned int port, unsigned int bytes, uint32_t *val)
700 {
701 struct RTCState *vrtc = vcpu_vrtc(current);
702
703 if ( bytes != 1 )
704 {
705 gdprintk(XENLOG_WARNING, "HVM_RTC bad access\n");
706 *val = ~0;
707 return X86EMUL_OKAY;
708 }
709
710 if ( dir == IOREQ_WRITE )
711 {
712 if ( rtc_ioport_write(vrtc, port, (uint8_t)*val) )
713 return X86EMUL_OKAY;
714 }
715 else if ( vrtc->hw.cmos_index < RTC_CMOS_SIZE )
716 {
717 *val = rtc_ioport_read(vrtc, port);
718 return X86EMUL_OKAY;
719 }
720
721 return X86EMUL_UNHANDLEABLE;
722 }
723
rtc_migrate_timers(struct vcpu * v)724 void rtc_migrate_timers(struct vcpu *v)
725 {
726 RTCState *s = vcpu_vrtc(v);
727
728 if ( !has_vrtc(v->domain) )
729 return;
730
731 if ( v->vcpu_id == 0 )
732 {
733 migrate_timer(&s->update_timer, v->processor);
734 migrate_timer(&s->update_timer2, v->processor);
735 migrate_timer(&s->alarm_timer, v->processor);
736 }
737 }
738
739 /* Save RTC hardware state */
rtc_save(struct domain * d,hvm_domain_context_t * h)740 static int rtc_save(struct domain *d, hvm_domain_context_t *h)
741 {
742 RTCState *s = domain_vrtc(d);
743 int rc;
744
745 if ( !has_vrtc(d) )
746 return 0;
747
748 spin_lock(&s->lock);
749 rc = hvm_save_entry(RTC, 0, h, &s->hw);
750 spin_unlock(&s->lock);
751 return rc;
752 }
753
754 /* Reload the hardware state from a saved domain */
rtc_load(struct domain * d,hvm_domain_context_t * h)755 static int rtc_load(struct domain *d, hvm_domain_context_t *h)
756 {
757 RTCState *s = domain_vrtc(d);
758
759 if ( !has_vrtc(d) )
760 return -ENODEV;
761
762 spin_lock(&s->lock);
763
764 /* Restore the registers */
765 if ( hvm_load_entry(RTC, h, &s->hw) != 0 )
766 {
767 spin_unlock(&s->lock);
768 return -EINVAL;
769 }
770
771 /* Reset the wall-clock time. In normal running, this runs with host
772 * time, so let's keep doing that. */
773 s->current_tm = gmtime(get_localtime(d));
774 rtc_copy_date(s);
775
776 /* Reset the periodic interrupt timer based on the registers */
777 rtc_timer_update(s);
778 check_update_timer(s);
779 alarm_timer_update(s);
780
781 spin_unlock(&s->lock);
782
783 return 0;
784 }
785
786 HVM_REGISTER_SAVE_RESTORE(RTC, rtc_save, rtc_load, 1, HVMSR_PER_DOM);
787
rtc_reset(struct domain * d)788 void rtc_reset(struct domain *d)
789 {
790 RTCState *s = domain_vrtc(d);
791
792 if ( !has_vrtc(d) )
793 return;
794
795 TRACE_0D(TRC_HVM_EMUL_RTC_STOP_TIMER);
796 destroy_periodic_time(&s->pt);
797 s->period = 0;
798 s->pt.source = PTSRC_isa;
799 }
800
rtc_init(struct domain * d)801 void rtc_init(struct domain *d)
802 {
803 RTCState *s = domain_vrtc(d);
804
805 if ( !has_vrtc(d) )
806 return;
807
808 spin_lock_init(&s->lock);
809
810 init_timer(&s->update_timer, rtc_update_timer, s, smp_processor_id());
811 init_timer(&s->update_timer2, rtc_update_timer2, s, smp_processor_id());
812 init_timer(&s->alarm_timer, rtc_alarm_cb, s, smp_processor_id());
813
814 register_portio_handler(d, RTC_PORT(0), 2, handle_rtc_io);
815
816 rtc_reset(d);
817
818 spin_lock(&s->lock);
819
820 s->hw.cmos_data[RTC_REG_A] = RTC_REF_CLCK_32KHZ | 6; /* ~1kHz */
821 s->hw.cmos_data[RTC_REG_B] = RTC_24H;
822 s->hw.cmos_data[RTC_REG_C] = 0;
823 s->hw.cmos_data[RTC_REG_D] = RTC_VRT;
824
825 s->current_tm = gmtime(get_localtime(d));
826 s->start_time = NOW();
827
828 rtc_copy_date(s);
829
830 check_update_timer(s);
831 spin_unlock(&s->lock);
832 }
833
rtc_deinit(struct domain * d)834 void rtc_deinit(struct domain *d)
835 {
836 RTCState *s = domain_vrtc(d);
837
838 if ( !has_vrtc(d) )
839 return;
840
841 spin_barrier(&s->lock);
842
843 TRACE_0D(TRC_HVM_EMUL_RTC_STOP_TIMER);
844 destroy_periodic_time(&s->pt);
845 kill_timer(&s->update_timer);
846 kill_timer(&s->update_timer2);
847 kill_timer(&s->alarm_timer);
848 }
849
rtc_update_clock(struct domain * d)850 void rtc_update_clock(struct domain *d)
851 {
852 RTCState *s = domain_vrtc(d);
853
854 if ( !has_vrtc(d) )
855 return;
856
857 spin_lock(&s->lock);
858 s->current_tm = gmtime(get_localtime(d));
859 spin_unlock(&s->lock);
860 }
861
862 /*
863 * Local variables:
864 * mode: C
865 * c-file-style: "BSD"
866 * c-basic-offset: 4
867 * indent-tabs-mode: nil
868 * End:
869 */
870