TSC backed timekeeping, 64-bit integer printing
authorJohn Hodge <[email protected]>
Sat, 12 Feb 2011 04:29:50 +0000 (12:29 +0800)
committerJohn Hodge <[email protected]>
Sat, 12 Feb 2011 04:29:50 +0000 (12:29 +0800)
- Improved 64-bit division (using the FPU)

Kernel/arch/x86/lib.c
Kernel/arch/x86/time.c
Kernel/include/acess.h
Kernel/lib.c
Kernel/time.c

index 796baa4..b73cc6a 100644 (file)
@@ -282,6 +282,21 @@ Uint64 __udivdi3(Uint64 Num, Uint64 Den)
        if(Num < Den*2) return 1;
        if(Num == Den*2)        return 2;
        
+       #if 1
+       i = 0;  // Shut up
+       P[0] = Num;
+       P[1] = Den;
+       __asm__ __volatile__ (
+               "fildq %2\n\t"  // Num
+               "fildq %1\n\t"  // Den
+               "fdivp\n\t"
+               "fistpq %0"
+               : "=m" (q)
+               : "m" (P[0]), "m" (P[1])
+               );
+               
+       //Log("%llx / %llx = %llx\n", Num, Den, q);
+       #else
        // Restoring division, from wikipedia
        // http://en.wikipedia.org/wiki/Division_(digital)
        P[0] = Num;     P[1] = 0;
@@ -303,6 +318,7 @@ Uint64 __udivdi3(Uint64 Num, Uint64 Den)
                        P[1] += Den;
                }
        }
+       #endif
        
        return q;
 }
index 63d4e00..37cc5e3 100644 (file)
@@ -9,23 +9,48 @@
 #define        TIMER_QUANTUM   100
 // 2^(15-rate), 15: 1HZ, 5: 1024Hz, 2: 8192Hz
 // (Max: 15, Min: 2) - 15 = 1Hz, 13 = 4Hz, 12 = 8Hz, 11 = 16Hz 10 = 32Hz, 2 = 8192Hz
-#define TIMER_RATE     10
-//#define TIMER_RATE   12
-//#define TIMER_RATE   15
+//#define TIMER_RATE   10      // 32 Hz
+//#define TIMER_RATE   12      // 8 Hz
+#define TIMER_RATE     14      // 2Hz
+//#define TIMER_RATE   15      // 1HZ
 #define TIMER_FREQ     (0x8000>>TIMER_RATE)    //Hz
 #define MS_PER_TICK_WHOLE      (1000/(TIMER_FREQ))
 #define MS_PER_TICK_FRACT      ((0x80000000*(1000%TIMER_FREQ))/TIMER_FREQ)
 
 // === IMPORTS ===
-extern Sint64  giTimestamp;
-extern Uint64  giTicks;
-extern Uint64  giPartMiliseconds;
+extern volatile Sint64 giTimestamp;
+extern volatile Uint64 giTicks;
+extern volatile Uint64 giPartMiliseconds;
 extern void    Timer_CallTimers(void);
 
+// === GLOBALS ===
+volatile Uint64        giTime_TSCAtLastTick = 0;
+volatile Uint64        giTime_TSCPerTick = 0;
+
 // === PROTOTYPES ===
+Sint64 now(void);
+ int   Time_Setup(void);
 void   Time_Interrupt(int);
+Uint64 Time_ReadTSC(void);
 
 // === CODE ===
+/**
+ * \fn Sint64 now()
+ * \brief Return the current timestamp
+ */
+Sint64 now(void)
+{
+       Uint64  tsc = Time_ReadTSC();
+       tsc -= giTime_TSCAtLastTick;
+       tsc *= MS_PER_TICK_WHOLE;
+       if( giTime_TSCPerTick ) {
+               tsc /= giTime_TSCPerTick;
+       }
+       else
+               tsc = 0;
+       return giTimestamp + tsc;
+}
+
 /**
  * \fn int Time_Setup(void)
  * \brief Sets the system time from the Realtime-Clock
@@ -74,6 +99,14 @@ int Time_Setup(void)
 void Time_Interrupt(int irq)
 {
        //Log("RTC Tick");
+       Uint64  curTSC = Time_ReadTSC();
+       
+       if( giTime_TSCAtLastTick )
+       {
+               giTime_TSCPerTick = curTSC - giTime_TSCAtLastTick;
+               //Log("curTSC = %lli, giTime_TSCPerTick = %lli", curTSC, giTime_TSCPerTick);
+       }
+       giTime_TSCAtLastTick = curTSC;
        
        giTicks ++;
        giTimestamp += MS_PER_TICK_WHOLE;
@@ -108,3 +141,10 @@ void Time_TimerThread(void)
        }
 }
 #endif
+
+Uint64 Time_ReadTSC(void)
+{
+       Uint32  a, d;
+       __asm__ __volatile__ ("rdtsc" : "=a" (a), "=d" (d));
+       return ((Uint64)d << 32) | a;
+}
index 1f969f8..95acb31 100644 (file)
@@ -346,7 +346,7 @@ extern char **str_split(const char *__str, char __ch);
 extern char    *strchr(const char *__s, int __c);
 extern int     strpos(const char *Str, char Ch);
 extern int     strpos8(const char *str, Uint32 search);
-extern void    itoa(char *buf, Uint num, int base, int minLength, char pad);
+extern void    itoa(char *buf, Uint64 num, int base, int minLength, char pad);
 extern int     atoi(const char *string);
 extern int     ReadUTF8(Uint8 *str, Uint32 *Val);
 extern int     WriteUTF8(Uint8 *str, Uint32 Val);
index bc32a0c..4c6ab18 100644 (file)
@@ -15,7 +15,7 @@ const short DAYS_BEFORE[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 3
 
 // === PROTOTYPES ===
  int   atoi(const char *string);
-void   itoa(char *buf, Uint num, int base, int minLength, char pad);
+void   itoa(char *buf, Uint64 num, int base, int minLength, char pad);
  int   vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args);
  int   sprintf(char *__s, const char *__format, ...);
  int   tolower(int c);
@@ -145,12 +145,12 @@ int atoi(const char *string)
 
 static const char cUCDIGITS[] = "0123456789ABCDEF";
 /**
- * \fn void itoa(char *buf, Uint num, int base, int minLength, char pad)
+ * \fn void itoa(char *buf, Uint64 num, int base, int minLength, char pad)
  * \brief Convert an integer into a character string
  */
-void itoa(char *buf, Uint num, int base, int minLength, char pad)
+void itoa(char *buf, Uint64 num, int base, int minLength, char pad)
 {
-       char    tmpBuf[BITS];
+       char    tmpBuf[64+1];
         int    pos=0, i;
 
        // Sanity check
index dcc4f79..9ddf26a 100644 (file)
@@ -27,15 +27,6 @@ Uint64       giPartMiliseconds = 0;
 tTimer gTimers[NUM_TIMERS];    // TODO: Replace by a ring-list timer
 
 // === CODE ===
-/**
- * \fn Sint64 now()
- * \brief Return the current timestamp
- */
-Sint64 now(void)
-{
-       return giTimestamp;
-}
-
 /**
  * \fn void Timer_CallTimers()
  */

UCC git Repository :: git.ucc.asn.au