Clock cleanups.
authorKevin O'Connor <kevin@koconnor.net>
Sun, 15 Feb 2009 18:02:56 +0000 (13:02 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Sun, 15 Feb 2009 18:02:56 +0000 (13:02 -0500)
Reset the RTC registers at boot time.
Add definitions for the RTC register bits and use consistently.
Don't use CMOS_CENTURY value on coreboot.
Minor - when waiting on the TSC wait until counter is greater than
    desired value (not greater than or equal).

src/ata.c
src/clock.c
src/ps2port.c

index 968add886511987c12e9422a2691269ed4f809ca..a28332857560865345958e197b923d623e9ba256 100644 (file)
--- a/src/ata.c
+++ b/src/ata.c
@@ -46,7 +46,7 @@ await_ide(u8 mask, u8 flags, u16 base, u16 timeout)
         u8 status = inb(base+ATA_CB_STAT);
         if ((status & mask) == flags)
             return status;
-        if (rdtscll() >= end) {
+        if (rdtscll() > end) {
             dprintf(1, "IDE time out\n");
             return -1;
         }
@@ -116,7 +116,7 @@ ata_reset(int driveid)
             if (inb(iobase1 + ATA_CB_DH) == ATA_CB_DH_DEV1)
                 break;
             // Change drive request failed to take effect - retry.
-            if (rdtscll() >= end) {
+            if (rdtscll() > end) {
                 dprintf(1, "ata_reset slave time out\n");
                 goto done;
             }
index b27417837c8a18651bc473769f0097522c940c22..e0f7dd226715a2b013510004701a27c85b630a5d 100644 (file)
 
 // RTC register flags
 #define RTC_A_UIP 0x80
-#define RTC_B_SET 0x80
-#define RTC_B_PIE 0x40
-#define RTC_B_AIE 0x20
-#define RTC_B_UIE 0x10
+
+#define RTC_B_SET  0x80
+#define RTC_B_PIE  0x40
+#define RTC_B_AIE  0x20
+#define RTC_B_UIE  0x10
+#define RTC_B_BIN  0x04
+#define RTC_B_24HR 0x02
+#define RTC_B_DSE  0x01
+
 
 // Bits for PORT_PS2_CTRLB
 #define PPCB_T2GATE (1<<0)
@@ -89,7 +94,7 @@ tscsleep(u64 diff)
 {
     u64 start = rdtscll();
     u64 end = start + diff;
-    while (rdtscll() < end)
+    while (rdtscll() <= end)
         cpu_relax();
 }
 
@@ -136,11 +141,11 @@ rtc_updating()
     // that this bit should be set is constrained to 244useconds, so
     // we wait for 1 msec max.
 
-    if ((inb_cmos(CMOS_STATUS_A) & 0x80) == 0)
+    if ((inb_cmos(CMOS_STATUS_A) & RTC_A_UIP) == 0)
         return 0;
     u64 end = calc_future_tsc(1);
     do {
-        if ((inb_cmos(CMOS_STATUS_A) & 0x80) == 0)
+        if ((inb_cmos(CMOS_STATUS_A) & RTC_A_UIP) == 0)
             return 0;
     } while (rdtscll() <= end);
 
@@ -158,6 +163,16 @@ pit_setup()
     outb(0x0, PORT_PIT_COUNTER0);
 }
 
+static void
+init_rtc()
+{
+    outb_cmos(0x26, CMOS_STATUS_A);       // 976.5625us updates
+    u8 regB = inb_cmos(CMOS_STATUS_B);
+    outb_cmos((regB & RTC_B_DSE) | RTC_B_24HR, CMOS_STATUS_B);
+    inb_cmos(CMOS_STATUS_C);
+    inb_cmos(CMOS_STATUS_D);
+}
+
 static u32
 bcd2bin(u8 val)
 {
@@ -171,6 +186,7 @@ timer_setup()
     calibrate_tsc();
     pit_setup();
 
+    init_rtc();
     rtc_updating();
     u32 seconds = bcd2bin(inb_cmos(CMOS_RTC_SECONDS));
     u32 ticks = (seconds * 18206507) / 1000000;
@@ -185,15 +201,6 @@ timer_setup()
     enable_hwirq(8, entry_70);
 }
 
-static void
-init_rtc()
-{
-    outb_cmos(0x26, CMOS_STATUS_A);
-    outb_cmos(0x02, CMOS_STATUS_B);
-    inb_cmos(CMOS_STATUS_C);
-    inb_cmos(CMOS_STATUS_D);
-}
-
 
 /****************************************************************
  * Standard clock functions
@@ -235,7 +242,7 @@ handle_1a02(struct bregs *regs)
     regs->dh = inb_cmos(CMOS_RTC_SECONDS);
     regs->cl = inb_cmos(CMOS_RTC_MINUTES);
     regs->ch = inb_cmos(CMOS_RTC_HOURS);
-    regs->dl = inb_cmos(CMOS_STATUS_B) & 0x01;
+    regs->dl = inb_cmos(CMOS_STATUS_B) & RTC_B_DSE;
     regs->ah = 0;
     regs->al = regs->ch;
     set_success(regs);
@@ -263,7 +270,8 @@ handle_1a03(struct bregs *regs)
     outb_cmos(regs->cl, CMOS_RTC_MINUTES);
     outb_cmos(regs->ch, CMOS_RTC_HOURS);
     // Set Daylight Savings time enabled bit to requested value
-    u8 val8 = (inb_cmos(CMOS_STATUS_B) & 0x60) | 0x02 | (regs->dl & 0x01);
+    u8 val8 = ((inb_cmos(CMOS_STATUS_B) & (RTC_B_PIE|RTC_B_AIE))
+               | RTC_B_24HR | (regs->dl & RTC_B_DSE));
     outb_cmos(val8, CMOS_STATUS_B);
     regs->ah = 0;
     regs->al = val8; // val last written to Reg B
@@ -282,7 +290,14 @@ handle_1a04(struct bregs *regs)
     regs->cl = inb_cmos(CMOS_RTC_YEAR);
     regs->dh = inb_cmos(CMOS_RTC_MONTH);
     regs->dl = inb_cmos(CMOS_RTC_DAY_MONTH);
-    regs->ch = inb_cmos(CMOS_CENTURY);
+    if (CONFIG_COREBOOT) {
+        if (regs->cl > 0x80)
+            regs->ch = 0x19;
+        else
+            regs->ch = 0x20;
+    } else {
+        regs->ch = inb_cmos(CMOS_CENTURY);
+    }
     regs->al = regs->ch;
     set_success(regs);
 }
@@ -309,7 +324,8 @@ handle_1a05(struct bregs *regs)
     outb_cmos(regs->cl, CMOS_RTC_YEAR);
     outb_cmos(regs->dh, CMOS_RTC_MONTH);
     outb_cmos(regs->dl, CMOS_RTC_DAY_MONTH);
-    outb_cmos(regs->ch, CMOS_CENTURY);
+    if (!CONFIG_COREBOOT)
+        outb_cmos(regs->ch, CMOS_CENTURY);
     // clear halt-clock bit
     u8 val8 = inb_cmos(CMOS_STATUS_B) & ~RTC_B_SET;
     outb_cmos(val8, CMOS_STATUS_B);
@@ -334,7 +350,7 @@ handle_1a06(struct bregs *regs)
     // My assumption: RegB = ((RegB & 01111111b) | 00100000b)
     u8 val8 = inb_cmos(CMOS_STATUS_B); // Get Status Reg B
     regs->ax = 0;
-    if (val8 & 0x20) {
+    if (val8 & RTC_B_AIE) {
         // Alarm interrupt enabled already
         set_fail(regs);
         return;
@@ -528,12 +544,12 @@ handle_70()
 
     if (!(registerB & (RTC_B_PIE|RTC_B_AIE)))
         goto done;
-    if (registerC & 0x20) {
+    if (registerC & RTC_B_AIE) {
         // Handle Alarm Interrupt.
         u32 eax=0, flags;
         call16_simpint(0x4a, &eax, &flags);
     }
-    if (!(registerC & 0x40))
+    if (!(registerC & RTC_B_PIE))
         goto done;
 
     // Handle Periodic Interrupt.
@@ -554,7 +570,7 @@ handle_70()
         clear_usertimer();
     } else {
         // Continue waiting.
-        time -= 0x3D1;
+        time -= 977;
         SET_BDA(user_wait_timeout, time);
     }
 
index 837f25a8265884fa701a9c018b8e7e2cd4e930ab..017e3ed67952f132ae0d68da2971cdb4838069c8 100644 (file)
@@ -152,7 +152,7 @@ ps2_recvbyte(int aux, int needack, int timeout)
 {
     u64 end = calc_future_tsc(timeout);
     for (;;) {
-        if (rdtscll() >= end) {
+        if (rdtscll() > end) {
             dprintf(1, "ps2_recvbyte timeout\n");
             return -1;
         }