]> Zhao Yanbai Git Server - minix.git/commitdiff
libsys: refactor frclock api 52/352/2
authorThomas Veerman <thomas@minix3.org>
Thu, 21 Feb 2013 16:02:42 +0000 (17:02 +0100)
committerThomas Veerman <thomas@minix3.org>
Fri, 22 Feb 2013 13:08:21 +0000 (13:08 +0000)
Make the frclock functions similar to the tsc utility functions. This
way, we can call frclock functions from the framebuffer driver which
will use frclock on ARM and tsc on X86.

Also, frclock_64_to_micros computed seconds, not microseconds

Change-Id: I6718ae0fb7db050794f6f032205923e1a32dc1ac

include/minix/sysutil.h
lib/libsys/arch/earm/frclock_util.c
lib/libsys/arch/earm/spin.c
lib/libsys/arch/i386/frclock_util.c [new file with mode: 0644]
lib/libsys/arch/i386/tsc_util.c

index 56a6d795292168d6ba0e2778d750c61794466d11..426e5a1b87ee618611d4f6026b3ad606d841452c 100644 (file)
@@ -62,11 +62,12 @@ u32_t tsc_to_micros(u32_t low, u32_t high);
 u32_t tsc_get_khz(void);
 u32_t micros_to_ticks(u32_t micros);
 #if defined(__arm__)
-u32_t read_frclock(void);
+void read_frclock(u32_t *frclk);
 u32_t delta_frclock(u32_t base, u32_t cur);
-u64_t read_frclock_64(void);
-u64_t delta_frclock_64(u64_t base, u64_t cur);
 #endif
+void read_frclock_64(u64_t *frclk);
+u64_t delta_frclock_64(u64_t base, u64_t cur);
+u32_t frclock_64_to_micros(u64_t tsc);
 void ser_putc(char c);
 void get_randomness(struct k_randomness *, int);
 u32_t sqrt_approx(u32_t);
index 8d81e78576793f5a4eb4ca5b35b2fed0de199181..574bb029a525d3330d1294df2f4225aaf0f9402d 100644 (file)
@@ -9,7 +9,7 @@
 #include <minix/type.h>
 #include <sys/errno.h>
 #include <sys/types.h>
-
+#include <assert.h>
 
 static u64_t calib_hz = 1625000, Hz;
 #define MICROHZ         1000000ULL     /* number of micros per second */
@@ -23,7 +23,7 @@ micro_delay(u32_t micros)
        Hz = sys_hz();
 
         /* Start of delay. */
-        start = read_frclock_64();
+        read_frclock_64(&start);
        delta_end = (calib_hz * micros) / MICROHZ;
 
         /* If we have to wait for at least one HZ tick, use the regular
@@ -37,7 +37,7 @@ micro_delay(u32_t micros)
 
         /* Wait (the rest) of the delay time using busywait. */
        do {
-                delta = read_frclock_64();
+                read_frclock_64(&delta);
        } while (delta_frclock_64(start, delta) < delta_end);
 
 
@@ -46,16 +46,18 @@ micro_delay(u32_t micros)
 
 u32_t frclock_64_to_micros(u64_t tsc)
 {
-        return (u32_t) tsc / calib_hz;
+        return (u32_t) tsc / (calib_hz / MICROHZ);
 }
 
-u32_t
-read_frclock(void)
+void
+read_frclock(u32_t *frclk)
 {
        extern struct minix_kerninfo *_minix_kerninfo;
        volatile u32_t *frclock;
+
+       assert(frclk);
        frclock = (u32_t *)((u8_t *) _minix_kerninfo->minix_frclock+OMAP3_TCRR);
-       return (u64_t) *frclock;
+       *frclk = *frclock;
 }
 
 u32_t
@@ -75,15 +77,15 @@ delta_frclock(u32_t base, u32_t cur)
        return delta;
 }
 
-u64_t
-read_frclock_64(void)
+void
+read_frclock_64(u64_t *frclk)
 {
-       return (u64_t) read_frclock();
+       read_frclock((u32_t *) frclk);  
 }
 
 u64_t
 delta_frclock_64(u64_t base, u64_t cur)
 {
-       return delta_frclock((u32_t) base, (u32_t) cur);
+       return (u64_t) delta_frclock((u32_t) base, (u32_t) cur);
 }
 
