On Thu, 1 Dec 2011 12:43:31 -0600 Anthony Liguori <aligu...@us.ibm.com> wrote:
I think it's a good idea to use python's unittest module and write tests as unit-tests (eg. using asserts instead of writing results as strings). > --- > 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:]))