2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2014, Neel Natu (neel@freebsd.org)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice unmodified, this list of conditions, and the following
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.
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.
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include "opt_bhyve_snapshot.h"
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>
40 #include <sys/mutex.h>
41 #include <sys/clock.h>
42 #include <sys/sysctl.h>
44 #include <machine/vmm.h>
45 #include <machine/vmm_snapshot.h>
54 /* Register layout of the RTC */
72 uint8_t nvram2[128 - 51];
74 CTASSERT(sizeof(struct rtcdev) == 128);
75 CTASSERT(offsetof(struct rtcdev, century) == RTC_CENTURY);
80 struct callout callout;
81 u_int addr; /* RTC register to read or write */
82 sbintime_t base_uptime;
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))
92 * RTC time is considered "broken" if:
93 * - RTC updates are halted by the guest
94 * - RTC date/time fields have invalid values
96 #define VRTC_BROKEN_TIME ((time_t)-1)
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)
106 static void vrtc_callout_handler(void *arg);
107 static void vrtc_set_reg_c(struct vrtc *vrtc, uint8_t newval);
109 static MALLOC_DEFINE(M_VRTC, "vrtc", "bhyve virtual rtc");
111 SYSCTL_DECL(_hw_vmm);
112 SYSCTL_NODE(_hw_vmm, OID_AUTO, vrtc, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL,
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");
120 divider_enabled(int reg_a)
123 * The RTC is counting only when dividers are not held in reset.
125 return ((reg_a & 0x70) == 0x20);
129 update_enabled(struct vrtc *vrtc)
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
137 if (!divider_enabled(vrtc->rtcdev.reg_a))
140 if (rtc_halted(vrtc))
143 if (vrtc->base_rtctime == VRTC_BROKEN_TIME)
150 vrtc_curtime(struct vrtc *vrtc, sbintime_t *basetime)
152 sbintime_t now, delta;
155 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
157 t = vrtc->base_rtctime;
158 *basetime = vrtc->base_uptime;
159 if (update_enabled(vrtc)) {
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;
166 *basetime += secs * SBT_1S;
171 static __inline uint8_t
172 rtcset(struct rtcdev *rtc, int val)
175 KASSERT(val >= 0 && val < 100, ("%s: invalid bin2bcd index %d",
178 return ((rtc->reg_b & RTCSB_BIN) ? val : bin2bcd_data[val]);
182 secs_to_rtc(time_t rtctime, struct vrtc *vrtc, int force_update)
189 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
192 KASSERT(rtctime == VRTC_BROKEN_TIME,
193 ("%s: invalid vrtc time %#lx", __func__, rtctime));
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).
202 if (rtc_halted(vrtc) && !force_update)
207 clock_ts_to_ct(&ts, &ct);
209 KASSERT(ct.sec >= 0 && ct.sec <= 59, ("invalid clocktime sec %d",
211 KASSERT(ct.min >= 0 && ct.min <= 59, ("invalid clocktime min %d",
213 KASSERT(ct.hour >= 0 && ct.hour <= 23, ("invalid clocktime hour %d",
215 KASSERT(ct.dow >= 0 && ct.dow <= 6, ("invalid clocktime wday %d",
217 KASSERT(ct.day >= 1 && ct.day <= 31, ("invalid clocktime mday %d",
219 KASSERT(ct.mon >= 1 && ct.mon <= 12, ("invalid clocktime month %d",
221 KASSERT(ct.year >= POSIX_BASE_YEAR, ("invalid clocktime year %d",
225 rtc->sec = rtcset(rtc, ct.sec);
226 rtc->min = rtcset(rtc, ct.min);
228 if (rtc->reg_b & RTCSB_24HR) {
232 * Convert to the 12-hour format.
241 * The remaining 'ct.hour' values are interpreted as:
242 * [1 - 11] -> 1 - 11 AM
243 * [13 - 23] -> 1 - 11 PM
250 rtc->hour = rtcset(rtc, hour);
252 if ((rtc->reg_b & RTCSB_24HR) == 0 && ct.hour >= 12)
253 rtc->hour |= 0x80; /* set MSB to indicate PM */
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);
263 rtcget(struct rtcdev *rtc, int val, int *retval)
265 uint8_t upper, lower;
267 if (rtc->reg_b & RTCSB_BIN) {
273 upper = (val >> 4) & 0xf;
275 if (lower > 9 || upper > 9)
278 *retval = upper * 10 + lower;
283 rtc_to_secs(struct vrtc *vrtc)
289 int century, error, hour, pm, year;
291 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
296 bzero(&ct, sizeof(struct clocktime));
298 error = rtcget(rtc, rtc->sec, &ct.sec);
299 if (error || ct.sec < 0 || ct.sec > 59) {
300 VM_CTR2(vm, "Invalid RTC sec %#x/%d", rtc->sec, ct.sec);
304 error = rtcget(rtc, rtc->min, &ct.min);
305 if (error || ct.min < 0 || ct.min > 59) {
306 VM_CTR2(vm, "Invalid RTC min %#x/%d", rtc->min, ct.min);
312 if ((rtc->reg_b & RTCSB_24HR) == 0) {
318 error = rtcget(rtc, hour, &ct.hour);
319 if ((rtc->reg_b & RTCSB_24HR) == 0) {
320 if (ct.hour >= 1 && ct.hour <= 12) {
322 * Convert from 12-hour format to internal 24-hour
323 * representation as follows:
325 * 12-hour format ct.hour
336 VM_CTR2(vm, "Invalid RTC 12-hour format %#x/%d",
342 if (error || ct.hour < 0 || ct.hour > 23) {
343 VM_CTR2(vm, "Invalid RTC hour %#x/%d", rtc->hour, ct.hour);
348 * Ignore 'rtc->dow' because some guests like Linux don't bother
349 * setting it at all while others like OpenBSD/i386 set it incorrectly.
351 * clock_ct_to_ts() does not depend on 'ct.dow' anyways so ignore it.
355 error = rtcget(rtc, rtc->day_of_month, &ct.day);
356 if (error || ct.day < 1 || ct.day > 31) {
357 VM_CTR2(vm, "Invalid RTC mday %#x/%d", rtc->day_of_month,
362 error = rtcget(rtc, rtc->month, &ct.mon);
363 if (error || ct.mon < 1 || ct.mon > 12) {
364 VM_CTR2(vm, "Invalid RTC month %#x/%d", rtc->month, ct.mon);
368 error = rtcget(rtc, rtc->year, &year);
369 if (error || year < 0 || year > 99) {
370 VM_CTR2(vm, "Invalid RTC year %#x/%d", rtc->year, year);
374 error = rtcget(rtc, rtc->century, ¢ury);
375 ct.year = century * 100 + year;
376 if (error || ct.year < POSIX_BASE_YEAR) {
377 VM_CTR2(vm, "Invalid RTC century %#x/%d", rtc->century,
382 error = clock_ct_to_ts(&ct, &ts);
383 if (error || ts.tv_sec < 0) {
384 VM_CTR3(vm, "Invalid RTC clocktime.date %04d-%02d-%02d",
385 ct.year, ct.mon, ct.day);
386 VM_CTR3(vm, "Invalid RTC clocktime.time %02d:%02d:%02d",
387 ct.hour, ct.min, ct.sec);
390 return (ts.tv_sec); /* success */
393 * Stop updating the RTC if the date/time fields programmed by
394 * the guest are invalid.
396 VM_CTR0(vrtc->vm, "Invalid RTC date/time programming detected");
397 return (VRTC_BROKEN_TIME);
401 vrtc_time_update(struct vrtc *vrtc, time_t newtime, sbintime_t newbase)
406 uint8_t alarm_sec, alarm_min, alarm_hour;
408 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
411 alarm_sec = rtc->alarm_sec;
412 alarm_min = rtc->alarm_min;
413 alarm_hour = rtc->alarm_hour;
415 oldtime = vrtc->base_rtctime;
416 VM_CTR2(vrtc->vm, "Updating RTC secs from %#lx to %#lx",
419 oldbase = vrtc->base_uptime;
420 VM_CTR2(vrtc->vm, "Updating RTC base uptime from %#lx to %#lx",
422 vrtc->base_uptime = newbase;
424 if (newtime == oldtime)
428 * If 'newtime' indicates that RTC updates are disabled then just
429 * record that and return. There is no need to do alarm interrupt
430 * processing in this case.
432 if (newtime == VRTC_BROKEN_TIME) {
433 vrtc->base_rtctime = VRTC_BROKEN_TIME;
438 * Return an error if RTC updates are halted by the guest.
440 if (rtc_halted(vrtc)) {
441 VM_CTR0(vrtc->vm, "RTC update halted by guest");
447 * If the alarm interrupt is enabled and 'oldtime' is valid
448 * then visit all the seconds between 'oldtime' and 'newtime'
449 * to check for the alarm condition.
451 * Otherwise move the RTC time forward directly to 'newtime'.
453 if (aintr_enabled(vrtc) && oldtime != VRTC_BROKEN_TIME)
454 vrtc->base_rtctime++;
456 vrtc->base_rtctime = newtime;
458 if (aintr_enabled(vrtc)) {
460 * Update the RTC date/time fields before checking
461 * if the alarm conditions are satisfied.
463 secs_to_rtc(vrtc->base_rtctime, vrtc, 0);
465 if ((alarm_sec >= 0xC0 || alarm_sec == rtc->sec) &&
466 (alarm_min >= 0xC0 || alarm_min == rtc->min) &&
467 (alarm_hour >= 0xC0 || alarm_hour == rtc->hour)) {
468 vrtc_set_reg_c(vrtc, rtc->reg_c | RTCIR_ALARM);
471 } while (vrtc->base_rtctime != newtime);
473 if (uintr_enabled(vrtc))
474 vrtc_set_reg_c(vrtc, rtc->reg_c | RTCIR_UPDATE);
480 vrtc_freq(struct vrtc *vrtc)
484 static sbintime_t pf[16] = {
503 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
506 * If both periodic and alarm interrupts are enabled then use the
507 * periodic frequency to drive the callout. The minimum periodic
508 * frequency (2 Hz) is higher than the alarm frequency (1 Hz) so
509 * piggyback the alarm on top of it. The same argument applies to
510 * the update interrupt.
512 if (pintr_enabled(vrtc) && divider_enabled(vrtc->rtcdev.reg_a)) {
513 ratesel = vrtc->rtcdev.reg_a & 0xf;
514 return (pf[ratesel]);
515 } else if (aintr_enabled(vrtc) && update_enabled(vrtc)) {
517 } else if (uintr_enabled(vrtc) && update_enabled(vrtc)) {
525 vrtc_callout_reset(struct vrtc *vrtc, sbintime_t freqsbt)
528 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
531 if (callout_active(&vrtc->callout)) {
532 VM_CTR0(vrtc->vm, "RTC callout stopped");
533 callout_stop(&vrtc->callout);
537 VM_CTR1(vrtc->vm, "RTC callout frequency %d hz", SBT_1S / freqsbt);
538 callout_reset_sbt(&vrtc->callout, freqsbt, 0, vrtc_callout_handler,
543 vrtc_callout_handler(void *arg)
545 struct vrtc *vrtc = arg;
546 sbintime_t freqsbt, basetime;
550 VM_CTR0(vrtc->vm, "vrtc callout fired");
553 if (callout_pending(&vrtc->callout)) /* callout was reset */
556 if (!callout_active(&vrtc->callout)) /* callout was stopped */
559 callout_deactivate(&vrtc->callout);
561 KASSERT((vrtc->rtcdev.reg_b & RTCSB_ALL_INTRS) != 0,
562 ("gratuitous vrtc callout"));
564 if (pintr_enabled(vrtc))
565 vrtc_set_reg_c(vrtc, vrtc->rtcdev.reg_c | RTCIR_PERIOD);
567 if (aintr_enabled(vrtc) || uintr_enabled(vrtc)) {
568 rtctime = vrtc_curtime(vrtc, &basetime);
569 error = vrtc_time_update(vrtc, rtctime, basetime);
570 KASSERT(error == 0, ("%s: vrtc_time_update error %d",
574 freqsbt = vrtc_freq(vrtc);
575 KASSERT(freqsbt != 0, ("%s: vrtc frequency cannot be zero", __func__));
576 vrtc_callout_reset(vrtc, freqsbt);
582 vrtc_callout_check(struct vrtc *vrtc, sbintime_t freq)
586 active = callout_active(&vrtc->callout) ? 1 : 0;
587 KASSERT((freq == 0 && !active) || (freq != 0 && active),
588 ("vrtc callout %s with frequency %#lx",
589 active ? "active" : "inactive", freq));
593 vrtc_set_reg_c(struct vrtc *vrtc, uint8_t newval)
596 int oldirqf, newirqf;
597 uint8_t oldval, changed;
599 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
602 newval &= RTCIR_ALARM | RTCIR_PERIOD | RTCIR_UPDATE;
604 oldirqf = rtc->reg_c & RTCIR_INT;
605 if ((aintr_enabled(vrtc) && (newval & RTCIR_ALARM) != 0) ||
606 (pintr_enabled(vrtc) && (newval & RTCIR_PERIOD) != 0) ||
607 (uintr_enabled(vrtc) && (newval & RTCIR_UPDATE) != 0)) {
614 rtc->reg_c = newirqf | newval;
615 changed = oldval ^ rtc->reg_c;
617 VM_CTR2(vrtc->vm, "RTC reg_c changed from %#x to %#x",
621 if (!oldirqf && newirqf) {
622 VM_CTR1(vrtc->vm, "RTC irq %d asserted", RTC_IRQ);
623 vatpic_pulse_irq(vrtc->vm, RTC_IRQ);
624 vioapic_pulse_irq(vrtc->vm, RTC_IRQ);
625 } else if (oldirqf && !newirqf) {
626 VM_CTR1(vrtc->vm, "RTC irq %d deasserted", RTC_IRQ);
631 vrtc_set_reg_b(struct vrtc *vrtc, uint8_t newval)
634 sbintime_t oldfreq, newfreq, basetime;
635 time_t curtime, rtctime;
637 uint8_t oldval, changed;
639 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
643 oldfreq = vrtc_freq(vrtc);
646 changed = oldval ^ newval;
648 VM_CTR2(vrtc->vm, "RTC reg_b changed from %#x to %#x",
652 if (changed & RTCSB_HALT) {
653 if ((newval & RTCSB_HALT) == 0) {
654 rtctime = rtc_to_secs(vrtc);
655 basetime = sbinuptime();
656 if (rtctime == VRTC_BROKEN_TIME) {
657 if (rtc_flag_broken_time)
661 curtime = vrtc_curtime(vrtc, &basetime);
662 KASSERT(curtime == vrtc->base_rtctime, ("%s: mismatch "
663 "between vrtc basetime (%#lx) and curtime (%#lx)",
664 __func__, vrtc->base_rtctime, curtime));
667 * Force a refresh of the RTC date/time fields so
668 * they reflect the time right before the guest set
671 secs_to_rtc(curtime, vrtc, 1);
674 * Updates are halted so mark 'base_rtctime' to denote
675 * that the RTC date/time is in flux.
677 rtctime = VRTC_BROKEN_TIME;
678 rtc->reg_b &= ~RTCSB_UINTR;
680 error = vrtc_time_update(vrtc, rtctime, basetime);
681 KASSERT(error == 0, ("vrtc_time_update error %d", error));
685 * Side effect of changes to the interrupt enable bits.
687 if (changed & RTCSB_ALL_INTRS)
688 vrtc_set_reg_c(vrtc, vrtc->rtcdev.reg_c);
691 * Change the callout frequency if it has changed.
693 newfreq = vrtc_freq(vrtc);
694 if (newfreq != oldfreq)
695 vrtc_callout_reset(vrtc, newfreq);
697 vrtc_callout_check(vrtc, newfreq);
700 * The side effect of bits that control the RTC date/time format
701 * is handled lazily when those fields are actually read.
707 vrtc_set_reg_a(struct vrtc *vrtc, uint8_t newval)
709 sbintime_t oldfreq, newfreq;
710 uint8_t oldval, changed;
712 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
714 newval &= ~RTCSA_TUP;
715 oldval = vrtc->rtcdev.reg_a;
716 oldfreq = vrtc_freq(vrtc);
718 if (divider_enabled(oldval) && !divider_enabled(newval)) {
719 VM_CTR2(vrtc->vm, "RTC divider held in reset at %#lx/%#lx",
720 vrtc->base_rtctime, vrtc->base_uptime);
721 } else if (!divider_enabled(oldval) && divider_enabled(newval)) {
723 * If the dividers are coming out of reset then update
724 * 'base_uptime' before this happens. This is done to
725 * maintain the illusion that the RTC date/time was frozen
726 * while the dividers were disabled.
728 vrtc->base_uptime = sbinuptime();
729 VM_CTR2(vrtc->vm, "RTC divider out of reset at %#lx/%#lx",
730 vrtc->base_rtctime, vrtc->base_uptime);
735 vrtc->rtcdev.reg_a = newval;
736 changed = oldval ^ newval;
738 VM_CTR2(vrtc->vm, "RTC reg_a changed from %#x to %#x",
743 * Side effect of changes to rate select and divider enable bits.
745 newfreq = vrtc_freq(vrtc);
746 if (newfreq != oldfreq)
747 vrtc_callout_reset(vrtc, newfreq);
749 vrtc_callout_check(vrtc, newfreq);
753 vrtc_set_time(struct vm *vm, time_t secs)
760 error = vrtc_time_update(vrtc, secs, sbinuptime());
764 VM_CTR2(vrtc->vm, "Error %d setting RTC time to %#lx", error,
767 VM_CTR1(vrtc->vm, "RTC time set to %#lx", secs);
774 vrtc_get_time(struct vm *vm)
782 t = vrtc_curtime(vrtc, &basetime);
789 vrtc_nvram_write(struct vm *vm, int offset, uint8_t value)
797 * Don't allow writes to RTC control registers or the date/time fields.
799 if (offset < offsetof(struct rtcdev, nvram[0]) ||
800 offset == RTC_CENTURY || offset >= sizeof(struct rtcdev)) {
801 VM_CTR1(vrtc->vm, "RTC nvram write to invalid offset %d",
807 ptr = (uint8_t *)(&vrtc->rtcdev);
809 VM_CTR2(vrtc->vm, "RTC nvram write %#x to offset %#x", value, offset);
816 vrtc_nvram_read(struct vm *vm, int offset, uint8_t *retval)
824 * Allow all offsets in the RTC to be read.
826 if (offset < 0 || offset >= sizeof(struct rtcdev))
833 * Update RTC date/time fields if necessary.
835 if (offset < 10 || offset == RTC_CENTURY) {
836 curtime = vrtc_curtime(vrtc, &basetime);
837 secs_to_rtc(curtime, vrtc, 0);
840 ptr = (uint8_t *)(&vrtc->rtcdev);
841 *retval = ptr[offset];
848 vrtc_addr_handler(struct vm *vm, int vcpuid, bool in, int port, int bytes,
864 vrtc->addr = *val & 0x7f;
871 vrtc_data_handler(struct vm *vm, int vcpuid, bool in, int port, int bytes,
888 if (offset >= sizeof(struct rtcdev)) {
894 curtime = vrtc_curtime(vrtc, &basetime);
895 vrtc_time_update(vrtc, curtime, basetime);
898 * Update RTC date/time fields if necessary.
900 * This is not just for reads of the RTC. The side-effect of writing
901 * the century byte requires other RTC date/time fields (e.g. sec)
902 * to be updated here.
904 if (offset < 10 || offset == RTC_CENTURY)
905 secs_to_rtc(curtime, vrtc, 0);
911 * reg_c interrupt flags are updated only if the
912 * corresponding interrupt enable bit in reg_b is set.
914 *val = vrtc->rtcdev.reg_c;
915 vrtc_set_reg_c(vrtc, 0);
917 *val = *((uint8_t *)rtc + offset);
919 VCPU_CTR2(vm, vcpuid, "Read value %#x from RTC offset %#x",
924 VCPU_CTR1(vm, vcpuid, "RTC reg_a set to %#x", *val);
925 vrtc_set_reg_a(vrtc, *val);
928 VCPU_CTR1(vm, vcpuid, "RTC reg_b set to %#x", *val);
929 error = vrtc_set_reg_b(vrtc, *val);
932 VCPU_CTR1(vm, vcpuid, "RTC reg_c set to %#x (ignored)",
936 VCPU_CTR1(vm, vcpuid, "RTC reg_d set to %#x (ignored)",
941 * High order bit of 'seconds' is readonly.
946 VCPU_CTR2(vm, vcpuid, "RTC offset %#x set to %#x",
948 *((uint8_t *)rtc + offset) = *val;
953 * XXX some guests (e.g. OpenBSD) write the century byte
954 * outside of RTCSB_HALT so re-calculate the RTC date/time.
956 if (offset == RTC_CENTURY && !rtc_halted(vrtc)) {
957 curtime = rtc_to_secs(vrtc);
958 error = vrtc_time_update(vrtc, curtime, sbinuptime());
959 KASSERT(!error, ("vrtc_time_update error %d", error));
960 if (curtime == VRTC_BROKEN_TIME && rtc_flag_broken_time)
969 vrtc_reset(struct vrtc *vrtc)
976 vrtc_set_reg_b(vrtc, rtc->reg_b & ~(RTCSB_ALL_INTRS | RTCSB_SQWE));
977 vrtc_set_reg_c(vrtc, 0);
978 KASSERT(!callout_active(&vrtc->callout), ("rtc callout still active"));
984 vrtc_init(struct vm *vm)
990 vrtc = malloc(sizeof(struct vrtc), M_VRTC, M_WAITOK | M_ZERO);
992 mtx_init(&vrtc->mtx, "vrtc lock", NULL, MTX_DEF);
993 callout_init(&vrtc->callout, 1);
995 /* Allow dividers to keep time but disable everything else */
998 rtc->reg_b = RTCSB_24HR;
1000 rtc->reg_d = RTCSD_PWR;
1002 /* Reset the index register to a safe value. */
1003 vrtc->addr = RTC_STATUSD;
1006 * Initialize RTC time to 00:00:00 Jan 1, 1970.
1011 vrtc->base_rtctime = VRTC_BROKEN_TIME;
1012 vrtc_time_update(vrtc, curtime, sbinuptime());
1013 secs_to_rtc(curtime, vrtc, 0);
1020 vrtc_cleanup(struct vrtc *vrtc)
1023 callout_drain(&vrtc->callout);
1027 #ifdef BHYVE_SNAPSHOT
1029 vrtc_snapshot(struct vrtc *vrtc, struct vm_snapshot_meta *meta)
1035 SNAPSHOT_VAR_OR_LEAVE(vrtc->addr, meta, ret, done);
1036 if (meta->op == VM_SNAPSHOT_RESTORE)
1037 vrtc->base_uptime = sbinuptime();
1038 SNAPSHOT_VAR_OR_LEAVE(vrtc->base_rtctime, meta, ret, done);
1040 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.sec, meta, ret, done);
1041 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.alarm_sec, meta, ret, done);
1042 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.min, meta, ret, done);
1043 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.alarm_min, meta, ret, done);
1044 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.hour, meta, ret, done);
1045 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.alarm_hour, meta, ret, done);
1046 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.day_of_week, meta, ret, done);
1047 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.day_of_month, meta, ret, done);
1048 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.month, meta, ret, done);
1049 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.year, meta, ret, done);
1050 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.reg_a, meta, ret, done);
1051 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.reg_b, meta, ret, done);
1052 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.reg_c, meta, ret, done);
1053 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.reg_d, meta, ret, done);
1054 SNAPSHOT_BUF_OR_LEAVE(vrtc->rtcdev.nvram, sizeof(vrtc->rtcdev.nvram),
1056 SNAPSHOT_VAR_OR_LEAVE(vrtc->rtcdev.century, meta, ret, done);
1057 SNAPSHOT_BUF_OR_LEAVE(vrtc->rtcdev.nvram2, sizeof(vrtc->rtcdev.nvram2),
1060 vrtc_callout_reset(vrtc, vrtc_freq(vrtc));