summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bhyve/rtc.c
diff options
context:
space:
mode:
authorgrehan <grehan@FreeBSD.org>2013-01-25 22:43:20 +0000
committergrehan <grehan@FreeBSD.org>2013-01-25 22:43:20 +0000
commit6112ba9b1816c490e13e787f2778aec9e990c622 (patch)
treed292c9eddf7e2cb1e470635218bff6f0b340e5d1 /usr.sbin/bhyve/rtc.c
parent183419297ca9ccdf9a3a0ec8739953751071cfdf (diff)
downloadFreeBSD-src-6112ba9b1816c490e13e787f2778aec9e990c622.zip
FreeBSD-src-6112ba9b1816c490e13e787f2778aec9e990c622.tar.gz
Improve correctness of rtc register implementation.
Submitted by: tycho nightingale at pluribusnetworks com
Diffstat (limited to 'usr.sbin/bhyve/rtc.c')
-rw-r--r--usr.sbin/bhyve/rtc.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/usr.sbin/bhyve/rtc.c b/usr.sbin/bhyve/rtc.c
index f8b894e..df21ac8 100644
--- a/usr.sbin/bhyve/rtc.c
+++ b/usr.sbin/bhyve/rtc.c
@@ -118,12 +118,16 @@ static int
rtc_addr_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
uint32_t *eax, void *arg)
{
- assert(in == 0);
-
if (bytes != 1)
return (-1);
- switch (*eax) {
+ if (in) {
+ /* straight read of this register will return 0xFF */
+ *eax = 0xff;
+ return (0);
+ }
+
+ switch (*eax & 0x7f) {
case RTC_SEC:
case RTC_MIN:
case RTC_HRS:
@@ -144,7 +148,7 @@ rtc_addr_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
return (-1);
}
- addr = *eax;
+ addr = *eax & 0x7f;
return (0);
}
@@ -219,6 +223,9 @@ rtc_data_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
case RTC_STATUSA:
*eax = status_a;
return (0);
+ case RTC_STATUSB:
+ *eax = status_b;
+ return (0);
case RTC_INTR:
*eax = 0;
return (0);
@@ -249,6 +256,9 @@ rtc_data_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
return (-1);
status_b = *eax;
break;
+ case RTC_STATUSD:
+ /* ignore write */
+ break;
case RTC_RSTCODE:
rstcode = *eax;
break;
@@ -270,5 +280,5 @@ rtc_data_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
return (0);
}
-INOUT_PORT(rtc, IO_RTC, IOPORT_F_OUT, rtc_addr_handler);
+INOUT_PORT(rtc, IO_RTC, IOPORT_F_INOUT, rtc_addr_handler);
INOUT_PORT(rtc, IO_RTC + 1, IOPORT_F_INOUT, rtc_data_handler);
OpenPOWER on IntegriCloud