7 #include <arch_config.h>
11 #define TIMER_QUANTUM 100
12 #define TIMER_FREQ PIT_TIMER_BASE_N/(PIT_TIMER_BASE_D*PIT_TIMER_DIVISOR)
13 #define MS_PER_TICK_WHOLE (1000*(PIT_TIMER_BASE_D*PIT_TIMER_DIVISOR)/PIT_TIMER_BASE_N)
14 #define MS_PER_TICK_FRACT ((0x80000000ULL*1000ULL*PIT_TIMER_BASE_D*PIT_TIMER_DIVISOR/PIT_TIMER_BASE_N)&0x7FFFFFFF)
15 #define US_PER_TICK (1000*1000/(TIMER_FREQ))
18 extern volatile Sint64 giTimestamp;
19 extern volatile Uint64 giTicks;
20 extern volatile Uint64 giPartMiliseconds;
21 extern void Timer_CallTimers(void);
24 volatile Uint64 giTime_TSCAtLastTick = 0;
25 volatile Uint64 giTime_TSCPerTick = 0;
30 void Time_UpdateTimestamp(void);
31 Uint64 Time_ReadTSC(void);
36 * \brief Return the current timestamp
40 Uint64 tsc = Time_ReadTSC();
41 tsc -= giTime_TSCAtLastTick;
42 tsc *= MS_PER_TICK_WHOLE;
43 if( giTime_TSCPerTick ) {
44 tsc /= giTime_TSCPerTick;
48 return giTimestamp + tsc;
52 * \fn int Time_Setup(void)
53 * \brief Sets the system time from the Realtime-Clock
57 Log_Log("Timer", "PIT Timer firing at %iHz, %i.0x%08x miliseconds per tick",
58 TIMER_FREQ, MS_PER_TICK_WHOLE, MS_PER_TICK_FRACT);
60 // TODO: Read time from RTC
66 * \brief Called on the timekeeping IRQ
68 void Time_UpdateTimestamp(void)
70 Uint64 curTSC = Time_ReadTSC();
72 if( giTime_TSCAtLastTick )
74 giTime_TSCPerTick = curTSC - giTime_TSCAtLastTick;
76 giTime_TSCAtLastTick = curTSC;
79 giTimestamp += MS_PER_TICK_WHOLE;
80 giPartMiliseconds += MS_PER_TICK_FRACT;
81 if(giPartMiliseconds > 0x80000000) {
83 giPartMiliseconds -= 0x80000000;
91 * \fn void Time_TimerThread(void)
93 void Time_TimerThread(void)
96 Threads_SetName("TIMER");
98 next = giTimestamp + TIMER_QUANTUM;
101 while(giTimestamp < next) Threads_Yield();
102 next = giTimestamp + TIMER_QUANTUM;
108 void Time_MicroSleep(Uint16 Microsecs) // max 64 ms
110 Uint64 cur_tsc = Time_ReadTSC();
111 // tsc_per_us * Microsec
112 Uint64 delta_tsc = (Uint64)Microsecs * giTime_TSCPerTick / US_PER_TICK;
113 Uint64 tgt_tsc = cur_tsc + delta_tsc;
115 if( tgt_tsc < cur_tsc )
116 while(Time_ReadTSC() > cur_tsc)
119 while( Time_ReadTSC() < tgt_tsc )
123 Uint64 Time_ReadTSC(void)
126 __asm__ __volatile__ ("rdtsc" : "=a" (a), "=d" (d));
127 return ((Uint64)d << 32) | a;