Lines Matching defs:vrtc

47 #include "vrtc.h"
72 struct vrtc {
82 #define VRTC_LOCK(vrtc) mtx_lock(&((vrtc)->mtx))
83 #define VRTC_UNLOCK(vrtc) mtx_unlock(&((vrtc)->mtx))
84 #define VRTC_LOCKED(vrtc) mtx_owned(&((vrtc)->mtx))
96 #define rtc_halted(vrtc) ((vrtc->rtcdev.reg_b & RTCSB_HALT) != 0)
97 #define aintr_enabled(vrtc) (((vrtc)->rtcdev.reg_b & RTCSB_AINTR) != 0)
98 #define pintr_enabled(vrtc) (((vrtc)->rtcdev.reg_b & RTCSB_PINTR) != 0)
99 #define uintr_enabled(vrtc) (((vrtc)->rtcdev.reg_b & RTCSB_UINTR) != 0)
102 static void vrtc_set_reg_c(struct vrtc *vrtc, uint8_t newval);
104 static MALLOC_DEFINE(M_VRTC, "vrtc", "bhyve virtual rtc");
107 SYSCTL_NODE(_hw_vmm, OID_AUTO, vrtc, CTLFLAG_RW, NULL, NULL);
123 update_enabled(struct vrtc *vrtc)
131 if (!divider_enabled(vrtc->rtcdev.reg_a))
134 if (rtc_halted(vrtc))
137 if (vrtc->base_rtctime == VRTC_BROKEN_TIME)
144 vrtc_curtime(struct vrtc *vrtc, sbintime_t *basetime)
149 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
151 t = vrtc->base_rtctime;
152 *basetime = vrtc->base_uptime;
153 if (update_enabled(vrtc)) {
155 delta = now - vrtc->base_uptime;
157 "%#lx to %#lx", vrtc->base_uptime, now));
176 secs_to_rtc(time_t rtctime, struct vrtc *vrtc, int force_update)
183 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
187 ("%s: invalid vrtc time %#lx", __func__, rtctime));
196 if (rtc_halted(vrtc) && !force_update)
218 rtc = &vrtc->rtcdev;
277 rtc_to_secs(struct vrtc *vrtc)
285 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
287 vm = vrtc->vm;
288 rtc = &vrtc->rtcdev;
390 VM_CTR0(vrtc->vm, "Invalid RTC date/time programming detected");
395 vrtc_time_update(struct vrtc *vrtc, time_t newtime, sbintime_t newbase)
402 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
404 rtc = &vrtc->rtcdev;
409 oldtime = vrtc->base_rtctime;
410 VM_CTR2(vrtc->vm, "Updating RTC secs from %#lx to %#lx",
413 oldbase = vrtc->base_uptime;
414 VM_CTR2(vrtc->vm, "Updating RTC base uptime from %#lx to %#lx",
416 vrtc->base_uptime = newbase;
427 vrtc->base_rtctime = VRTC_BROKEN_TIME;
434 if (rtc_halted(vrtc)) {
435 VM_CTR0(vrtc->vm, "RTC update halted by guest");
447 if (aintr_enabled(vrtc) && oldtime != VRTC_BROKEN_TIME)
448 vrtc->base_rtctime++;
450 vrtc->base_rtctime = newtime;
452 if (aintr_enabled(vrtc)) {
457 secs_to_rtc(vrtc->base_rtctime, vrtc, 0);
462 vrtc_set_reg_c(vrtc, rtc->reg_c | RTCIR_ALARM);
465 } while (vrtc->base_rtctime != newtime);
467 if (uintr_enabled(vrtc))
468 vrtc_set_reg_c(vrtc, rtc->reg_c | RTCIR_UPDATE);
474 vrtc_freq(struct vrtc *vrtc)
497 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
506 if (pintr_enabled(vrtc) && divider_enabled(vrtc->rtcdev.reg_a)) {
507 ratesel = vrtc->rtcdev.reg_a & 0xf;
509 } else if (aintr_enabled(vrtc) && update_enabled(vrtc)) {
511 } else if (uintr_enabled(vrtc) && update_enabled(vrtc)) {
519 vrtc_callout_reset(struct vrtc *vrtc, sbintime_t freqsbt)
522 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
525 if (callout_active(&vrtc->callout)) {
526 VM_CTR0(vrtc->vm, "RTC callout stopped");
527 callout_stop(&vrtc->callout);
531 VM_CTR1(vrtc->vm, "RTC callout frequency %d hz", SBT_1S / freqsbt);
532 callout_reset_sbt(&vrtc->callout, freqsbt, 0, vrtc_callout_handler,
533 vrtc, 0);
539 struct vrtc *vrtc = arg;
544 VM_CTR0(vrtc->vm, "vrtc callout fired");
546 VRTC_LOCK(vrtc);
547 if (callout_pending(&vrtc->callout)) /* callout was reset */
550 if (!callout_active(&vrtc->callout)) /* callout was stopped */
553 callout_deactivate(&vrtc->callout);
555 KASSERT((vrtc->rtcdev.reg_b & RTCSB_ALL_INTRS) != 0,
556 ("gratuitous vrtc callout"));
558 if (pintr_enabled(vrtc))
559 vrtc_set_reg_c(vrtc, vrtc->rtcdev.reg_c | RTCIR_PERIOD);
561 if (aintr_enabled(vrtc) || uintr_enabled(vrtc)) {
562 rtctime = vrtc_curtime(vrtc, &basetime);
563 error = vrtc_time_update(vrtc, rtctime, basetime);
568 freqsbt = vrtc_freq(vrtc);
569 KASSERT(freqsbt != 0, ("%s: vrtc frequency cannot be zero", __func__));
570 vrtc_callout_reset(vrtc, freqsbt);
572 VRTC_UNLOCK(vrtc);
576 vrtc_callout_check(struct vrtc *vrtc, sbintime_t freq)
580 active = callout_active(&vrtc->callout) ? 1 : 0;
582 ("vrtc callout %s with frequency %#lx",
587 vrtc_set_reg_c(struct vrtc *vrtc, uint8_t newval)
593 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
595 rtc = &vrtc->rtcdev;
599 if ((aintr_enabled(vrtc) && (newval & RTCIR_ALARM) != 0) ||
600 (pintr_enabled(vrtc) && (newval & RTCIR_PERIOD) != 0) ||
601 (uintr_enabled(vrtc) && (newval & RTCIR_UPDATE) != 0)) {
611 VM_CTR2(vrtc->vm, "RTC reg_c changed from %#x to %#x",
616 VM_CTR1(vrtc->vm, "RTC irq %d asserted", RTC_IRQ);
617 vatpic_pulse_irq(vrtc->vm, RTC_IRQ);
618 vioapic_pulse_irq(vrtc->vm, RTC_IRQ);
620 VM_CTR1(vrtc->vm, "RTC irq %d deasserted", RTC_IRQ);
625 vrtc_set_reg_b(struct vrtc *vrtc, uint8_t newval)
633 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
635 rtc = &vrtc->rtcdev;
637 oldfreq = vrtc_freq(vrtc);
642 VM_CTR2(vrtc->vm, "RTC reg_b changed from %#x to %#x",
648 rtctime = rtc_to_secs(vrtc);
655 curtime = vrtc_curtime(vrtc, &basetime);
656 KASSERT(curtime == vrtc->base_rtctime, ("%s: mismatch "
657 "between vrtc basetime (%#lx) and curtime (%#lx)",
658 __func__, vrtc->base_rtctime, curtime));
665 secs_to_rtc(curtime, vrtc, 1);
674 error = vrtc_time_update(vrtc, rtctime, basetime);
682 vrtc_set_reg_c(vrtc, vrtc->rtcdev.reg_c);
687 newfreq = vrtc_freq(vrtc);
689 vrtc_callout_reset(vrtc, newfreq);
691 vrtc_callout_check(vrtc, newfreq);
701 vrtc_set_reg_a(struct vrtc *vrtc, uint8_t newval)
706 KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
709 oldval = vrtc->rtcdev.reg_a;
710 oldfreq = vrtc_freq(vrtc);
713 VM_CTR2(vrtc->vm, "RTC divider held in reset at %#lx/%#lx",
714 vrtc->base_rtctime, vrtc->base_uptime);
722 vrtc->base_uptime = sbinuptime();
723 VM_CTR2(vrtc->vm, "RTC divider out of reset at %#lx/%#lx",
724 vrtc->base_rtctime, vrtc->base_uptime);
729 vrtc->rtcdev.reg_a = newval;
732 VM_CTR2(vrtc->vm, "RTC reg_a changed from %#x to %#x",
739 newfreq = vrtc_freq(vrtc);
741 vrtc_callout_reset(vrtc, newfreq);
743 vrtc_callout_check(vrtc, newfreq);
749 struct vrtc *vrtc;
752 vrtc = vm_rtc(vm);
753 VRTC_LOCK(vrtc);
754 error = vrtc_time_update(vrtc, secs, sbinuptime());
755 VRTC_UNLOCK(vrtc);
758 VM_CTR2(vrtc->vm, "Error %d setting RTC time to %#lx", error,
761 VM_CTR1(vrtc->vm, "RTC time set to %#lx", secs);
770 struct vrtc *vrtc;
774 vrtc = vm_rtc(vm);
775 VRTC_LOCK(vrtc);
776 t = vrtc_curtime(vrtc, &basetime);
777 VRTC_UNLOCK(vrtc);
785 struct vrtc *vrtc;
788 vrtc = vm_rtc(vm);
795 VM_CTR1(vrtc->vm, "RTC nvram write to invalid offset %d",
800 VRTC_LOCK(vrtc);
801 ptr = (uint8_t *)(&vrtc->rtcdev);
803 VM_CTR2(vrtc->vm, "RTC nvram write %#x to offset %#x", value, offset);
804 VRTC_UNLOCK(vrtc);
812 struct vrtc *vrtc;
823 vrtc = vm_rtc(vm);
824 VRTC_LOCK(vrtc);
830 curtime = vrtc_curtime(vrtc, &basetime);
831 secs_to_rtc(curtime, vrtc, 0);
834 ptr = (uint8_t *)(&vrtc->rtcdev);
837 VRTC_UNLOCK(vrtc);
845 struct vrtc *vrtc;
847 vrtc = vm_rtc(vm);
857 VRTC_LOCK(vrtc);
858 vrtc->addr = *val & 0x7f;
859 VRTC_UNLOCK(vrtc);
868 struct vrtc *vrtc;
874 vrtc = vm_rtc(vm);
875 rtc = &vrtc->rtcdev;
880 VRTC_LOCK(vrtc);
881 offset = vrtc->addr;
883 VRTC_UNLOCK(vrtc);
888 curtime = vrtc_curtime(vrtc, &basetime);
889 vrtc_time_update(vrtc, curtime, basetime);
899 secs_to_rtc(curtime, vrtc, 0);
908 *val = vrtc->rtcdev.reg_c;
909 vrtc_set_reg_c(vrtc, 0);
919 vrtc_set_reg_a(vrtc, *val);
923 error = vrtc_set_reg_b(vrtc, *val);
950 if (offset == RTC_CENTURY && !rtc_halted(vrtc)) {
951 curtime = rtc_to_secs(vrtc);
952 error = vrtc_time_update(vrtc, curtime, sbinuptime());
958 VRTC_UNLOCK(vrtc);
963 vrtc_reset(struct vrtc *vrtc)
967 VRTC_LOCK(vrtc);
969 rtc = &vrtc->rtcdev;
970 vrtc_set_reg_b(vrtc, rtc->reg_b & ~(RTCSB_ALL_INTRS | RTCSB_SQWE));
971 vrtc_set_reg_c(vrtc, 0);
972 KASSERT(!callout_active(&vrtc->callout), ("rtc callout still active"));
974 VRTC_UNLOCK(vrtc);
977 struct vrtc *
980 struct vrtc *vrtc;
984 vrtc = malloc(sizeof(struct vrtc), M_VRTC, M_WAITOK | M_ZERO);
985 vrtc->vm = vm;
986 mtx_init(&vrtc->mtx, "vrtc lock", NULL, MTX_DEF);
987 callout_init(&vrtc->callout, 1);
990 rtc = &vrtc->rtcdev;
997 vrtc->addr = RTC_STATUSD;
1004 VRTC_LOCK(vrtc);
1005 vrtc->base_rtctime = VRTC_BROKEN_TIME;
1006 vrtc_time_update(vrtc, curtime, sbinuptime());
1007 secs_to_rtc(curtime, vrtc, 0);
1008 VRTC_UNLOCK(vrtc);
1010 return (vrtc);
1014 vrtc_cleanup(struct vrtc *vrtc)
1017 callout_drain(&vrtc->callout);
1018 free(vrtc, M_VRTC);