root / tests / rtc-test.c @ 164a101f
History | View | Annotate | Download (15.7 kB)
1 | d1aaf543 | Anthony Liguori | /*
|
---|---|---|---|
2 | d1aaf543 | Anthony Liguori | * QTest testcase for the MC146818 real-time clock
|
3 | d1aaf543 | Anthony Liguori | *
|
4 | d1aaf543 | Anthony Liguori | * Copyright IBM, Corp. 2012
|
5 | d1aaf543 | Anthony Liguori | *
|
6 | d1aaf543 | Anthony Liguori | * Authors:
|
7 | d1aaf543 | Anthony Liguori | * Anthony Liguori <aliguori@us.ibm.com>
|
8 | d1aaf543 | Anthony Liguori | *
|
9 | d1aaf543 | Anthony Liguori | * This work is licensed under the terms of the GNU GPL, version 2 or later.
|
10 | d1aaf543 | Anthony Liguori | * See the COPYING file in the top-level directory.
|
11 | d1aaf543 | Anthony Liguori | *
|
12 | d1aaf543 | Anthony Liguori | */
|
13 | d1aaf543 | Anthony Liguori | #include "libqtest.h" |
14 | 0d09e41a | Paolo Bonzini | #include "hw/timer/mc146818rtc_regs.h" |
15 | d1aaf543 | Anthony Liguori | |
16 | d1aaf543 | Anthony Liguori | #include <glib.h> |
17 | d1aaf543 | Anthony Liguori | #include <stdio.h> |
18 | d1aaf543 | Anthony Liguori | #include <string.h> |
19 | d1aaf543 | Anthony Liguori | #include <stdlib.h> |
20 | d1aaf543 | Anthony Liguori | #include <unistd.h> |
21 | d1aaf543 | Anthony Liguori | |
22 | d1aaf543 | Anthony Liguori | static uint8_t base = 0x70; |
23 | d1aaf543 | Anthony Liguori | |
24 | d1aaf543 | Anthony Liguori | static int bcd2dec(int value) |
25 | d1aaf543 | Anthony Liguori | { |
26 | d1aaf543 | Anthony Liguori | return (((value >> 4) & 0x0F) * 10) + (value & 0x0F); |
27 | d1aaf543 | Anthony Liguori | } |
28 | d1aaf543 | Anthony Liguori | |
29 | d1aaf543 | Anthony Liguori | static uint8_t cmos_read(uint8_t reg)
|
30 | d1aaf543 | Anthony Liguori | { |
31 | d1aaf543 | Anthony Liguori | outb(base + 0, reg);
|
32 | d1aaf543 | Anthony Liguori | return inb(base + 1); |
33 | d1aaf543 | Anthony Liguori | } |
34 | d1aaf543 | Anthony Liguori | |
35 | d1aaf543 | Anthony Liguori | static void cmos_write(uint8_t reg, uint8_t val) |
36 | d1aaf543 | Anthony Liguori | { |
37 | d1aaf543 | Anthony Liguori | outb(base + 0, reg);
|
38 | d1aaf543 | Anthony Liguori | outb(base + 1, val);
|
39 | d1aaf543 | Anthony Liguori | } |
40 | d1aaf543 | Anthony Liguori | |
41 | d1aaf543 | Anthony Liguori | static int tm_cmp(struct tm *lhs, struct tm *rhs) |
42 | d1aaf543 | Anthony Liguori | { |
43 | d1aaf543 | Anthony Liguori | time_t a, b; |
44 | d1aaf543 | Anthony Liguori | struct tm d1, d2;
|
45 | d1aaf543 | Anthony Liguori | |
46 | d1aaf543 | Anthony Liguori | memcpy(&d1, lhs, sizeof(d1));
|
47 | d1aaf543 | Anthony Liguori | memcpy(&d2, rhs, sizeof(d2));
|
48 | d1aaf543 | Anthony Liguori | |
49 | d1aaf543 | Anthony Liguori | a = mktime(&d1); |
50 | d1aaf543 | Anthony Liguori | b = mktime(&d2); |
51 | d1aaf543 | Anthony Liguori | |
52 | d1aaf543 | Anthony Liguori | if (a < b) {
|
53 | d1aaf543 | Anthony Liguori | return -1; |
54 | d1aaf543 | Anthony Liguori | } else if (a > b) { |
55 | d1aaf543 | Anthony Liguori | return 1; |
56 | d1aaf543 | Anthony Liguori | } |
57 | d1aaf543 | Anthony Liguori | |
58 | d1aaf543 | Anthony Liguori | return 0; |
59 | d1aaf543 | Anthony Liguori | } |
60 | d1aaf543 | Anthony Liguori | |
61 | d1aaf543 | Anthony Liguori | #if 0
|
62 | d1aaf543 | Anthony Liguori | static void print_tm(struct tm *tm)
|
63 | d1aaf543 | Anthony Liguori | {
|
64 | d1aaf543 | Anthony Liguori | printf("%04d-%02d-%02d %02d:%02d:%02d\n",
|
65 | d1aaf543 | Anthony Liguori | tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
66 | d1aaf543 | Anthony Liguori | tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_gmtoff);
|
67 | d1aaf543 | Anthony Liguori | }
|
68 | d1aaf543 | Anthony Liguori | #endif
|
69 | d1aaf543 | Anthony Liguori | |
70 | d1aaf543 | Anthony Liguori | static void cmos_get_date_time(struct tm *date) |
71 | d1aaf543 | Anthony Liguori | { |
72 | d1aaf543 | Anthony Liguori | int base_year = 2000, hour_offset; |
73 | d1aaf543 | Anthony Liguori | int sec, min, hour, mday, mon, year;
|
74 | d1aaf543 | Anthony Liguori | time_t ts; |
75 | d1aaf543 | Anthony Liguori | struct tm dummy;
|
76 | d1aaf543 | Anthony Liguori | |
77 | d1aaf543 | Anthony Liguori | sec = cmos_read(RTC_SECONDS); |
78 | d1aaf543 | Anthony Liguori | min = cmos_read(RTC_MINUTES); |
79 | d1aaf543 | Anthony Liguori | hour = cmos_read(RTC_HOURS); |
80 | d1aaf543 | Anthony Liguori | mday = cmos_read(RTC_DAY_OF_MONTH); |
81 | d1aaf543 | Anthony Liguori | mon = cmos_read(RTC_MONTH); |
82 | d1aaf543 | Anthony Liguori | year = cmos_read(RTC_YEAR); |
83 | d1aaf543 | Anthony Liguori | |
84 | d1aaf543 | Anthony Liguori | if ((cmos_read(RTC_REG_B) & REG_B_DM) == 0) { |
85 | d1aaf543 | Anthony Liguori | sec = bcd2dec(sec); |
86 | d1aaf543 | Anthony Liguori | min = bcd2dec(min); |
87 | d1aaf543 | Anthony Liguori | hour = bcd2dec(hour); |
88 | d1aaf543 | Anthony Liguori | mday = bcd2dec(mday); |
89 | d1aaf543 | Anthony Liguori | mon = bcd2dec(mon); |
90 | d1aaf543 | Anthony Liguori | year = bcd2dec(year); |
91 | d1aaf543 | Anthony Liguori | hour_offset = 80;
|
92 | d1aaf543 | Anthony Liguori | } else {
|
93 | d1aaf543 | Anthony Liguori | hour_offset = 0x80;
|
94 | d1aaf543 | Anthony Liguori | } |
95 | d1aaf543 | Anthony Liguori | |
96 | d1aaf543 | Anthony Liguori | if ((cmos_read(0x0B) & REG_B_24H) == 0) { |
97 | d1aaf543 | Anthony Liguori | if (hour >= hour_offset) {
|
98 | d1aaf543 | Anthony Liguori | hour -= hour_offset; |
99 | d1aaf543 | Anthony Liguori | hour += 12;
|
100 | d1aaf543 | Anthony Liguori | } |
101 | d1aaf543 | Anthony Liguori | } |
102 | d1aaf543 | Anthony Liguori | |
103 | d1aaf543 | Anthony Liguori | ts = time(NULL);
|
104 | d1aaf543 | Anthony Liguori | localtime_r(&ts, &dummy); |
105 | d1aaf543 | Anthony Liguori | |
106 | d1aaf543 | Anthony Liguori | date->tm_isdst = dummy.tm_isdst; |
107 | d1aaf543 | Anthony Liguori | date->tm_sec = sec; |
108 | d1aaf543 | Anthony Liguori | date->tm_min = min; |
109 | d1aaf543 | Anthony Liguori | date->tm_hour = hour; |
110 | d1aaf543 | Anthony Liguori | date->tm_mday = mday; |
111 | d1aaf543 | Anthony Liguori | date->tm_mon = mon - 1;
|
112 | d1aaf543 | Anthony Liguori | date->tm_year = base_year + year - 1900;
|
113 | a05ddd92 | Andreas Färber | #ifndef __sun__
|
114 | d1aaf543 | Anthony Liguori | date->tm_gmtoff = 0;
|
115 | a05ddd92 | Andreas Färber | #endif
|
116 | d1aaf543 | Anthony Liguori | |
117 | d1aaf543 | Anthony Liguori | ts = mktime(date); |
118 | d1aaf543 | Anthony Liguori | } |
119 | d1aaf543 | Anthony Liguori | |
120 | d1aaf543 | Anthony Liguori | static void check_time(int wiggle) |
121 | d1aaf543 | Anthony Liguori | { |
122 | d1aaf543 | Anthony Liguori | struct tm start, date[4], end; |
123 | d1aaf543 | Anthony Liguori | struct tm *datep;
|
124 | d1aaf543 | Anthony Liguori | time_t ts; |
125 | d1aaf543 | Anthony Liguori | |
126 | d1aaf543 | Anthony Liguori | /*
|
127 | d1aaf543 | Anthony Liguori | * This check assumes a few things. First, we cannot guarantee that we get
|
128 | d1aaf543 | Anthony Liguori | * a consistent reading from the wall clock because we may hit an edge of
|
129 | d1aaf543 | Anthony Liguori | * the clock while reading. To work around this, we read four clock readings
|
130 | d1aaf543 | Anthony Liguori | * such that at least two of them should match. We need to assume that one
|
131 | d1aaf543 | Anthony Liguori | * reading is corrupt so we need four readings to ensure that we have at
|
132 | d1aaf543 | Anthony Liguori | * least two consecutive identical readings
|
133 | d1aaf543 | Anthony Liguori | *
|
134 | d1aaf543 | Anthony Liguori | * It's also possible that we'll cross an edge reading the host clock so
|
135 | d1aaf543 | Anthony Liguori | * simply check to make sure that the clock reading is within the period of
|
136 | d1aaf543 | Anthony Liguori | * when we expect it to be.
|
137 | d1aaf543 | Anthony Liguori | */
|
138 | d1aaf543 | Anthony Liguori | |
139 | d1aaf543 | Anthony Liguori | ts = time(NULL);
|
140 | d1aaf543 | Anthony Liguori | gmtime_r(&ts, &start); |
141 | d1aaf543 | Anthony Liguori | |
142 | d1aaf543 | Anthony Liguori | cmos_get_date_time(&date[0]);
|
143 | d1aaf543 | Anthony Liguori | cmos_get_date_time(&date[1]);
|
144 | d1aaf543 | Anthony Liguori | cmos_get_date_time(&date[2]);
|
145 | d1aaf543 | Anthony Liguori | cmos_get_date_time(&date[3]);
|
146 | d1aaf543 | Anthony Liguori | |
147 | d1aaf543 | Anthony Liguori | ts = time(NULL);
|
148 | d1aaf543 | Anthony Liguori | gmtime_r(&ts, &end); |
149 | d1aaf543 | Anthony Liguori | |
150 | d1aaf543 | Anthony Liguori | if (tm_cmp(&date[0], &date[1]) == 0) { |
151 | d1aaf543 | Anthony Liguori | datep = &date[0];
|
152 | d1aaf543 | Anthony Liguori | } else if (tm_cmp(&date[1], &date[2]) == 0) { |
153 | d1aaf543 | Anthony Liguori | datep = &date[1];
|
154 | d1aaf543 | Anthony Liguori | } else if (tm_cmp(&date[2], &date[3]) == 0) { |
155 | d1aaf543 | Anthony Liguori | datep = &date[2];
|
156 | d1aaf543 | Anthony Liguori | } else {
|
157 | d1aaf543 | Anthony Liguori | g_assert_not_reached(); |
158 | d1aaf543 | Anthony Liguori | } |
159 | d1aaf543 | Anthony Liguori | |
160 | d1aaf543 | Anthony Liguori | if (!(tm_cmp(&start, datep) <= 0 && tm_cmp(datep, &end) <= 0)) { |
161 | 02b3efcb | Blue Swirl | long t, s;
|
162 | d1aaf543 | Anthony Liguori | |
163 | d1aaf543 | Anthony Liguori | start.tm_isdst = datep->tm_isdst; |
164 | d1aaf543 | Anthony Liguori | |
165 | 02b3efcb | Blue Swirl | t = (long)mktime(datep);
|
166 | 02b3efcb | Blue Swirl | s = (long)mktime(&start);
|
167 | d1aaf543 | Anthony Liguori | if (t < s) {
|
168 | d1aaf543 | Anthony Liguori | g_test_message("RTC is %ld second(s) behind wall-clock\n", (s - t));
|
169 | d1aaf543 | Anthony Liguori | } else {
|
170 | d1aaf543 | Anthony Liguori | g_test_message("RTC is %ld second(s) ahead of wall-clock\n", (t - s));
|
171 | d1aaf543 | Anthony Liguori | } |
172 | d1aaf543 | Anthony Liguori | |
173 | d1aaf543 | Anthony Liguori | g_assert_cmpint(ABS(t - s), <=, wiggle); |
174 | d1aaf543 | Anthony Liguori | } |
175 | d1aaf543 | Anthony Liguori | } |
176 | d1aaf543 | Anthony Liguori | |
177 | d1aaf543 | Anthony Liguori | static int wiggle = 2; |
178 | d1aaf543 | Anthony Liguori | |
179 | b8994faf | Paolo Bonzini | static void set_year_20xx(void) |
180 | b6db4aca | Paolo Bonzini | { |
181 | b6db4aca | Paolo Bonzini | /* Set BCD mode */
|
182 | f9b3ed40 | Paolo Bonzini | cmos_write(RTC_REG_B, REG_B_24H); |
183 | b6db4aca | Paolo Bonzini | cmos_write(RTC_REG_A, 0x76);
|
184 | b6db4aca | Paolo Bonzini | cmos_write(RTC_YEAR, 0x11);
|
185 | b8994faf | Paolo Bonzini | cmos_write(RTC_CENTURY, 0x20);
|
186 | b6db4aca | Paolo Bonzini | cmos_write(RTC_MONTH, 0x02);
|
187 | b6db4aca | Paolo Bonzini | cmos_write(RTC_DAY_OF_MONTH, 0x02);
|
188 | b6db4aca | Paolo Bonzini | cmos_write(RTC_HOURS, 0x02);
|
189 | b6db4aca | Paolo Bonzini | cmos_write(RTC_MINUTES, 0x04);
|
190 | b6db4aca | Paolo Bonzini | cmos_write(RTC_SECONDS, 0x58);
|
191 | b6db4aca | Paolo Bonzini | cmos_write(RTC_REG_A, 0x26);
|
192 | b6db4aca | Paolo Bonzini | |
193 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02);
|
194 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04);
|
195 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58);
|
196 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02);
|
197 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02);
|
198 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11);
|
199 | b8994faf | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20);
|
200 | b6db4aca | Paolo Bonzini | |
201 | 4e45deed | Gerd Hoffmann | if (sizeof(time_t) == 4) { |
202 | 4e45deed | Gerd Hoffmann | return;
|
203 | 4e45deed | Gerd Hoffmann | } |
204 | 4e45deed | Gerd Hoffmann | |
205 | b6db4aca | Paolo Bonzini | /* Set a date in 2080 to ensure there is no year-2038 overflow. */
|
206 | b6db4aca | Paolo Bonzini | cmos_write(RTC_REG_A, 0x76);
|
207 | b6db4aca | Paolo Bonzini | cmos_write(RTC_YEAR, 0x80);
|
208 | b6db4aca | Paolo Bonzini | cmos_write(RTC_REG_A, 0x26);
|
209 | b6db4aca | Paolo Bonzini | |
210 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02);
|
211 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04);
|
212 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58);
|
213 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02);
|
214 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02);
|
215 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x80);
|
216 | b8994faf | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20);
|
217 | b6db4aca | Paolo Bonzini | |
218 | b6db4aca | Paolo Bonzini | cmos_write(RTC_REG_A, 0x76);
|
219 | b6db4aca | Paolo Bonzini | cmos_write(RTC_YEAR, 0x11);
|
220 | b6db4aca | Paolo Bonzini | cmos_write(RTC_REG_A, 0x26);
|
221 | b6db4aca | Paolo Bonzini | |
222 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02);
|
223 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04);
|
224 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58);
|
225 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02);
|
226 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02);
|
227 | b6db4aca | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11);
|
228 | b8994faf | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20);
|
229 | b8994faf | Paolo Bonzini | } |
230 | b8994faf | Paolo Bonzini | |
231 | b8994faf | Paolo Bonzini | static void set_year_1980(void) |
232 | b8994faf | Paolo Bonzini | { |
233 | b8994faf | Paolo Bonzini | /* Set BCD mode */
|
234 | f9b3ed40 | Paolo Bonzini | cmos_write(RTC_REG_B, REG_B_24H); |
235 | b8994faf | Paolo Bonzini | cmos_write(RTC_REG_A, 0x76);
|
236 | b8994faf | Paolo Bonzini | cmos_write(RTC_YEAR, 0x80);
|
237 | b8994faf | Paolo Bonzini | cmos_write(RTC_CENTURY, 0x19);
|
238 | b8994faf | Paolo Bonzini | cmos_write(RTC_MONTH, 0x02);
|
239 | b8994faf | Paolo Bonzini | cmos_write(RTC_DAY_OF_MONTH, 0x02);
|
240 | b8994faf | Paolo Bonzini | cmos_write(RTC_HOURS, 0x02);
|
241 | b8994faf | Paolo Bonzini | cmos_write(RTC_MINUTES, 0x04);
|
242 | b8994faf | Paolo Bonzini | cmos_write(RTC_SECONDS, 0x58);
|
243 | b8994faf | Paolo Bonzini | cmos_write(RTC_REG_A, 0x26);
|
244 | b8994faf | Paolo Bonzini | |
245 | b8994faf | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02);
|
246 | b8994faf | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04);
|
247 | b8994faf | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58);
|
248 | b8994faf | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02);
|
249 | b8994faf | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02);
|
250 | b8994faf | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x80);
|
251 | b8994faf | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x19);
|
252 | b6db4aca | Paolo Bonzini | } |
253 | b6db4aca | Paolo Bonzini | |
254 | d1aaf543 | Anthony Liguori | static void bcd_check_time(void) |
255 | d1aaf543 | Anthony Liguori | { |
256 | d1aaf543 | Anthony Liguori | /* Set BCD mode */
|
257 | f9b3ed40 | Paolo Bonzini | cmos_write(RTC_REG_B, REG_B_24H); |
258 | d1aaf543 | Anthony Liguori | check_time(wiggle); |
259 | d1aaf543 | Anthony Liguori | } |
260 | d1aaf543 | Anthony Liguori | |
261 | d1aaf543 | Anthony Liguori | static void dec_check_time(void) |
262 | d1aaf543 | Anthony Liguori | { |
263 | d1aaf543 | Anthony Liguori | /* Set DEC mode */
|
264 | f9b3ed40 | Paolo Bonzini | cmos_write(RTC_REG_B, REG_B_24H | REG_B_DM); |
265 | d1aaf543 | Anthony Liguori | check_time(wiggle); |
266 | d1aaf543 | Anthony Liguori | } |
267 | d1aaf543 | Anthony Liguori | |
268 | d1aaf543 | Anthony Liguori | static void alarm_time(void) |
269 | d1aaf543 | Anthony Liguori | { |
270 | d1aaf543 | Anthony Liguori | struct tm now;
|
271 | d1aaf543 | Anthony Liguori | time_t ts; |
272 | d1aaf543 | Anthony Liguori | int i;
|
273 | d1aaf543 | Anthony Liguori | |
274 | d1aaf543 | Anthony Liguori | ts = time(NULL);
|
275 | d1aaf543 | Anthony Liguori | gmtime_r(&ts, &now); |
276 | d1aaf543 | Anthony Liguori | |
277 | d1aaf543 | Anthony Liguori | /* set DEC mode */
|
278 | f9b3ed40 | Paolo Bonzini | cmos_write(RTC_REG_B, REG_B_24H | REG_B_DM); |
279 | d1aaf543 | Anthony Liguori | |
280 | d1aaf543 | Anthony Liguori | g_assert(!get_irq(RTC_ISA_IRQ)); |
281 | d1aaf543 | Anthony Liguori | cmos_read(RTC_REG_C); |
282 | d1aaf543 | Anthony Liguori | |
283 | d1aaf543 | Anthony Liguori | now.tm_sec = (now.tm_sec + 2) % 60; |
284 | f9b3ed40 | Paolo Bonzini | cmos_write(RTC_SECONDS_ALARM, now.tm_sec); |
285 | f9b3ed40 | Paolo Bonzini | cmos_write(RTC_MINUTES_ALARM, RTC_ALARM_DONT_CARE); |
286 | f9b3ed40 | Paolo Bonzini | cmos_write(RTC_HOURS_ALARM, RTC_ALARM_DONT_CARE); |
287 | d1aaf543 | Anthony Liguori | cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) | REG_B_AIE); |
288 | d1aaf543 | Anthony Liguori | |
289 | d1aaf543 | Anthony Liguori | for (i = 0; i < 2 + wiggle; i++) { |
290 | d1aaf543 | Anthony Liguori | if (get_irq(RTC_ISA_IRQ)) {
|
291 | d1aaf543 | Anthony Liguori | break;
|
292 | d1aaf543 | Anthony Liguori | } |
293 | d1aaf543 | Anthony Liguori | |
294 | d1aaf543 | Anthony Liguori | clock_step(1000000000);
|
295 | d1aaf543 | Anthony Liguori | } |
296 | d1aaf543 | Anthony Liguori | |
297 | d1aaf543 | Anthony Liguori | g_assert(get_irq(RTC_ISA_IRQ)); |
298 | d1aaf543 | Anthony Liguori | g_assert((cmos_read(RTC_REG_C) & REG_C_AF) != 0);
|
299 | d1aaf543 | Anthony Liguori | g_assert(cmos_read(RTC_REG_C) == 0);
|
300 | d1aaf543 | Anthony Liguori | } |
301 | d1aaf543 | Anthony Liguori | |
302 | cc2832a5 | Paolo Bonzini | static void set_time(int mode, int h, int m, int s) |
303 | cc2832a5 | Paolo Bonzini | { |
304 | cc2832a5 | Paolo Bonzini | /* set BCD 12 hour mode */
|
305 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_REG_B, mode); |
306 | cc2832a5 | Paolo Bonzini | |
307 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_REG_A, 0x76);
|
308 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_HOURS, h); |
309 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_MINUTES, m); |
310 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_SECONDS, s); |
311 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_REG_A, 0x26);
|
312 | cc2832a5 | Paolo Bonzini | } |
313 | cc2832a5 | Paolo Bonzini | |
314 | cc2832a5 | Paolo Bonzini | #define assert_time(h, m, s) \
|
315 | cc2832a5 | Paolo Bonzini | do { \
|
316 | cc2832a5 | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_HOURS), ==, h); \ |
317 | cc2832a5 | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_MINUTES), ==, m); \ |
318 | cc2832a5 | Paolo Bonzini | g_assert_cmpint(cmos_read(RTC_SECONDS), ==, s); \ |
319 | cc2832a5 | Paolo Bonzini | } while(0) |
320 | cc2832a5 | Paolo Bonzini | |
321 | cc2832a5 | Paolo Bonzini | static void basic_12h_bcd(void) |
322 | cc2832a5 | Paolo Bonzini | { |
323 | cc2832a5 | Paolo Bonzini | /* set BCD 12 hour mode */
|
324 | cc2832a5 | Paolo Bonzini | set_time(0, 0x81, 0x59, 0x00); |
325 | cc2832a5 | Paolo Bonzini | clock_step(1000000000LL);
|
326 | cc2832a5 | Paolo Bonzini | assert_time(0x81, 0x59, 0x01); |
327 | cc2832a5 | Paolo Bonzini | clock_step(59000000000LL);
|
328 | cc2832a5 | Paolo Bonzini | assert_time(0x82, 0x00, 0x00); |
329 | cc2832a5 | Paolo Bonzini | |
330 | cc2832a5 | Paolo Bonzini | /* test BCD wraparound */
|
331 | cc2832a5 | Paolo Bonzini | set_time(0, 0x09, 0x59, 0x59); |
332 | cc2832a5 | Paolo Bonzini | clock_step(60000000000LL);
|
333 | cc2832a5 | Paolo Bonzini | assert_time(0x10, 0x00, 0x59); |
334 | cc2832a5 | Paolo Bonzini | |
335 | cc2832a5 | Paolo Bonzini | /* 12 AM -> 1 AM */
|
336 | cc2832a5 | Paolo Bonzini | set_time(0, 0x12, 0x59, 0x59); |
337 | cc2832a5 | Paolo Bonzini | clock_step(1000000000LL);
|
338 | cc2832a5 | Paolo Bonzini | assert_time(0x01, 0x00, 0x00); |
339 | cc2832a5 | Paolo Bonzini | |
340 | cc2832a5 | Paolo Bonzini | /* 12 PM -> 1 PM */
|
341 | cc2832a5 | Paolo Bonzini | set_time(0, 0x92, 0x59, 0x59); |
342 | cc2832a5 | Paolo Bonzini | clock_step(1000000000LL);
|
343 | cc2832a5 | Paolo Bonzini | assert_time(0x81, 0x00, 0x00); |
344 | cc2832a5 | Paolo Bonzini | |
345 | cc2832a5 | Paolo Bonzini | /* 11 AM -> 12 PM */
|
346 | cc2832a5 | Paolo Bonzini | set_time(0, 0x11, 0x59, 0x59); |
347 | cc2832a5 | Paolo Bonzini | clock_step(1000000000LL);
|
348 | cc2832a5 | Paolo Bonzini | assert_time(0x92, 0x00, 0x00); |
349 | cc2832a5 | Paolo Bonzini | /* TODO: test day wraparound */
|
350 | cc2832a5 | Paolo Bonzini | |
351 | cc2832a5 | Paolo Bonzini | /* 11 PM -> 12 AM */
|
352 | cc2832a5 | Paolo Bonzini | set_time(0, 0x91, 0x59, 0x59); |
353 | cc2832a5 | Paolo Bonzini | clock_step(1000000000LL);
|
354 | cc2832a5 | Paolo Bonzini | assert_time(0x12, 0x00, 0x00); |
355 | cc2832a5 | Paolo Bonzini | /* TODO: test day wraparound */
|
356 | cc2832a5 | Paolo Bonzini | } |
357 | cc2832a5 | Paolo Bonzini | |
358 | cc2832a5 | Paolo Bonzini | static void basic_12h_dec(void) |
359 | cc2832a5 | Paolo Bonzini | { |
360 | cc2832a5 | Paolo Bonzini | /* set decimal 12 hour mode */
|
361 | cc2832a5 | Paolo Bonzini | set_time(REG_B_DM, 0x81, 59, 0); |
362 | cc2832a5 | Paolo Bonzini | clock_step(1000000000LL);
|
363 | cc2832a5 | Paolo Bonzini | assert_time(0x81, 59, 1); |
364 | cc2832a5 | Paolo Bonzini | clock_step(59000000000LL);
|
365 | cc2832a5 | Paolo Bonzini | assert_time(0x82, 0, 0); |
366 | cc2832a5 | Paolo Bonzini | |
367 | cc2832a5 | Paolo Bonzini | /* 12 PM -> 1 PM */
|
368 | cc2832a5 | Paolo Bonzini | set_time(REG_B_DM, 0x8c, 59, 59); |
369 | cc2832a5 | Paolo Bonzini | clock_step(1000000000LL);
|
370 | cc2832a5 | Paolo Bonzini | assert_time(0x81, 0, 0); |
371 | cc2832a5 | Paolo Bonzini | |
372 | cc2832a5 | Paolo Bonzini | /* 12 AM -> 1 AM */
|
373 | cc2832a5 | Paolo Bonzini | set_time(REG_B_DM, 0x0c, 59, 59); |
374 | cc2832a5 | Paolo Bonzini | clock_step(1000000000LL);
|
375 | cc2832a5 | Paolo Bonzini | assert_time(0x01, 0, 0); |
376 | cc2832a5 | Paolo Bonzini | |
377 | cc2832a5 | Paolo Bonzini | /* 11 AM -> 12 PM */
|
378 | cc2832a5 | Paolo Bonzini | set_time(REG_B_DM, 0x0b, 59, 59); |
379 | cc2832a5 | Paolo Bonzini | clock_step(1000000000LL);
|
380 | cc2832a5 | Paolo Bonzini | assert_time(0x8c, 0, 0); |
381 | cc2832a5 | Paolo Bonzini | |
382 | cc2832a5 | Paolo Bonzini | /* 11 PM -> 12 AM */
|
383 | cc2832a5 | Paolo Bonzini | set_time(REG_B_DM, 0x8b, 59, 59); |
384 | cc2832a5 | Paolo Bonzini | clock_step(1000000000LL);
|
385 | cc2832a5 | Paolo Bonzini | assert_time(0x0c, 0, 0); |
386 | cc2832a5 | Paolo Bonzini | /* TODO: test day wraparound */
|
387 | cc2832a5 | Paolo Bonzini | } |
388 | cc2832a5 | Paolo Bonzini | |
389 | cc2832a5 | Paolo Bonzini | static void basic_24h_bcd(void) |
390 | cc2832a5 | Paolo Bonzini | { |
391 | cc2832a5 | Paolo Bonzini | /* set BCD 24 hour mode */
|
392 | cc2832a5 | Paolo Bonzini | set_time(REG_B_24H, 0x09, 0x59, 0x00); |
393 | cc2832a5 | Paolo Bonzini | clock_step(1000000000LL);
|
394 | cc2832a5 | Paolo Bonzini | assert_time(0x09, 0x59, 0x01); |
395 | cc2832a5 | Paolo Bonzini | clock_step(59000000000LL);
|
396 | cc2832a5 | Paolo Bonzini | assert_time(0x10, 0x00, 0x00); |
397 | cc2832a5 | Paolo Bonzini | |
398 | cc2832a5 | Paolo Bonzini | /* test BCD wraparound */
|
399 | cc2832a5 | Paolo Bonzini | set_time(REG_B_24H, 0x09, 0x59, 0x00); |
400 | cc2832a5 | Paolo Bonzini | clock_step(60000000000LL);
|
401 | cc2832a5 | Paolo Bonzini | assert_time(0x10, 0x00, 0x00); |
402 | cc2832a5 | Paolo Bonzini | |
403 | cc2832a5 | Paolo Bonzini | /* TODO: test day wraparound */
|
404 | cc2832a5 | Paolo Bonzini | set_time(REG_B_24H, 0x23, 0x59, 0x00); |
405 | cc2832a5 | Paolo Bonzini | clock_step(60000000000LL);
|
406 | cc2832a5 | Paolo Bonzini | assert_time(0x00, 0x00, 0x00); |
407 | cc2832a5 | Paolo Bonzini | } |
408 | cc2832a5 | Paolo Bonzini | |
409 | cc2832a5 | Paolo Bonzini | static void basic_24h_dec(void) |
410 | cc2832a5 | Paolo Bonzini | { |
411 | cc2832a5 | Paolo Bonzini | /* set decimal 24 hour mode */
|
412 | cc2832a5 | Paolo Bonzini | set_time(REG_B_24H | REG_B_DM, 9, 59, 0); |
413 | cc2832a5 | Paolo Bonzini | clock_step(1000000000LL);
|
414 | cc2832a5 | Paolo Bonzini | assert_time(9, 59, 1); |
415 | cc2832a5 | Paolo Bonzini | clock_step(59000000000LL);
|
416 | cc2832a5 | Paolo Bonzini | assert_time(10, 0, 0); |
417 | cc2832a5 | Paolo Bonzini | |
418 | cc2832a5 | Paolo Bonzini | /* test BCD wraparound */
|
419 | cc2832a5 | Paolo Bonzini | set_time(REG_B_24H | REG_B_DM, 9, 59, 0); |
420 | cc2832a5 | Paolo Bonzini | clock_step(60000000000LL);
|
421 | cc2832a5 | Paolo Bonzini | assert_time(10, 0, 0); |
422 | cc2832a5 | Paolo Bonzini | |
423 | cc2832a5 | Paolo Bonzini | /* TODO: test day wraparound */
|
424 | cc2832a5 | Paolo Bonzini | set_time(REG_B_24H | REG_B_DM, 23, 59, 0); |
425 | cc2832a5 | Paolo Bonzini | clock_step(60000000000LL);
|
426 | cc2832a5 | Paolo Bonzini | assert_time(0, 0, 0); |
427 | cc2832a5 | Paolo Bonzini | } |
428 | cc2832a5 | Paolo Bonzini | |
429 | cc2832a5 | Paolo Bonzini | static void am_pm_alarm(void) |
430 | cc2832a5 | Paolo Bonzini | { |
431 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_MINUTES_ALARM, 0xC0);
|
432 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_SECONDS_ALARM, 0xC0);
|
433 | cc2832a5 | Paolo Bonzini | |
434 | cc2832a5 | Paolo Bonzini | /* set BCD 12 hour mode */
|
435 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_REG_B, 0);
|
436 | cc2832a5 | Paolo Bonzini | |
437 | cc2832a5 | Paolo Bonzini | /* Set time and alarm hour. */
|
438 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_REG_A, 0x76);
|
439 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_HOURS_ALARM, 0x82);
|
440 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_HOURS, 0x81);
|
441 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_MINUTES, 0x59);
|
442 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_SECONDS, 0x00);
|
443 | cc2832a5 | Paolo Bonzini | cmos_read(RTC_REG_C); |
444 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_REG_A, 0x26);
|
445 | cc2832a5 | Paolo Bonzini | |
446 | cc2832a5 | Paolo Bonzini | /* Check that alarm triggers when AM/PM is set. */
|
447 | cc2832a5 | Paolo Bonzini | clock_step(60000000000LL);
|
448 | cc2832a5 | Paolo Bonzini | g_assert(cmos_read(RTC_HOURS) == 0x82);
|
449 | cc2832a5 | Paolo Bonzini | g_assert((cmos_read(RTC_REG_C) & REG_C_AF) != 0);
|
450 | cc2832a5 | Paolo Bonzini | |
451 | cc2832a5 | Paolo Bonzini | /*
|
452 | cc2832a5 | Paolo Bonzini | * Each of the following two tests takes over 60 seconds due to the time
|
453 | cc2832a5 | Paolo Bonzini | * needed to report the PIT interrupts. Unfortunately, our PIT device
|
454 | cc2832a5 | Paolo Bonzini | * model keeps counting even when GATE=0, so we cannot simply disable
|
455 | cc2832a5 | Paolo Bonzini | * it in main().
|
456 | cc2832a5 | Paolo Bonzini | */
|
457 | cc2832a5 | Paolo Bonzini | if (g_test_quick()) {
|
458 | cc2832a5 | Paolo Bonzini | return;
|
459 | cc2832a5 | Paolo Bonzini | } |
460 | cc2832a5 | Paolo Bonzini | |
461 | cc2832a5 | Paolo Bonzini | /* set DEC 12 hour mode */
|
462 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_REG_B, REG_B_DM); |
463 | cc2832a5 | Paolo Bonzini | |
464 | cc2832a5 | Paolo Bonzini | /* Set time and alarm hour. */
|
465 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_REG_A, 0x76);
|
466 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_HOURS_ALARM, 0x82);
|
467 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_HOURS, 3);
|
468 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_MINUTES, 0);
|
469 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_SECONDS, 0);
|
470 | cc2832a5 | Paolo Bonzini | cmos_read(RTC_REG_C); |
471 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_REG_A, 0x26);
|
472 | cc2832a5 | Paolo Bonzini | |
473 | cc2832a5 | Paolo Bonzini | /* Check that alarm triggers. */
|
474 | cc2832a5 | Paolo Bonzini | clock_step(3600 * 11 * 1000000000LL); |
475 | cc2832a5 | Paolo Bonzini | g_assert(cmos_read(RTC_HOURS) == 0x82);
|
476 | cc2832a5 | Paolo Bonzini | g_assert((cmos_read(RTC_REG_C) & REG_C_AF) != 0);
|
477 | cc2832a5 | Paolo Bonzini | |
478 | cc2832a5 | Paolo Bonzini | /* Same as above, with inverted HOURS and HOURS_ALARM. */
|
479 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_REG_A, 0x76);
|
480 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_HOURS_ALARM, 2);
|
481 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_HOURS, 3);
|
482 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_MINUTES, 0);
|
483 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_SECONDS, 0);
|
484 | cc2832a5 | Paolo Bonzini | cmos_read(RTC_REG_C); |
485 | cc2832a5 | Paolo Bonzini | cmos_write(RTC_REG_A, 0x26);
|
486 | cc2832a5 | Paolo Bonzini | |
487 | cc2832a5 | Paolo Bonzini | /* Check that alarm does not trigger if hours differ only by AM/PM. */
|
488 | cc2832a5 | Paolo Bonzini | clock_step(3600 * 11 * 1000000000LL); |
489 | cc2832a5 | Paolo Bonzini | g_assert(cmos_read(RTC_HOURS) == 0x82);
|
490 | cc2832a5 | Paolo Bonzini | g_assert((cmos_read(RTC_REG_C) & REG_C_AF) == 0);
|
491 | cc2832a5 | Paolo Bonzini | } |
492 | cc2832a5 | Paolo Bonzini | |
493 | 85215d41 | Blue Swirl | /* success if no crash or abort */
|
494 | 85215d41 | Blue Swirl | static void fuzz_registers(void) |
495 | 85215d41 | Blue Swirl | { |
496 | 85215d41 | Blue Swirl | unsigned int i; |
497 | 85215d41 | Blue Swirl | |
498 | 85215d41 | Blue Swirl | for (i = 0; i < 1000; i++) { |
499 | 85215d41 | Blue Swirl | uint8_t reg, val; |
500 | 85215d41 | Blue Swirl | |
501 | 85215d41 | Blue Swirl | reg = (uint8_t)g_test_rand_int_range(0, 16); |
502 | 85215d41 | Blue Swirl | val = (uint8_t)g_test_rand_int_range(0, 256); |
503 | 85215d41 | Blue Swirl | |
504 | 85215d41 | Blue Swirl | cmos_write(reg, val); |
505 | 85215d41 | Blue Swirl | cmos_read(reg); |
506 | 85215d41 | Blue Swirl | } |
507 | 85215d41 | Blue Swirl | } |
508 | 85215d41 | Blue Swirl | |
509 | 02c6ccc6 | Alex Horn | static void register_b_set_flag(void) |
510 | 02c6ccc6 | Alex Horn | { |
511 | 02c6ccc6 | Alex Horn | /* Enable binary-coded decimal (BCD) mode and SET flag in Register B*/
|
512 | f9b3ed40 | Paolo Bonzini | cmos_write(RTC_REG_B, REG_B_24H | REG_B_SET); |
513 | 02c6ccc6 | Alex Horn | |
514 | 02c6ccc6 | Alex Horn | cmos_write(RTC_REG_A, 0x76);
|
515 | 02c6ccc6 | Alex Horn | cmos_write(RTC_YEAR, 0x11);
|
516 | 02c6ccc6 | Alex Horn | cmos_write(RTC_CENTURY, 0x20);
|
517 | 02c6ccc6 | Alex Horn | cmos_write(RTC_MONTH, 0x02);
|
518 | 02c6ccc6 | Alex Horn | cmos_write(RTC_DAY_OF_MONTH, 0x02);
|
519 | 02c6ccc6 | Alex Horn | cmos_write(RTC_HOURS, 0x02);
|
520 | 02c6ccc6 | Alex Horn | cmos_write(RTC_MINUTES, 0x04);
|
521 | 02c6ccc6 | Alex Horn | cmos_write(RTC_SECONDS, 0x58);
|
522 | 02c6ccc6 | Alex Horn | cmos_write(RTC_REG_A, 0x26);
|
523 | 02c6ccc6 | Alex Horn | |
524 | 02c6ccc6 | Alex Horn | /* Since SET flag is still enabled, these are equality checks. */
|
525 | 02c6ccc6 | Alex Horn | g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02);
|
526 | 02c6ccc6 | Alex Horn | g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04);
|
527 | 02c6ccc6 | Alex Horn | g_assert_cmpint(cmos_read(RTC_SECONDS), ==, 0x58);
|
528 | 02c6ccc6 | Alex Horn | g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02);
|
529 | 02c6ccc6 | Alex Horn | g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02);
|
530 | 02c6ccc6 | Alex Horn | g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11);
|
531 | 02c6ccc6 | Alex Horn | g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20);
|
532 | 02c6ccc6 | Alex Horn | |
533 | 02c6ccc6 | Alex Horn | /* Disable SET flag in Register B */
|
534 | 02c6ccc6 | Alex Horn | cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) & ~REG_B_SET); |
535 | 02c6ccc6 | Alex Horn | |
536 | 02c6ccc6 | Alex Horn | g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02);
|
537 | 02c6ccc6 | Alex Horn | g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04);
|
538 | 02c6ccc6 | Alex Horn | |
539 | 02c6ccc6 | Alex Horn | /* Since SET flag is disabled, this is an inequality check.
|
540 | 02c6ccc6 | Alex Horn | * We (reasonably) assume that no (sexagesimal) overflow occurs. */
|
541 | 02c6ccc6 | Alex Horn | g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58);
|
542 | 02c6ccc6 | Alex Horn | g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02);
|
543 | 02c6ccc6 | Alex Horn | g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02);
|
544 | 02c6ccc6 | Alex Horn | g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11);
|
545 | 02c6ccc6 | Alex Horn | g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20);
|
546 | 02c6ccc6 | Alex Horn | } |
547 | 02c6ccc6 | Alex Horn | |
548 | d1aaf543 | Anthony Liguori | int main(int argc, char **argv) |
549 | d1aaf543 | Anthony Liguori | { |
550 | d1aaf543 | Anthony Liguori | QTestState *s = NULL;
|
551 | d1aaf543 | Anthony Liguori | int ret;
|
552 | d1aaf543 | Anthony Liguori | |
553 | d1aaf543 | Anthony Liguori | g_test_init(&argc, &argv, NULL);
|
554 | d1aaf543 | Anthony Liguori | |
555 | d1aaf543 | Anthony Liguori | s = qtest_start("-display none -rtc clock=vm");
|
556 | d1aaf543 | Anthony Liguori | qtest_irq_intercept_in(s, "ioapic");
|
557 | d1aaf543 | Anthony Liguori | |
558 | cc2832a5 | Paolo Bonzini | qtest_add_func("/rtc/check-time/bcd", bcd_check_time);
|
559 | cc2832a5 | Paolo Bonzini | qtest_add_func("/rtc/check-time/dec", dec_check_time);
|
560 | cc2832a5 | Paolo Bonzini | qtest_add_func("/rtc/alarm/interrupt", alarm_time);
|
561 | cc2832a5 | Paolo Bonzini | qtest_add_func("/rtc/alarm/am-pm", am_pm_alarm);
|
562 | cc2832a5 | Paolo Bonzini | qtest_add_func("/rtc/basic/dec-24h", basic_24h_dec);
|
563 | cc2832a5 | Paolo Bonzini | qtest_add_func("/rtc/basic/bcd-24h", basic_24h_bcd);
|
564 | cc2832a5 | Paolo Bonzini | qtest_add_func("/rtc/basic/dec-12h", basic_12h_dec);
|
565 | cc2832a5 | Paolo Bonzini | qtest_add_func("/rtc/basic/bcd-12h", basic_12h_bcd);
|
566 | b8994faf | Paolo Bonzini | qtest_add_func("/rtc/set-year/20xx", set_year_20xx);
|
567 | b8994faf | Paolo Bonzini | qtest_add_func("/rtc/set-year/1980", set_year_1980);
|
568 | eeb29fb9 | Cole Robinson | qtest_add_func("/rtc/misc/register_b_set_flag", register_b_set_flag);
|
569 | eeb29fb9 | Cole Robinson | qtest_add_func("/rtc/misc/fuzz-registers", fuzz_registers);
|
570 | d1aaf543 | Anthony Liguori | ret = g_test_run(); |
571 | d1aaf543 | Anthony Liguori | |
572 | d1aaf543 | Anthony Liguori | if (s) {
|
573 | d1aaf543 | Anthony Liguori | qtest_quit(s); |
574 | d1aaf543 | Anthony Liguori | } |
575 | d1aaf543 | Anthony Liguori | |
576 | d1aaf543 | Anthony Liguori | return ret;
|
577 | d1aaf543 | Anthony Liguori | } |