17
17
#include "qemu/timer.h"
18
18
#include "hw/timer/mc146818rtc_regs.h"
19
19
20
+ #define UIP_HOLD_LENGTH (8 * NANOSECONDS_PER_SECOND / 32768)
21
+
20
22
static uint8_t base = 0x70 ;
21
23
22
24
static int bcd2dec (int value )
@@ -297,16 +299,30 @@ static void alarm_time(void)
297
299
g_assert (cmos_read (RTC_REG_C ) == 0 );
298
300
}
299
301
302
+ static void set_time_regs (int h , int m , int s )
303
+ {
304
+ cmos_write (RTC_HOURS , h );
305
+ cmos_write (RTC_MINUTES , m );
306
+ cmos_write (RTC_SECONDS , s );
307
+ }
308
+
300
309
static void set_time (int mode , int h , int m , int s )
301
310
{
302
- /* set BCD 12 hour mode */
303
311
cmos_write (RTC_REG_B , mode );
304
-
305
312
cmos_write (RTC_REG_A , 0x76 );
313
+ set_time_regs (h , m , s );
314
+ cmos_write (RTC_REG_A , 0x26 );
315
+ }
316
+
317
+ static void set_datetime_bcd (int h , int min , int s , int d , int m , int y )
318
+ {
306
319
cmos_write (RTC_HOURS , h );
307
- cmos_write (RTC_MINUTES , m );
320
+ cmos_write (RTC_MINUTES , min );
308
321
cmos_write (RTC_SECONDS , s );
309
- cmos_write (RTC_REG_A , 0x26 );
322
+ cmos_write (RTC_YEAR , y & 0xFF );
323
+ cmos_write (RTC_CENTURY , y >> 8 );
324
+ cmos_write (RTC_MONTH , m );
325
+ cmos_write (RTC_DAY_OF_MONTH , d );
310
326
}
311
327
312
328
#define assert_time (h , m , s ) \
@@ -316,6 +332,17 @@ static void set_time(int mode, int h, int m, int s)
316
332
g_assert_cmpint(cmos_read(RTC_SECONDS), ==, s); \
317
333
} while(0)
318
334
335
+ #define assert_datetime_bcd (h , min , s , d , m , y ) \
336
+ do { \
337
+ g_assert_cmpint(cmos_read(RTC_HOURS), ==, h); \
338
+ g_assert_cmpint(cmos_read(RTC_MINUTES), ==, min); \
339
+ g_assert_cmpint(cmos_read(RTC_SECONDS), ==, s); \
340
+ g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, d); \
341
+ g_assert_cmpint(cmos_read(RTC_MONTH), ==, m); \
342
+ g_assert_cmpint(cmos_read(RTC_YEAR), ==, (y & 0xFF)); \
343
+ g_assert_cmpint(cmos_read(RTC_CENTURY), ==, (y >> 8)); \
344
+ } while(0)
345
+
319
346
static void basic_12h_bcd (void )
320
347
{
321
348
/* set BCD 12 hour mode */
@@ -506,41 +533,30 @@ static void fuzz_registers(void)
506
533
507
534
static void register_b_set_flag (void )
508
535
{
536
+ if (cmos_read (RTC_REG_A ) & REG_A_UIP ) {
537
+ clock_step (UIP_HOLD_LENGTH + NANOSECONDS_PER_SECOND / 5 );
538
+ }
539
+ g_assert_cmpint (cmos_read (RTC_REG_A ) & REG_A_UIP , = = , 0 );
540
+
509
541
/* Enable binary-coded decimal (BCD) mode and SET flag in Register B*/
510
542
cmos_write (RTC_REG_B , REG_B_24H | REG_B_SET );
511
543
512
- cmos_write (RTC_REG_A , 0x76 );
513
- cmos_write (RTC_YEAR , 0x11 );
514
- cmos_write (RTC_CENTURY , 0x20 );
515
- cmos_write (RTC_MONTH , 0x02 );
516
- cmos_write (RTC_DAY_OF_MONTH , 0x02 );
517
- cmos_write (RTC_HOURS , 0x02 );
518
- cmos_write (RTC_MINUTES , 0x04 );
519
- cmos_write (RTC_SECONDS , 0x58 );
520
- cmos_write (RTC_REG_A , 0x26 );
544
+ set_datetime_bcd (0x02 , 0x04 , 0x58 , 0x02 , 0x02 , 0x2011 );
521
545
522
- /* Since SET flag is still enabled, these are equality checks. */
523
- g_assert_cmpint (cmos_read (RTC_HOURS ), = = , 0x02 );
524
- g_assert_cmpint (cmos_read (RTC_MINUTES ), = = , 0x04 );
525
- g_assert_cmpint (cmos_read (RTC_SECONDS ), = = , 0x58 );
526
- g_assert_cmpint (cmos_read (RTC_DAY_OF_MONTH ), = = , 0x02 );
527
- g_assert_cmpint (cmos_read (RTC_MONTH ), = = , 0x02 );
528
- g_assert_cmpint (cmos_read (RTC_YEAR ), = = , 0x11 );
529
- g_assert_cmpint (cmos_read (RTC_CENTURY ), = = , 0x20 );
546
+ assert_datetime_bcd (0x02 , 0x04 , 0x58 , 0x02 , 0x02 , 0x2011 );
547
+
548
+ /* Since SET flag is still enabled, time does not advance. */
549
+ clock_step (1000000000LL );
550
+ assert_datetime_bcd (0x02 , 0x04 , 0x58 , 0x02 , 0x02 , 0x2011 );
530
551
531
552
/* Disable SET flag in Register B */
532
553
cmos_write (RTC_REG_B , cmos_read (RTC_REG_B ) & ~REG_B_SET );
533
554
534
- g_assert_cmpint (cmos_read (RTC_HOURS ), = = , 0x02 );
535
- g_assert_cmpint (cmos_read (RTC_MINUTES ), = = , 0x04 );
555
+ assert_datetime_bcd (0x02 , 0x04 , 0x58 , 0x02 , 0x02 , 0x2011 );
536
556
537
- /* Since SET flag is disabled, this is an inequality check.
538
- * We (reasonably) assume that no (sexagesimal) overflow occurs. */
539
- g_assert_cmpint (cmos_read (RTC_SECONDS ), >=, 0x58 );
540
- g_assert_cmpint (cmos_read (RTC_DAY_OF_MONTH ), = = , 0x02 );
541
- g_assert_cmpint (cmos_read (RTC_MONTH ), = = , 0x02 );
542
- g_assert_cmpint (cmos_read (RTC_YEAR ), = = , 0x11 );
543
- g_assert_cmpint (cmos_read (RTC_CENTURY ), = = , 0x20 );
557
+ /* Since SET flag is disabled, the clock now advances. */
558
+ clock_step (1000000000LL );
559
+ assert_datetime_bcd (0x02 , 0x04 , 0x59 , 0x02 , 0x02 , 0x2011 );
544
560
}
545
561
546
562
#define RTC_PERIOD_CODE1 13 /* 8 Hz */
0 commit comments