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