Kernel/x86_64 - Disable full page dump on #PF
[tpg/acess2.git] / KernelLand / Kernel / arch / x86_64 / time.c
1 /*
2  * Acess2 Kernel
3  * Timekeeping
4  * arch/x86_64/time.c
5  */
6 #include <acess.h>
7 #include <arch_config.h>
8 #include <timers.h>
9
10 // === MACROS ===
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))
16
17 // === IMPORTS ===
18 extern volatile Sint64  giTimestamp;
19 extern volatile Uint64  giTicks;
20 extern volatile Uint64  giPartMiliseconds;
21 extern void     Timer_CallTimers(void);
22
23 // === GLOBALS ===
24 volatile Uint64 giTime_TSCAtLastTick = 0;
25 volatile Uint64 giTime_TSCPerTick = 0;
26
27 // === PROTOTYPES ===
28 //Sint64        now(void);
29  int    Time_Setup(void);
30 void    Time_UpdateTimestamp(void);
31 Uint64  Time_ReadTSC(void);
32
33 // === CODE ===
34 /**
35  * \fn Sint64 now()
36  * \brief Return the current timestamp
37  */
38 Sint64 now(void)
39 {
40         Uint64  tsc = Time_ReadTSC();
41         tsc -= giTime_TSCAtLastTick;
42         tsc *= MS_PER_TICK_WHOLE;
43         if( giTime_TSCPerTick ) {
44                 tsc /= giTime_TSCPerTick;
45         }
46         else
47                 tsc = 0;
48         return giTimestamp + tsc;
49 }
50
51 /**
52  * \fn int Time_Setup(void)
53  * \brief Sets the system time from the Realtime-Clock
54  */
55 int Time_Setup(void)
56 {
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);
59
60         // TODO: Read time from RTC
61         
62         return 0;
63 }
64
65 /**
66  * \brief Called on the timekeeping IRQ
67  */
68 void Time_UpdateTimestamp(void)
69 {
70         Uint64  curTSC = Time_ReadTSC();
71         
72         if( giTime_TSCAtLastTick )
73         {
74                 giTime_TSCPerTick = curTSC - giTime_TSCAtLastTick;
75         }
76         giTime_TSCAtLastTick = curTSC;
77         
78         giTicks ++;
79         giTimestamp += MS_PER_TICK_WHOLE;
80         giPartMiliseconds += MS_PER_TICK_FRACT;
81         if(giPartMiliseconds > 0x80000000) {
82                 giTimestamp ++;
83                 giPartMiliseconds -= 0x80000000;
84         }
85         
86         Timer_CallTimers();
87 }
88
89 #if 0
90 /**
91  * \fn void Time_TimerThread(void)
92  */
93 void Time_TimerThread(void)
94 {
95         Sint64  next;
96         Threads_SetName("TIMER");
97         
98         next = giTimestamp + TIMER_QUANTUM;
99         for(;;)
100         {
101                 while(giTimestamp < next)       Threads_Yield();
102                 next = giTimestamp + TIMER_QUANTUM;     
103                 Timer_CallTimers();
104         }
105 }
106 #endif
107
108 void Time_MicroSleep(Uint16 Microsecs)  // max 64 ms
109 {
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;
114
115         if( tgt_tsc < cur_tsc )
116                 while(Time_ReadTSC() > cur_tsc)
117                         ;       
118
119         while( Time_ReadTSC() < tgt_tsc )
120                 ;
121 }
122
123 Uint64 Time_ReadTSC(void)
124 {
125         Uint32  a, d;
126         __asm__ __volatile__ ("rdtsc" : "=a" (a), "=d" (d));
127         return ((Uint64)d << 32) | a;
128 }

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