Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenrtctimer.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS HAL 00003 * LICENSE: GNU GPL - See COPYING in the top level directory 00004 * FILE: hal/halx86/generic/apic.c 00005 * PURPOSE: HAL APIC Management and Control Code 00006 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) 00007 * REFERENCES: 00008 */ 00009 00010 /* INCLUDES *******************************************************************/ 00011 00012 #include <hal.h> 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 00017 /* GLOBALS ********************************************************************/ 00018 00019 const UCHAR HalpClockVector = 0xD1; 00020 BOOLEAN HalpClockSetMSRate; 00021 UCHAR HalpNextMSRate; 00022 UCHAR HalpCurrentRate = 9; /* Initial rate 9: 128 Hz / 7.8 ms */ 00023 ULONG HalpCurrentTimeIncrement; 00024 static UCHAR RtcMinimumClockRate = 6; /* Minimum rate 6: 16 Hz / 62.5 ms */ 00025 static UCHAR RtcMaximumClockRate = 10; /* Maximum rate 10: 256 Hz / 3.9 ms */ 00026 00027 00028 ULONG 00029 FORCEINLINE 00030 RtcClockRateToIncrement(UCHAR Rate) 00031 { 00032 ULONG Freqency = ((32768 << 1) >> Rate); 00033 return (1000000 + (Freqency/2)) / Freqency; 00034 } 00035 00036 VOID 00037 RtcSetClockRate(UCHAR ClockRate) 00038 { 00039 UCHAR RegisterA; 00040 00041 /* Update the global values */ 00042 HalpCurrentRate = ClockRate; 00043 HalpCurrentTimeIncrement = RtcClockRateToIncrement(ClockRate); 00044 00045 /* Acquire CMOS lock */ 00046 HalpAcquireCmosSpinLock(); 00047 00048 // TODO: disable NMI 00049 00050 /* Read value of register A */ 00051 RegisterA = HalpReadCmos(RTC_REGISTER_A); 00052 00053 /* Change lower 4 bits to new rate */ 00054 RegisterA &= 0xF0; 00055 RegisterA |= ClockRate; 00056 00057 /* Write the new value */ 00058 HalpWriteCmos(RTC_REGISTER_A, RegisterA); 00059 00060 /* Release CMOS lock */ 00061 HalpReleaseCmosSpinLock(); 00062 } 00063 00064 00065 VOID 00066 NTAPI 00067 INIT_FUNCTION 00068 HalpInitializeClock(VOID) 00069 { 00070 ULONG_PTR EFlags; 00071 UCHAR RegisterB; 00072 00073 /* Save EFlags and disable interrupts */ 00074 EFlags = __readeflags(); 00075 _disable(); 00076 00077 // TODO: disable NMI 00078 00079 /* Acquire CMOS lock */ 00080 HalpAcquireCmosSpinLock(); 00081 00082 /* Enable the periodic interrupt in the CMOS */ 00083 RegisterB = HalpReadCmos(RTC_REGISTER_B); 00084 HalpWriteCmos(RTC_REGISTER_B, RegisterB | RTC_REG_B_PI); 00085 00086 /* Release CMOS lock */ 00087 HalpReleaseCmosSpinLock(); 00088 00089 /* Set initial rate */ 00090 RtcSetClockRate(HalpCurrentRate); 00091 00092 /* Restore interrupt state */ 00093 __writeeflags(EFlags); 00094 00095 /* Notify the kernel about the maximum and minimum increment */ 00096 KeSetTimeIncrement(RtcClockRateToIncrement(RtcMaximumClockRate), 00097 RtcClockRateToIncrement(RtcMinimumClockRate)); 00098 00099 00100 DPRINT1("Clock initialized\n"); 00101 } 00102 00103 VOID 00104 FASTCALL 00105 HalpClockInterruptHandler(IN PKTRAP_FRAME TrapFrame) 00106 { 00107 ULONG LastIncrement; 00108 KIRQL Irql; 00109 00110 /* Enter trap */ 00111 KiEnterInterruptTrap(TrapFrame); 00112 #ifdef _M_AMD64 00113 /* This is for debugging */ 00114 TrapFrame->ErrorCode = 0xc10c4; 00115 #endif 00116 00117 /* Start the interrupt */ 00118 if (!HalBeginSystemInterrupt(CLOCK_LEVEL, HalpClockVector, &Irql)) 00119 { 00120 /* Spurious, just end the interrupt */ 00121 KiEoiHelper(TrapFrame); 00122 } 00123 00124 /* Read register C, so that the next interrupt can happen */ 00125 HalpReadCmos(RTC_REGISTER_C);; 00126 00127 /* Save increment */ 00128 LastIncrement = HalpCurrentTimeIncrement; 00129 00130 /* Check if someone changed the time rate */ 00131 if (HalpClockSetMSRate) 00132 { 00133 /* Set new clock rate */ 00134 RtcSetClockRate(HalpNextMSRate); 00135 00136 /* We're done */ 00137 HalpClockSetMSRate = FALSE; 00138 } 00139 00140 /* Update the system time -- on x86 the kernel will exit this trap */ 00141 KeUpdateSystemTime(TrapFrame, LastIncrement, Irql); 00142 } 00143 00144 VOID 00145 FASTCALL 00146 HalpProfileInterruptHandler(IN PKTRAP_FRAME TrapFrame) 00147 { 00148 __debugbreak(); 00149 } 00150 00151 ULONG 00152 NTAPI 00153 HalSetTimeIncrement(IN ULONG Increment) 00154 { 00155 UCHAR Rate; 00156 00157 /* Lookup largest value below given Increment */ 00158 for (Rate = RtcMinimumClockRate; Rate <= RtcMaximumClockRate; Rate++) 00159 { 00160 /* Check if this is the largest rate possible */ 00161 if (RtcClockRateToIncrement(Rate + 1) > Increment) break; 00162 } 00163 00164 /* Set the rate and tell HAL we want to change it */ 00165 HalpNextMSRate = Rate; 00166 HalpClockSetMSRate = TRUE; 00167 00168 /* Return the real increment */ 00169 return RtcClockRateToIncrement(Rate); 00170 } Generated on Mon May 28 2012 04:28:32 for ReactOS by
1.7.6.1
|