From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:46807) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RWHdo-0000oh-VT for qemu-devel@nongnu.org; Thu, 01 Dec 2011 20:10:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RWHdn-0003JM-Mk for qemu-devel@nongnu.org; Thu, 01 Dec 2011 20:10:16 -0500 Received: from cpe-70-123-132-139.austin.res.rr.com ([70.123.132.139]:51178 helo=localhost6.localdomain6) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RWHdn-0003Cy-0T for qemu-devel@nongnu.org; Thu, 01 Dec 2011 20:10:15 -0500 From: Anthony Liguori Date: Thu, 1 Dec 2011 12:43:31 -0600 Message-Id: <1322765012-3164-6-git-send-email-aliguori@us.ibm.com> In-Reply-To: <1322765012-3164-1-git-send-email-aliguori@us.ibm.com> References: <1322765012-3164-1-git-send-email-aliguori@us.ibm.com> Subject: [Qemu-devel] [RFC v2 5/6] Add RTC test case List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Anthony Liguori --- rtc-test.py | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 105 insertions(+), 0 deletions(-) create mode 100644 rtc-test.py diff --git a/rtc-test.py b/rtc-test.py new file mode 100644 index 0000000..3159795 --- /dev/null +++ b/rtc-test.py @@ -0,0 +1,105 @@ +from qtest import inb, outb +import qtest, time, calendar + +base = 0x70 + +def bcd2dec(value): + return (((value >> 4) & 0x0F) * 10) + (value & 0x0F) + +def dec2bcd(value): + return ((value / 10) << 4) | (value % 10) + +def cmos_read(reg): + outb(base + 0, reg) + return inb(base + 1) + +def cmos_write(reg, val): + outb(base + 0, reg) + outb(base + 1, val) + +def cmos_get_date_time(): + base_year = 2000 + + sec = cmos_read(0x00) + min = cmos_read(0x02) + hour = cmos_read(0x04) + mday = cmos_read(0x07) + mon = cmos_read(0x08) + year = cmos_read(0x09) + + if (cmos_read(0x0B) & 4) == 0: + sec = bcd2dec(sec) + min = bcd2dec(min) + hour = bcd2dec(hour) + mday = bcd2dec(mday) + mon = bcd2dec(mon) + year = bcd2dec(year) + hour_offset = 80 + else: + hour_offset = 0x80 + + if (cmos_read(0x0B) & 2) == 0: + if hour >= hour_offset: + hour -= hour_offset + hour += 12 + + return time.gmtime(calendar.timegm(((base_year + year), mon, mday, hour, min, sec))) + +def check_time(): + # This check assumes a few things. First, we cannot guarantee that we get + # a consistent reading from the wall clock because we may hit an edge of + # the clock while reading. To work around this, we read four clock readings + # such that at least two of them should match. We need to assume that one + # reading is corrupt so we need four readings to ensure that we have at + # least two consecutive identical readings + # + # It's also possible that we'll cross an edge reading the host clock so + # simply check to make sure that the clock reading is within the period of + # when we expect it to be. + + start = time.gmtime() + date1 = cmos_get_date_time() + date2 = cmos_get_date_time() + date3 = cmos_get_date_time() + date4 = cmos_get_date_time() + end = time.gmtime() + + if date1 == date2: + date = date1 + elif date2 == date3: + date = date2 + elif date3 == date4: + date = date4 + else: + print 'Could not read RTC fast enough' + return False + + if not start <= date <= end: + t = calendar.timegm(date) + s = calendar.timegm(start) + if t < s: + print 'RTC is %d second(s) behind wall-clock' % (s - t) + else: + print 'RTC is %d second(s) ahead of wall-clock' % (t - s) + return False + + return True + +def main(args): + qtest.init(args[0]) + + # Set BCD mode + cmos_write(0x0B, cmos_read(0x0B) | 0x02) + if not check_time(): + return 1 + + # Set DEC mode + cmos_write(0x0B, cmos_read(0x0B) & ~0x02) + if not check_time(): + return 1 + + return 0 + +if __name__ == '__main__': + import sys + sys.exit(main(sys.argv[1:])) -- 1.7.4.1