FreeBSD/Linux Kernel Cross Reference
sys/amd64/vmm/io/vrtc.c
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2014, Neel Natu (neel@freebsd.org)
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice unmodified, this list of conditions, and the following
12 * disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include "opt_bhyve_snapshot.h"
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/queue.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/lock.h>
40 #include <sys/mutex.h>
41 #include <sys/clock.h>
42 #include <sys/sysctl.h>
43
44 #include <machine/vmm.h>
45 #include <machine/vmm_snapshot.h>
46
47 #include <isa/rtc.h>
48
49 #include "vmm_ktr.h"
50 #include "vatpic.h"
51 #include "vioapic.h"
52 #include "vrtc.h"
53
54 /* Register layout of the RTC */
55 struct rtcdev {
56 uint8_t sec;
57 uint8_t alarm_sec;
58 uint8_t min;
59 uint8_t alarm_min;
60 uint8_t hour;
61 uint8_t alarm_hour;
62 uint8_t day_of_week;
63 uint8_t day_of_month;
64 uint8_t month;
65 uint8_t year;
66 uint8_t reg_a;
67 uint8_t reg_b;
68 uint8_t reg_c;
69 uint8_t reg_d;
70 uint8_t nvram[36];
71 uint8_t century;
72 uint8_t nvram2[128 - 51];
73 } __packed;
74 CTASSERT(sizeof(struct rtcdev) == 128);
75 CTASSERT(offsetof(struct rtcdev, century) == RTC_CENTURY);
76
77 struct vrtc {
78 struct vm *vm;
79 struct mtx mtx;
80 struct callout callout;
81 u_int addr; /* RTC register to read or write */
82 sbintime_t base_uptime;
83 time_t base_rtctime;
84 struct rtcdev rtcdev;
85 };
86
87 #define VRTC_LOCK(vrtc) mtx_lock(&((vrtc)->mtx))
88 #define VRTC_UNLOCK(vrtc) mtx_unlock(&((vrtc)->mtx))
89 #define VRTC_LOCKED(vrtc) mtx_owned(&((vrtc)->mtx))
90
91 /*
92 * RTC time is considered "broken" if:
93 * - RTC updates are halted by the guest
94 * - RTC date/time fields have invalid values
95 */
96 #define VRTC_BROKEN_TIME ((time_t)-1)
97
98 #define RTC_IRQ 8
99 #define RTCSB_BIN 0x04
100 #define RTCSB_ALL_INTRS (RTCSB_UINTR | RTCSB_AINTR | RTCSB_PINTR)
101 #define rtc_halted(vrtc) ((vrtc->rtcdev.reg_b & RTCSB_HALT) != 0)
102 #define aintr_enabled(vrtc) (((vrtc)->rtcdev.reg_b & RTCSB_AINTR) != 0)
103 #define pintr_enabled(vrtc) (((vrtc)->rtcdev.reg_b & RTCSB_PINTR) != 0)
104 #define uintr_enabled(vrtc) (((vrtc)->rtcdev.reg_b & RTCSB_UINTR) != 0)
105
106 static void vrtc_callout_handler(void *arg);
107 static void vrtc_set_reg_c(struct vrtc *vrtc, uint8_t newval);
108
109 static MALLOC_DEFINE(M_VRTC, "vrtc", "bhyve virtual rtc");
110
111 SYSCTL_DECL(_hw_vmm);
112 SYSCTL_NODE(_hw_vmm, OID_AUTO, vrtc, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL,
113 NULL);
114
115 static int rtc_flag_broken_time = 1;
116 SYSCTL_INT(_hw_vmm_vrtc, OID_AUTO, flag_broken_time, CTLFLAG_RDTUN,
117 &rtc_flag_broken_time, 0, "Stop guest when invalid RTC time is detected");
118
119 static __inline bool
120 divider_enabled(int reg_a)
121 {
122 /*
123 * The RTC is counting only when dividers are not held in reset.
124 */
125 return ((reg_a & 0x70) == 0x20);
126 }
127
128 static __inline bool
129 update_enabled(struct vrtc *vrtc)
130 {
131 /*
132 * RTC date/time can be updated only if:
133 * - divider is not held in reset
134 * - guest has not disabled updates
135 * - the date/time fields have valid contents
136 */
137 if (!divider_enabled(vrtc->rtcdev.reg_a))
138 return (false);
139
140 if (rtc_halted(vrtc))
141 return (false);
142
143 if (vrtc->base_rtctime == VRTC_BROKEN_TIME)
144 return (false);
145
146 return (true);
147 }
148
149 static time_t
150 vrtc_curtime(struct vrtc *vrtc, sbintime_t *basetime)
151 {
152 sbintime_t now, delta;
153 time_t t, secs;
154
155 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
156
157 t = vrtc->base_rtctime;
158 *basetime = vrtc->base_uptime;
159 if (update_enabled(vrtc)) {
160 now = sbinuptime();
161 delta = now - vrtc->base_uptime;
162 KASSERT(delta >= 0, ("vrtc_curtime: uptime went backwards: "
163 "%#lx to %#lx", vrtc->base_uptime, now));
164 secs = delta / SBT_1S;
165 t += secs;
166 *basetime += secs * SBT_1S;
167 }
168 return (t);
169 }
170
171 static __inline uint8_t
172 rtcset(struct rtcdev *rtc, int val)
173 {
174
175 KASSERT(val >= 0 && val < 100, ("%s: invalid bin2bcd index %d",
176 __func__, val));
177
178 return ((rtc->reg_b & RTCSB_BIN) ? val : bin2bcd_data[val]);
179 }
180
181 static void
182 secs_to_rtc(time_t rtctime, struct vrtc *vrtc, int force_update)
183 {
184 struct clocktime ct;
185 struct timespec ts;
186 struct rtcdev *rtc;
187 int hour;
188
189 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
190
191 if (rtctime < 0) {
192 KASSERT(rtctime == VRTC_BROKEN_TIME,
193 ("%s: invalid vrtc time %#lx", __func__, rtctime));
194 return;
195 }
196
197 /*
198 * If the RTC is halted then the guest has "ownership" of the
199 * date/time fields. Don't update the RTC date/time fields in
200 * this case (unless forced).
201 */
202 if (rtc_halted(vrtc) && !force_update)
203 return;
204
205 ts.tv_sec = rtctime;
206 ts.tv_nsec = 0;
207 clock_ts_to_ct(&ts, &ct);
208
209 KASSERT(ct.sec >= 0 && ct.sec <= 59, ("invalid clocktime sec %d",
210 ct.sec));
211 KASSERT(ct.min >= 0 && ct.min <= 59, ("invalid clocktime min %d",
212 ct.min));
213 KASSERT(ct.hour >= 0 && ct.hour <= 23, ("invalid clocktime hour %d",
214 ct.hour));
215 KASSERT(ct.dow >= 0 && ct.dow <= 6, ("invalid clocktime wday %d",
216 ct.dow));
217 KASSERT(ct.day >= 1 && ct.day <= 31, ("invalid clocktime mday %d",
218 ct.day));
219 KASSERT(ct.mon >= 1 && ct.mon <= 12, ("invalid clocktime month %d",
220 ct.mon));
221 KASSERT(ct.year >= POSIX_BASE_YEAR, ("invalid clocktime year %d",
222 ct.year));
223
224 rtc = &vrtc->rtcdev;
225 rtc->sec = rtcset(rtc, ct.sec);
226 rtc->min = rtcset(rtc, ct.min);
227
228 if (rtc->reg_b & RTCSB_24HR) {
229 hour = ct.hour;
230 } else {
231 /*
232 * Convert to the 12-hour format.
233 */
234 switch (ct.hour) {
235 case 0: /* 12 AM */
236 case 12: /* 12 PM */
237 hour = 12;
238 break;
239 default:
240 /*
241 * The remaining 'ct.hour' values are interpreted as:
242 * [1 - 11] -> 1 - 11 AM
243 * [13 - 23] -> 1 - 11 PM
244 */
245 hour = ct.hour % 12;
246 break;
247 }
248 }
249
250 rtc->hour = rtcset(rtc, hour);
251
252 if ((rtc->reg_b & RTCSB_24HR) == 0 && ct.hour >= 12)
253 rtc->hour |= 0x80; /* set MSB to indicate PM */
254
255 rtc->day_of_week = rtcset(rtc, ct.dow + 1);
256 rtc->day_of_month = rtcset(rtc, ct.day);
257 rtc->month = rtcset(rtc, ct.mon);
258 rtc->year = rtcset(rtc, ct.year % 100);
259 rtc->century = rtcset(rtc, ct.year / 100);
260 }
261
262 static int
263 rtcget(struct rtcdev *rtc, int val, int *retval)
264 {
265 uint8_t upper, lower;
266
267 if (rtc->reg_b & RTCSB_BIN) {
268 *retval = val;
269 return (0);
270 }
271
272 lower = val & 0xf;
273 upper = (val >> 4) & 0xf;
274
275 if (lower > 9 || upper > 9)
276 return (-1);
277
278 *retval = upper * 10 + lower;
279 return (0);
280 }
281
282 static time_t
283 rtc_to_secs(struct vrtc *vrtc)
284 {
285 struct clocktime ct;
286 struct timespec ts;
287 struct rtcdev *rtc;
288 #ifdef KTR
289 struct vm *vm = vrtc->vm;
290 #endif
291 int century, error, hour, pm, year;
292
293 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
294
295 rtc = &vrtc->rtcdev;
296
297 bzero(&ct, sizeof(struct clocktime));
298
299 error = rtcget(rtc, rtc->sec, &ct.sec);
300 if (error || ct.sec < 0 || ct.sec > 59) {
301 VM_CTR2(vm, "Invalid RTC sec %#x/%d", rtc->sec, ct.sec);
302 goto fail;
303 }
304
305 error = rtcget(rtc, rtc->min, &ct.min);
306 if (error || ct.min < 0 || ct.min > 59) {
307 VM_CTR2(vm, "Invalid RTC min %#x/%d", rtc->min, ct.min);
308 goto fail;
309 }
310
311 pm = 0;
312 hour = rtc->hour;
313 if ((rtc->reg_b & RTCSB_24HR) == 0) {
314 if (hour & 0x80) {
315 hour &= ~0x80;
316 pm = 1;
317 }
318 }
319 error = rtcget(rtc, hour, &ct.hour);
320 if ((rtc->reg_b & RTCSB_24HR) == 0) {
321 if (ct.hour >= 1 && ct.hour <= 12) {
322 /*
323 * Convert from 12-hour format to internal 24-hour
324 * representation as follows:
325 *
326 * 12-hour format ct.hour
327 * 12 AM 0
328 * 1 - 11 AM 1 - 11
329 * 12 PM 12
330 * 1 - 11 PM 13 - 23
331 */
332 if (ct.hour == 12)
333 ct.hour = 0;
334 if (pm)
335 ct.hour += 12;
336 } else {
337 VM_CTR2(vm, "Invalid RTC 12-hour format %#x/%d",
338 rtc->hour, ct.hour);
339 goto fail;
340 }
341 }
342
343 if (error || ct.hour < 0 || ct.hour > 23) {
344 VM_CTR2(vm, "Invalid RTC hour %#x/%d", rtc->hour, ct.hour);
345 goto fail;
346 }
347
348 /*
349 * Ignore 'rtc->dow' because some guests like Linux don't bother
350 * setting it at all while others like OpenBSD/i386 set it incorrectly.
351 *
352 * clock_ct_to_ts() does not depend on 'ct.dow' anyways so ignore it.
353 */
354 ct.dow = -1;
355
356 error = rtcget(rtc, rtc->day_of_month, &ct.day);
357 if (error || ct.day < 1 || ct.day > 31) {
358 VM_CTR2(vm, "Invalid RTC mday %#x/%d", rtc->day_of_month,
359 ct.day);
360 goto fail;
361 }
362
363 error = rtcget(rtc, rtc->month, &ct.mon);
364 if (error || ct.mon < 1 || ct.mon > 12) {
365 VM_CTR2(vm, "Invalid RTC month %#x/%d", rtc->month, ct.mon);
366 goto fail;
367 }
368
369 error = rtcget(rtc, rtc->year, &year);
370 if (error || year < 0 || year > 99) {
371 VM_CTR2(vm, "Invalid RTC year %#x/%d", rtc->year, year);
372 goto fail;
373 }
374
375 error = rtcget(rtc, rtc->century, ¢ury);
376 ct.year = century * 100 + year;
377 if (error || ct.year < POSIX_BASE_YEAR) {
378 VM_CTR2(vm, "Invalid RTC century %#x/%d", rtc->century,
379 ct.year);
380 goto fail;
381 }
382
383 error = clock_ct_to_ts(&ct, &ts);
384 if (error || ts.tv_sec < 0) {
385 VM_CTR3(vm, "Invalid RTC clocktime.date %04d-%02d-%02d",
386 ct.year, ct.mon, ct.day);
387 VM_CTR3(vm, "Invalid RTC clocktime.time %02d:%02d:%02d",
388 ct.hour, ct.min, ct.sec);
389 goto fail;
390 }
391 return (ts.tv_sec); /* success */
392 fail:
393 /*
394 * Stop updating the RTC if the date/time fields programmed by
395 * the guest are invalid.
396 */
397 VM_CTR0(vrtc->vm, "Invalid RTC date/time programming detected");
398 return (VRTC_BROKEN_TIME);
399 }
400
401 static int
402 vrtc_time_update(struct vrtc *vrtc, time_t newtime, sbintime_t newbase)
403 {
404 struct rtcdev *rtc;
405 time_t oldtime;
406 uint8_t alarm_sec, alarm_min, alarm_hour;
407
408 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
409
410 rtc = &vrtc->rtcdev;
411 alarm_sec = rtc->alarm_sec;
412 alarm_min = rtc->alarm_min;
413 alarm_hour = rtc->alarm_hour;
414
415 oldtime = vrtc->base_rtctime;
416 VM_CTR2(vrtc->vm, "Updating RTC secs from %#lx to %#lx",
417 oldtime, newtime);
418
419 VM_CTR2(vrtc->vm, "Updating RTC base uptime from %#lx to %#lx",
420 vrtc->base_uptime, newbase);
421 vrtc->base_uptime = newbase;
422
423 if (newtime == oldtime)
424 return (0);
425
426 /*
427 * If 'newtime' indicates that RTC updates are disabled then just
428 * record that and return. There is no need to do alarm interrupt
429 * processing in this case.
430 */
431 if (newtime == VRTC_BROKEN_TIME) {
432 vrtc->base_rtctime = VRTC_BROKEN_TIME;
433 return (0);
434 }
435
436 /*
437 * Return an error if RTC updates are halted by the guest.
438 */
439 if (rtc_halted(vrtc)) {
440 VM_CTR0(vrtc->vm, "RTC update halted by guest");
441 return (EBUSY);
442 }
443
444 do {
445 /*
446 * If the alarm interrupt is enabled and 'oldtime' is valid
447 * then visit all the seconds between 'oldtime' and 'newtime'
448 * to check for the alarm condition.
449 *
450 * Otherwise move the RTC time forward directly to 'newtime'.
451 */
452 if (aintr_enabled(vrtc) && oldtime != VRTC_BROKEN_TIME)
453 vrtc->base_rtctime++;
454 else
455 vrtc->base_rtctime = newtime;
456
457 if (aintr_enabled(vrtc)) {
458 /*
459 * Update the RTC date/time fields before checking
460 * if the alarm conditions are satisfied.
461 */
462 secs_to_rtc(vrtc->base_rtctime, vrtc, 0);
463
464 if ((alarm_sec >= 0xC0 || alarm_sec == rtc->sec) &&
465 (alarm_min >= 0xC0 || alarm_min == rtc->min) &&
466 (alarm_hour >= 0xC0 || alarm_hour == rtc->hour)) {
467 vrtc_set_reg_c(vrtc, rtc->reg_c | RTCIR_ALARM);
468 }
469 }
470 } while (vrtc->base_rtctime != newtime);
471
472 if (uintr_enabled(vrtc))
473 vrtc_set_reg_c(vrtc, rtc->reg_c | RTCIR_UPDATE);
474
475 return (0);
476 }
477
478 static sbintime_t
479 vrtc_freq(struct vrtc *vrtc)
480 {
481 int ratesel;
482
483 static sbintime_t pf[16] = {
484 0,
485 SBT_1S / 256,
486 SBT_1S / 128,
487 SBT_1S / 8192,
488 SBT_1S / 4096,
489 SBT_1S / 2048,
490 SBT_1S / 1024,
491 SBT_1S / 512,
492 SBT_1S / 256,
493 SBT_1S / 128,
494 SBT_1S / 64,
495 SBT_1S / 32,
496 SBT_1S / 16,
497 SBT_1S / 8,
498 SBT_1S / 4,
499 SBT_1S / 2,
500 };
501
502 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
503
504 /*
505 * If both periodic and alarm interrupts are enabled then use the
506 * periodic frequency to drive the callout. The minimum periodic
507 * frequency (2 Hz) is higher than the alarm frequency (1 Hz) so
508 * piggyback the alarm on top of it. The same argument applies to
509 * the update interrupt.
510 */
511 if (pintr_enabled(vrtc) && divider_enabled(vrtc->rtcdev.reg_a)) {
512 ratesel = vrtc->rtcdev.reg_a & 0xf;
513 return (pf[ratesel]);
514 } else if (aintr_enabled(vrtc) && update_enabled(vrtc)) {
515 return (SBT_1S);
516 } else if (uintr_enabled(vrtc) && update_enabled(vrtc)) {
517 return (SBT_1S);
518 } else {
519 return (0);
520 }
521 }
522
523 static void
524 vrtc_callout_reset(struct vrtc *vrtc, sbintime_t freqsbt)
525 {
526
527 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
528
529 if (freqsbt == 0) {
530 if (callout_active(&vrtc->callout)) {
531 VM_CTR0(vrtc->vm, "RTC callout stopped");
532 callout_stop(&vrtc->callout);
533 }
534 return;
535 }
536 VM_CTR1(vrtc->vm, "RTC callout frequency %d hz", SBT_1S / freqsbt);
537 callout_reset_sbt(&vrtc->callout, freqsbt, 0, vrtc_callout_handler,
538 vrtc, 0);
539 }
540
541 static void
542 vrtc_callout_handler(void *arg)
543 {
544 struct vrtc *vrtc = arg;
545 sbintime_t freqsbt, basetime;
546 time_t rtctime;
547 int error __diagused;
548
549 VM_CTR0(vrtc->vm, "vrtc callout fired");
550
551 VRTC_LOCK(vrtc);
552 if (callout_pending(&vrtc->callout)) /* callout was reset */
553 goto done;
554
555 if (!callout_active(&vrtc->callout)) /* callout was stopped */
556 goto done;
557
558 callout_deactivate(&vrtc->callout);
559
560 KASSERT((vrtc->rtcdev.reg_b & RTCSB_ALL_INTRS) != 0,
561 ("gratuitous vrtc callout"));
562
563 if (pintr_enabled(vrtc))
564 vrtc_set_reg_c(vrtc, vrtc->rtcdev.reg_c | RTCIR_PERIOD);
565
566 if (aintr_enabled(vrtc) || uintr_enabled(vrtc)) {
567 rtctime = vrtc_curtime(vrtc, &basetime);
568 error = vrtc_time_update(vrtc, rtctime, basetime);
569 KASSERT(error == 0, ("%s: vrtc_time_update error %d",
570 __func__, error));
571 }
572
573 freqsbt = vrtc_freq(vrtc);
574 KASSERT(freqsbt != 0, ("%s: vrtc frequency cannot be zero", __func__));
575 vrtc_callout_reset(vrtc, freqsbt);
576 done:
577 VRTC_UNLOCK(vrtc);
578 }
579
580 static __inline void
581 vrtc_callout_check(struct vrtc *vrtc, sbintime_t freq)
582 {
583 int active __diagused;
584
585 active = callout_active(&vrtc->callout) ? 1 : 0;
586 KASSERT((freq == 0 && !active) || (freq != 0 && active),
587 ("vrtc callout %s with frequency %#lx",
588 active ? "active" : "inactive", freq));
589 }
590
591 static void
592 vrtc_set_reg_c(struct vrtc *vrtc, uint8_t newval)
593 {
594 struct rtcdev *rtc;
595 int oldirqf, newirqf;
596 uint8_t oldval, changed;
597
598 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
599
600 rtc = &vrtc->rtcdev;
601 newval &= RTCIR_ALARM | RTCIR_PERIOD | RTCIR_UPDATE;
602
603 oldirqf = rtc->reg_c & RTCIR_INT;
604 if ((aintr_enabled(vrtc) && (newval & RTCIR_ALARM) != 0) ||
605 (pintr_enabled(vrtc) && (newval & RTCIR_PERIOD) != 0) ||
606 (uintr_enabled(vrtc) && (newval & RTCIR_UPDATE) != 0)) {
607 newirqf = RTCIR_INT;
608 } else {
609 newirqf = 0;
610 }
611
612 oldval = rtc->reg_c;
613 rtc->reg_c = newirqf | newval;
614 changed = oldval ^ rtc->reg_c;
615 if (changed) {
616 VM_CTR2(vrtc->vm, "RTC reg_c changed from %#x to %#x",
617 oldval, rtc->reg_c);
618 }
619
620 if (!oldirqf && newirqf) {
621 VM_CTR1(vrtc->vm, "RTC irq %d asserted", RTC_IRQ);
622 vatpic_pulse_irq(vrtc->vm, RTC_IRQ);
623 vioapic_pulse_irq(vrtc->vm, RTC_IRQ);
624 } else if (oldirqf && !newirqf) {
625 VM_CTR1(vrtc->vm, "RTC irq %d deasserted", RTC_IRQ);
626 }
627 }
628
629 static int
630 vrtc_set_reg_b(struct vrtc *vrtc, uint8_t newval)
631 {
632 struct rtcdev *rtc;
633 sbintime_t oldfreq, newfreq, basetime;
634 time_t curtime, rtctime;
635 int error __diagused;
636 uint8_t oldval, changed;
637
638 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
639
640 rtc = &vrtc->rtcdev;
641 oldval = rtc->reg_b;
642 oldfreq = vrtc_freq(vrtc);
643
644 rtc->reg_b = newval;
645 changed = oldval ^ newval;
646 if (changed) {
647 VM_CTR2(vrtc->vm, "RTC reg_b changed from %#x to %#x",
648 oldval, newval);
649 }
650
651 if (changed & RTCSB_HALT) {
652 if ((newval & RTCSB_HALT) == 0) {
653 rtctime = rtc_to_secs(vrtc);
654 basetime = sbinuptime();
655 if (rtctime == VRTC_BROKEN_TIME) {
656 if (rtc_flag_broken_time)
657 return (-1);
658 }
659 } else {
660 curtime = vrtc_curtime(vrtc, &basetime);
661 KASSERT(curtime == vrtc->base_rtctime, ("%s: mismatch "
662 "between vrtc basetime (%#lx) and curtime (%#lx)",
663 __func__, vrtc->base_rtctime, curtime));
664
665 /*
666 * Force a refresh of the RTC date/time fields so
667 * they reflect the time right before the guest set
668 * the HALT bit.
669 */
670 secs_to_rtc(curtime, vrtc, 1);
671
672 /*
673 * Updates are halted so mark 'base_rtctime' to denote
674 * that the RTC date/time is in flux.
675 */
676 rtctime = VRTC_BROKEN_TIME;
677 rtc->reg_b &= ~RTCSB_UINTR;
678 }
679 error = vrtc_time_update(vrtc, rtctime, basetime);
680 KASSERT(error == 0, ("vrtc_time_update error %d", error));
681 }
682
683 /*
684 * Side effect of changes to the interrupt enable bits.
685 */
686 if (changed & RTCSB_ALL_INTRS)
687 vrtc_set_reg_c(vrtc, vrtc->rtcdev.reg_c);
688
689 /*
690 * Change the callout frequency if it has changed.
691 */
692 newfreq = vrtc_freq(vrtc);
693 if (newfreq != oldfreq)
694 vrtc_callout_reset(vrtc, newfreq);
695 else
696 vrtc_callout_check(vrtc, newfreq);
697
698 /*
699 * The side effect of bits that control the RTC date/time format
700 * is handled lazily when those fields are actually read.
701 */
702 return (0);
703 }
704
705 static void
706 vrtc_set_reg_a(struct vrtc *vrtc, uint8_t newval)
707 {
708 sbintime_t oldfreq, newfreq;
709 uint8_t oldval, changed;
710
711 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
712
713 newval &= ~RTCSA_TUP;
714 oldval = vrtc->rtcdev.reg_a;
715 oldfreq = vrtc_freq(vrtc);
716
717 if (divider_enabled(oldval) && !divider_enabled(newval)) {
718 VM_CTR2(vrtc->vm, "RTC divider held in reset at %#lx/%#lx",
719 vrtc->base_rtctime, vrtc->base_uptime);
720 } else if (!divider_enabled(oldval) && divider_enabled(newval)) {
721 /*
722 * If the dividers are coming out of reset then update
723 * 'base_uptime' before this happens. This is done to
724 * maintain the illusion that the RTC date/time was frozen
725 * while the dividers were disabled.
726 */
727 vrtc->base_uptime = sbinuptime();
728 VM_CTR2(vrtc->vm, "RTC divider out of reset at %#lx/%#lx",
729 vrtc->base_rtctime, vrtc->base_uptime);
730 } else {
731 /* NOTHING */
732 }
733
734 vrtc->rtcdev.reg_a = newval;
735 changed = oldval ^ newval;
736 if (changed) {
737 VM_CTR2(vrtc->vm, "RTC reg_a changed from %#x to %#x",
738 oldval, newval);
739 }
740
741 /*
742 * Side effect of changes to rate select and divider enable bits.
743 */
744 newfreq = vrtc_freq(vrtc);
745 if (newfreq != oldfreq)
746 vrtc_callout_reset(vrtc, newfreq);
747 else
748 vrtc_callout_check(vrtc, newfreq);
749 }
750
751 int
752 vrtc_set_time(struct vm *vm, time_t secs)
753 {
754 struct vrtc *vrtc;
755 int error;
756
757 vrtc = vm_rtc(vm);
758 VRTC_LOCK(vrtc);
759 error = vrtc_time_update(vrtc, secs, sbinuptime());
760 VRTC_UNLOCK(vrtc);
761
762 if (error) {
763 VM_CTR2(vrtc->vm, "Error %d setting RTC time to %#lx", error,
764 secs);
765 } else {
766 VM_CTR1(vrtc->vm, "RTC time set to %#lx", secs);
767 }
768
769 return (error);
770 }
771
772 time_t
773 vrtc_get_time(struct vm *vm)
774 {
775 struct vrtc *vrtc;
776 sbintime_t basetime;
777 time_t t;
778
779 vrtc = vm_rtc(vm);
780 VRTC_LOCK(vrtc);
781 t = vrtc_curtime(vrtc, &basetime);
782 VRTC_UNLOCK(vrtc);
783
784 return (t);
785 }
786
787 int
788 vrtc_nvram_write(struct vm *vm, int offset, uint8_t value)
789 {
790 struct vrtc *vrtc;
791 uint8_t *ptr;
792
793 vrtc = vm_rtc(vm);
794
795 /*
796 * Don't allow writes to RTC control registers or the date/time fields.
797 */
798 if (offset < offsetof(struct rtcdev, nvram[0]) ||
799 offset == RTC_CENTURY || offset >= sizeof(struct rtcdev)) {
800 VM_CTR1(vrtc->vm, "RTC nvram write to invalid offset %d",
801 offset);
802 return (EINVAL);
803 }
804
805 VRTC_LOCK(vrtc);
806 ptr = (uint8_t *)(&vrtc->rtcdev);
807 ptr[offset] = value;
808 VM_CTR2(vrtc->vm, "RTC nvram write %#x to offset %#x", value, offset);
809 VRTC_UNLOCK(vrtc);
810
811 return (0);
812 }
813
814 int
815 vrtc_nvram_read(struct vm *vm, int offset, uint8_t *retval)
816 {
817 struct vrtc *vrtc;
818 sbintime_t basetime;
819 time_t curtime;
820 uint8_t *ptr;
821
822 /*
823 * Allow all offsets in the RTC to be read.
824 */
825 if (offset < 0 || offset >= sizeof(struct rtcdev))
826 return (EINVAL);
827
828 vrtc = vm_rtc(vm);
829 VRTC_LOCK(vrtc);
830
831 /*
832 * Update RTC date/time fields if necessary.
833 */
834 if (offset < 10 || offset == RTC_CENTURY) {
835 curtime = vrtc_curtime(vrtc, &basetime);
836 secs_to_rtc(curtime, vrtc, 0);
837 }
838
839 ptr = (uint8_t *)(&vrtc->rtcdev);
840 *retval = ptr[offset];
841
842 VRTC_UNLOCK(vrtc);
843 return (0);
844 }
845
846 int
847 vrtc_addr_handler(struct vm *vm, bool in, int port, int bytes, uint32_t *val)
848 {
849 struct vrtc *vrtc;
850
851 vrtc = vm_rtc(vm);
852
853 if (bytes != 1)
854 return (-1);
855
856 if (in) {
857 *val = 0xff;
858 return (0);
859 }
860
861 VRTC_LOCK(vrtc);
862 vrtc->addr = *val & 0x7f;
863 VRTC_UNLOCK(vrtc);
864
865 return (0);
866 }
867
868 int
869 vrtc_data_handler(struct vm *vm, bool in, int port, int bytes, uint32_t *val)
870 {
871 struct vrtc *vrtc;
872 struct rtcdev *rtc;
873 sbintime_t basetime;
874 time_t curtime;
875 int error, offset;
876
877 vrtc = vm_rtc(vm);
878 rtc = &vrtc->rtcdev;
879
880 if (bytes != 1)
881 return (-1);
882
883 VRTC_LOCK(vrtc);
884 offset = vrtc->addr;
885 if (offset >= sizeof(struct rtcdev)) {
886 VRTC_UNLOCK(vrtc);
887 return (-1);
888 }
889
890 error = 0;
891 curtime = vrtc_curtime(vrtc, &basetime);
892 vrtc_time_update(vrtc, curtime, basetime);
893
894 /*
895 * Update RTC date/time fields if necessary.
896 *
897 * This is not just for reads of the RTC. The side-effect of writing
898 * the century byte requires other RTC date/time fields (e.g. sec)
899 * to be updated here.
900 */
901 if (offset < 10 || offset == RTC_CENTURY)
902 secs_to_rtc(curtime, vrtc, 0);
903
904 if (in) {
905 if (offset == 12) {
906 /*
907 * XXX
908 * reg_c interrupt flags are updated only if the
909 * corresponding interrupt enable bit in reg_b is set.
910 */
911 *val = vrtc->rtcdev.reg_c;
912 vrtc_set_reg_c(vrtc, 0);
913 } else {
914 *val = *((uint8_t *)rtc + offset);
915 }
916 VM_CTR2(vm, "Read value %#x from RTC offset %#x",
917 *val, offset);
918 } else {
919 switch (offset) {
920 case 10:
921 VM_CTR1(vm, "RTC reg_a set to %#x", *val);
922 vrtc_set_reg_a(vrtc, *val);
923 break;
924 case 11:
925 VM_CTR1(vm, "RTC reg_b set to %#x", *val);
926 error = vrtc_set_reg_b(vrtc, *val);
927 break;
928 case 12:
929 VM_CTR1(vm, "RTC reg_c set to %#x (ignored)",
930 *val);
931 break;
932 case 13:
933 VM_CTR1(vm, "RTC reg_d set to %#x (ignored)",
934 *val);
935 break;
936 case 0:
937 /*
938 * High order bit of 'seconds' is readonly.
939 */
940 *val &= 0x7f;
941 /* FALLTHRU */
942 default:
943 VM_CTR2(vm, "RTC offset %#x set to %#x",
944 offset, *val);
945 *((uint8_t *)rtc + offset) = *val;
946 break;
947 }
948
949 /*
950 * XXX some guests (e.g. OpenBSD) write the century byte
951 * outside of RTCSB_HALT so re-calculate the RTC date/time.
952 */
953 if (offset == RTC_CENTURY && !rtc_halted(vrtc)) {
954 curtime = rtc_to_secs(vrtc);
955 error = vrtc_time_update(vrtc, curtime, sbinuptime());
956 KASSERT(!error, ("vrtc_time_update error %d", error));
957 if (curtime == VRTC_BROKEN_TIME && rtc_flag_broken_time)
958 error = -1;
959 }
960 }
961 VRTC_UNLOCK(vrtc);
962 return (error);
963 }
964
965 void
966 vrtc_reset(struct vrtc *vrtc)
967 {
968 struct rtcdev *rtc;
969
970 VRTC_LOCK(vrtc);
971
972 rtc = &vrtc->rtcdev;
973 vrtc_set_reg_b(vrtc, rtc->reg_b & ~(RTCSB_ALL_INTRS | RTCSB_SQWE));
974 vrtc_set_reg_c(vrtc, 0);
975 KASSERT(!callout_active(&vrtc->callout), ("rtc callout still active"));
976
977 VRTC_UNLOCK(vrtc);
978 }
979
980 struct vrtc *
981 vrtc_init(struct vm *vm)
982 {
983 struct vrtc *vrtc;
984 struct rtcdev *rtc;
985 time_t curtime;
986
987 vrtc = malloc(sizeof(struct vrtc), M_VRTC, M_WAITOK | M_ZERO);
988 vrtc->vm = vm;
989 mtx_init(&vrtc->mtx, "vrtc lock", NULL, MTX_DEF);
990 callout_init(&vrtc->callout, 1);
991
992 /* Allow dividers to keep time but disable everything else */
993 rtc = &vrtc->rtcdev;
994 rtc->reg_a = 0x20;
995 rtc->reg_b = RTCSB_24HR;
996 rtc->reg_c = 0;
997 rtc->reg_d = RTCSD_PWR;
998
999 /* Reset the index register to a safe value. */
1000 vrtc->addr = RTC_STATUSD;
1001
1002 /*
1003 * Initialize RTC time to 00:00:00 Jan 1, 1970.
1004 */
1005 curtime = 0;
1006
1007 VRTC_LOCK(vrtc);
1008 vrtc->base_rtctime = VRTC_BROKEN_TIME;
1009 vrtc_time_update(vrtc, curtime, sbinuptime());
1010 secs_to_rtc(curtime, vrtc, 0);
1011 VRTC_UNLOCK(vrtc);
1012
1013 return (vrtc);
1014 }
1015
1016 void
1017 vrtc_cleanup(struct vrtc *vrtc)
1018 {
1019
1020 callout_drain(&vrtc->callout);
1021 mtx_destroy(&vrtc->mtx);
1022 free(vrtc, M_VRTC);
1023 }
1024
1025 #ifdef BHYVE_SNAPSHOT
1026 int
1027 vrtc_snapshot(struct vrtc *vrtc, struct vm_snapshot_meta *meta)
1028 {
1029 int ret;
1030
1031 VRTC_LOCK(vrtc);
1032
1033 SNAPSHOT_VAR_OR_LEAVE(vrtc->addr, meta, ret, done);
1034 if (meta->op == VM_SNAPSHOT_RESTORE)
1035 vrtc->base_uptime = sbinuptime();
1036 SNAPSHOT_VAR_OR_LEAVE(vrtc->base_rtctime, meta, ret, done);
1037
1038 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.sec, meta, ret, done);
1039 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.alarm_sec, meta, ret, done);
1040 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.min, meta, ret, done);
1041 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.alarm_min, meta, ret, done);
1042 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.hour, meta, ret, done);
1043 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.alarm_hour, meta, ret, done);
1044 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.day_of_week, meta, ret, done);
1045 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.day_of_month, meta, ret, done);
1046 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.month, meta, ret, done);
1047 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.year, meta, ret, done);
1048 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.reg_a, meta, ret, done);
1049 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.reg_b, meta, ret, done);
1050 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.reg_c, meta, ret, done);
1051 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.reg_d, meta, ret, done);
1052 SNAPSHOT_BUF_OR_LEAVE(vrtc->rtcdev.nvram, sizeof(vrtc->rtcdev.nvram),
1053 meta, ret, done);
1054 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.century, meta, ret, done);
1055 SNAPSHOT_BUF_OR_LEAVE(vrtc->rtcdev.nvram2, sizeof(vrtc->rtcdev.nvram2),
1056 meta, ret, done);
1057
1058 vrtc_callout_reset(vrtc, vrtc_freq(vrtc));
1059
1060 VRTC_UNLOCK(vrtc);
1061
1062 done:
1063 return (ret);
1064 }
1065 #endif
Cache object: f5ed43e9f80368f734a261112931010f
|