index 1033a2f8ffde27b00d54886ba1137800aa376db3..3e2115f03ecd3debff723a90d7a20f6ad7e3b99d 100644 (file)
@@ -55,11 +55,11 @@ int spin_check(spin_t *s)
 
        case STATE_BASE_TS:
                s->s_state = STATE_TS;
-               s->s_base_tsc = read_frclock_64();
+               read_frclock_64(&s->s_base_tsc);
                break;
 
        case STATE_TS:
-               cur_tsc = read_frclock_64();
+               read_frclock_64(&cur_tsc);
                tsc_delta = delta_frclock_64(s->s_base_tsc, cur_tsc);
                micro_delta = frclock_64_to_micros(tsc_delta);
 
diff --git a/lib/libsys/arch/i386/frclock_util.c b/lib/libsys/arch/i386/frclock_util.c
new file mode 100644 (file)
index 0000000..8d81e78
--- /dev/null
@@ -0,0 +1,89 @@
+/* Some utility functions around the free running clock on ARM. The clock is
+ * 32-bits wide, but we provide 64-bit wrapper functions to make it look
+ * similar to the read_tsc functions. On hardware we could actually make use
+ * of the timer overflow counter, but emulator doesn't emulate it. */
+
+#include "omap_timer_registers.h"
+#include <minix/minlib.h>
+#include <minix/sysutil.h>
+#include <minix/type.h>
+#include <sys/errno.h>
+#include <sys/types.h>
+
+
+static u64_t calib_hz = 1625000, Hz;
+#define MICROHZ         1000000ULL     /* number of micros per second */
+#define MICROSPERTICK(h)       (MICROHZ/(h)) /* number of micros per HZ tick */
+
+int
+micro_delay(u32_t micros)
+{
+        u64_t start, delta, delta_end;
+
+       Hz = sys_hz();
+
+        /* Start of delay. */
+        start = read_frclock_64();
+       delta_end = (calib_hz * micros) / MICROHZ;
+
+        /* If we have to wait for at least one HZ tick, use the regular
+         * tickdelay first. Round downwards on purpose, so the average
+         * half-tick we wait short (depending on where in the current tick
+         * we call tickdelay). We can correct for both overhead of tickdelay
+         * itself and the short wait in the busywait later.
+         */
+        if (micros >= MICROSPERTICK(Hz))
+                tickdelay(micros*Hz/MICROHZ);
+
+        /* Wait (the rest) of the delay time using busywait. */
+       do {
+                delta = read_frclock_64();
+       } while (delta_frclock_64(start, delta) < delta_end);
+
+
+        return 0;
+}
+
+u32_t frclock_64_to_micros(u64_t tsc)
+{
+        return (u32_t) tsc / calib_hz;
+}
+
+u32_t
+read_frclock(void)
+{
+       extern struct minix_kerninfo *_minix_kerninfo;
+       volatile u32_t *frclock;
+       frclock = (u32_t *)((u8_t *) _minix_kerninfo->minix_frclock+OMAP3_TCRR);
+       return (u64_t) *frclock;
+}
+
+u32_t
+delta_frclock(u32_t base, u32_t cur)
+{
+       u32_t delta;
+
+       if (cur < base) {
+               /* We have wrapped around, so delta is base to wrapping point
+                * plus starting point (0) to cur. This supports wrapping once
+                * only. */
+               delta = (UINT_MAX - base) + cur;
+       } else {
+               delta = cur - base;
+       }
+
+       return delta;
+}
+
+u64_t
+read_frclock_64(void)
+{
+       return (u64_t) read_frclock();
+}
+
+u64_t
+delta_frclock_64(u64_t base, u64_t cur)
+{
+       return delta_frclock((u32_t) base, (u32_t) cur);
+}
+
index d6dc1aff8d01d7654b2fe4fe6bf94045c45b7a7a..87b2b8c1c00030b61e313a44fd9802d8bd8870b7 100644 (file)
@@ -107,3 +107,12 @@ u32_t tsc_get_khz(void)
 
        return calib_mhz * 1000;
 }
+
+#define frclock_64_to_micros tsc_64_to_micros
+#define read_frclock_64 read_tsc_64
+
+u64_t delta_frclock_64(u64_t base, u64_t cur)
+{
+        return cur - base;
+}
+