• Home
  • History
  • Annotate
  • Raw
  • Download
  • only in /freebsd-13-stable/sys/amd64/vmm/io/

Lines Matching defs:vrtc

52 #include "vrtc.h"
77 struct vrtc {
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))
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)
107 static void vrtc_set_reg_c(struct vrtc *vrtc, uint8_t newval);
109 static MALLOC_DEFINE(M_VRTC, "vrtc", "bhyve virtual rtc");
112 SYSCTL_NODE(_hw_vmm, OID_AUTO, vrtc, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL,
129 update_enabled(struct vrtc *vrtc)
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)
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;
163 "%#lx to %#lx", vrtc->base_uptime, now));
182 secs_to_rtc(time_t rtctime, struct vrtc *vrtc, int force_update)
189 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
193 ("%s: invalid vrtc time %#lx", __func__, rtctime));
202 if (rtc_halted(vrtc) && !force_update)
224 rtc = &vrtc->rtcdev;
283 rtc_to_secs(struct vrtc *vrtc)
291 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
293 vm = vrtc->vm;
294 rtc = &vrtc->rtcdev;
396 VM_CTR0(vrtc->vm, "Invalid RTC date/time programming detected");
401 vrtc_time_update(struct vrtc *vrtc, time_t newtime, sbintime_t newbase)
408 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
410 rtc = &vrtc->rtcdev;
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;
433 vrtc->base_rtctime = VRTC_BROKEN_TIME;
440 if (rtc_halted(vrtc)) {
441 VM_CTR0(vrtc->vm, "RTC update halted by guest");
453 if (aintr_enabled(vrtc) && oldtime != VRTC_BROKEN_TIME)
454 vrtc->base_rtctime++;
456 vrtc->base_rtctime = newtime;
458 if (aintr_enabled(vrtc)) {
463 secs_to_rtc(vrtc->base_rtctime, vrtc, 0);
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)
503 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
512 if (pintr_enabled(vrtc) && divider_enabled(vrtc->rtcdev.reg_a)) {
513 ratesel = vrtc->rtcdev.reg_a & 0xf;
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,
539 vrtc, 0);
545 struct vrtc *vrtc = arg;
550 VM_CTR0(vrtc->vm, "vrtc callout fired");
552 VRTC_LOCK(vrtc);
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);
574 freqsbt = vrtc_freq(vrtc);
575 KASSERT(freqsbt != 0, ("%s: vrtc frequency cannot be zero", __func__));
576 vrtc_callout_reset(vrtc, freqsbt);
578 VRTC_UNLOCK(vrtc);
582 vrtc_callout_check(struct vrtc *vrtc, sbintime_t freq)
586 active = callout_active(&vrtc->callout) ? 1 : 0;
588 ("vrtc callout %s with frequency %#lx",
593 vrtc_set_reg_c(struct vrtc *vrtc, uint8_t newval)
599 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
601 rtc = &vrtc->rtcdev;
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)) {
617 VM_CTR2(vrtc->vm, "RTC reg_c changed from %#x to %#x",
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);
626 VM_CTR1(vrtc->vm, "RTC irq %d deasserted", RTC_IRQ);
631 vrtc_set_reg_b(struct vrtc *vrtc, uint8_t newval)
639 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
641 rtc = &vrtc->rtcdev;
643 oldfreq = vrtc_freq(vrtc);
648 VM_CTR2(vrtc->vm, "RTC reg_b changed from %#x to %#x",
654 rtctime = rtc_to_secs(vrtc);
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));
671 secs_to_rtc(curtime, vrtc, 1);
680 error = vrtc_time_update(vrtc, rtctime, basetime);
688 vrtc_set_reg_c(vrtc, vrtc->rtcdev.reg_c);
693 newfreq = vrtc_freq(vrtc);
695 vrtc_callout_reset(vrtc, newfreq);
697 vrtc_callout_check(vrtc, newfreq);
707 vrtc_set_reg_a(struct vrtc *vrtc, uint8_t newval)
712 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
715 oldval = vrtc->rtcdev.reg_a;
716 oldfreq = vrtc_freq(vrtc);
719 VM_CTR2(vrtc->vm, "RTC divider held in reset at %#lx/%#lx",
720 vrtc->base_rtctime, vrtc->base_uptime);
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;
738 VM_CTR2(vrtc->vm, "RTC reg_a changed from %#x to %#x",
745 newfreq = vrtc_freq(vrtc);
747 vrtc_callout_reset(vrtc, newfreq);
749 vrtc_callout_check(vrtc, newfreq);
755 struct vrtc *vrtc;
758 vrtc = vm_rtc(vm);
759 VRTC_LOCK(vrtc);
760 error = vrtc_time_update(vrtc, secs, sbinuptime());
761 VRTC_UNLOCK(vrtc);
764 VM_CTR2(vrtc->vm, "Error %d setting RTC time to %#lx", error,
767 VM_CTR1(vrtc->vm, "RTC time set to %#lx", secs);
776 struct vrtc *vrtc;
780 vrtc = vm_rtc(vm);
781 VRTC_LOCK(vrtc);
782 t = vrtc_curtime(vrtc, &basetime);
783 VRTC_UNLOCK(vrtc);
791 struct vrtc *vrtc;
794 vrtc = vm_rtc(vm);
801 VM_CTR1(vrtc->vm, "RTC nvram write to invalid offset %d",
806 VRTC_LOCK(vrtc);
807 ptr = (uint8_t *)(&vrtc->rtcdev);
809 VM_CTR2(vrtc->vm, "RTC nvram write %#x to offset %#x", value, offset);
810 VRTC_UNLOCK(vrtc);
818 struct vrtc *vrtc;
829 vrtc = vm_rtc(vm);
830 VRTC_LOCK(vrtc);
836 curtime = vrtc_curtime(vrtc, &basetime);
837 secs_to_rtc(curtime, vrtc, 0);
840 ptr = (uint8_t *)(&vrtc->rtcdev);
843 VRTC_UNLOCK(vrtc);
851 struct vrtc *vrtc;
853 vrtc = vm_rtc(vm);
863 VRTC_LOCK(vrtc);
864 vrtc->addr = *val & 0x7f;
865 VRTC_UNLOCK(vrtc);
874 struct vrtc *vrtc;
880 vrtc = vm_rtc(vm);
881 rtc = &vrtc->rtcdev;
886 VRTC_LOCK(vrtc);
887 offset = vrtc->addr;
889 VRTC_UNLOCK(vrtc);
894 curtime = vrtc_curtime(vrtc, &basetime);
895 vrtc_time_update(vrtc, curtime, basetime);
905 secs_to_rtc(curtime, vrtc, 0);
914 *val = vrtc->rtcdev.reg_c;
915 vrtc_set_reg_c(vrtc, 0);
925 vrtc_set_reg_a(vrtc, *val);
929 error = vrtc_set_reg_b(vrtc, *val);
956 if (offset == RTC_CENTURY && !rtc_halted(vrtc)) {
957 curtime = rtc_to_secs(vrtc);
958 error = vrtc_time_update(vrtc, curtime, sbinuptime());
964 VRTC_UNLOCK(vrtc);
969 vrtc_reset(struct vrtc *vrtc)
973 VRTC_LOCK(vrtc);
975 rtc = &vrtc->rtcdev;
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"));
980 VRTC_UNLOCK(vrtc);
983 struct vrtc *
986 struct vrtc *vrtc;
990 vrtc = malloc(sizeof(struct vrtc), M_VRTC, M_WAITOK | M_ZERO);
991 vrtc->vm = vm;
992 mtx_init(&vrtc->mtx, "vrtc lock", NULL, MTX_DEF);
993 callout_init(&vrtc->callout, 1);
996 rtc = &vrtc->rtcdev;
1003 vrtc->addr = RTC_STATUSD;
1010 VRTC_LOCK(vrtc);
1011 vrtc->base_rtctime = VRTC_BROKEN_TIME;
1012 vrtc_time_update(vrtc, curtime, sbinuptime());
1013 secs_to_rtc(curtime, vrtc, 0);
1014 VRTC_UNLOCK(vrtc);
1016 return (vrtc);
1020 vrtc_cleanup(struct vrtc *vrtc)
1023 callout_drain(&vrtc->callout);
1024 free(vrtc, M_VRTC);
1029 vrtc_snapshot(struct vrtc *vrtc, struct vm_snapshot_meta *meta)
1033 VRTC_LOCK(vrtc);
1035 SNAPSHOT_VAR_OR_LEAVE(vrtc->addr, meta, ret, done);
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));
1062 VRTC_UNLOCK(vrtc);