ReactOS Fundraising Campaign 2012
 
€ 4,060 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tsc.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS HAL
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            hal/halamd64/generic/tsc.c
00005  * PURPOSE:         HAL Routines for TSC handling
00006  * PROGRAMMERS:     Timo Kreuzer (timo.kreuzer@reactos.org)
00007  */
00008 
00009 /* INCLUDES ******************************************************************/
00010 
00011 #include <hal.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 #include "tsc.h"
00016 
00017 LARGE_INTEGER HalpCpuClockFrequency = {{INITIAL_STALL_COUNT * 1000000}};
00018 
00019 UCHAR TscCalibrationPhase;
00020 ULONG64 TscCalibrationArray[NUM_SAMPLES];
00021 UCHAR HalpRtcClockVector = 0xD1;
00022 
00023 #define RTC_MODE 6 /* Mode 6 is 1024 Hz */
00024 #define SAMPLE_FREQENCY ((32768 << 1) >> RTC_MODE)
00025 
00026 /* PRIVATE FUNCTIONS *********************************************************/
00027 
00028 static
00029 ULONG64
00030 DoLinearRegression(
00031     ULONG XMax,
00032     ULONG64 *ArrayY)
00033 {
00034     ULONG X, SumXX;
00035     ULONG64 SumXY;
00036 
00037     /* Calculate the sum of the squares of X */
00038     SumXX = (XMax * (XMax + 1) * (2*XMax + 1)) / 6;
00039 
00040     /* Calculate the sum of the differences to the first value
00041        weighted by x */
00042     for (SumXY = 0, X = 1; X <= XMax; X++)
00043     {
00044          SumXY += X * (ArrayY[X] - ArrayY[0]);
00045     }
00046 
00047     /* Account for sample frequency */
00048     SumXY *= SAMPLE_FREQENCY;
00049 
00050     /* Return the quotient of the sums */
00051     return (SumXY + (SumXX/2)) / SumXX;
00052 }
00053 
00054 VOID
00055 NTAPI
00056 HalpInitializeTsc()
00057 {
00058     ULONG_PTR Flags;
00059     KIDTENTRY OldIdtEntry, *IdtPointer;
00060     PKPCR Pcr = KeGetPcr();
00061     UCHAR RegisterA, RegisterB;
00062 
00063     /* Check if the CPU supports RDTSC */
00064     if (!(KeGetCurrentPrcb()->FeatureBits & KF_RDTSC))
00065     {
00066         KeBugCheck(HAL_INITIALIZATION_FAILED);
00067     }
00068 
00069      /* Save flags and disable interrupts */
00070     Flags = __readeflags();
00071     _disable();
00072 
00073     /* Enable the periodic interrupt in the CMOS */
00074     RegisterB = HalpReadCmos(RTC_REGISTER_B);
00075     HalpWriteCmos(RTC_REGISTER_B, RegisterB | RTC_REG_B_PI);
00076 
00077     /* Modify register A to RTC_MODE to get SAMPLE_FREQENCY */
00078     RegisterA = HalpReadCmos(RTC_REGISTER_A);
00079     RegisterA = (RegisterA & 0xF0) | RTC_MODE;
00080     HalpWriteCmos(RTC_REGISTER_A, RegisterA);
00081 
00082     /* Save old IDT entry */
00083     IdtPointer = KiGetIdtEntry(Pcr, HalpRtcClockVector);
00084     OldIdtEntry = *IdtPointer;
00085 
00086     /* Set the calibration ISR */
00087     KeRegisterInterruptHandler(HalpRtcClockVector, TscCalibrationISR);
00088 
00089     /* Reset TSC value to 0 */
00090     __writemsr(MSR_RDTSC, 0);
00091 
00092     /* Enable the timer interupt */
00093     HalEnableSystemInterrupt(HalpRtcClockVector, CLOCK_LEVEL, Latched);
00094 
00095     /* Read register C, so that the next interrupt can happen */
00096     HalpReadCmos(RTC_REGISTER_C);;
00097 
00098     /* Wait for completion */
00099     _enable();
00100     while (TscCalibrationPhase < NUM_SAMPLES) _ReadWriteBarrier();
00101     _disable();
00102 
00103     /* Disable the periodic interrupt in the CMOS */
00104     HalpWriteCmos(RTC_REGISTER_B, RegisterB & ~RTC_REG_B_PI);
00105 
00106     /* Disable the timer interupt */
00107     HalDisableSystemInterrupt(HalpRtcClockVector, CLOCK_LEVEL);
00108 
00109     /* Restore old IDT entry */
00110     *IdtPointer = OldIdtEntry;
00111 
00112     /* Calculate an average, using simplified linear regression */
00113     HalpCpuClockFrequency.QuadPart = DoLinearRegression(NUM_SAMPLES - 1,
00114                                                         TscCalibrationArray);
00115 
00116     /* Restore flags */
00117     __writeeflags(Flags);
00118 
00119 }
00120 
00121 VOID
00122 NTAPI
00123 HalpCalibrateStallExecution(VOID)
00124 {
00125     // Timer interrupt is now active
00126 
00127     HalpInitializeTsc();
00128 
00129     KeGetPcr()->StallScaleFactor = (ULONG)(HalpCpuClockFrequency.QuadPart / 1000000);
00130 }
00131 
00132 /* PUBLIC FUNCTIONS ***********************************************************/
00133 
00134 LARGE_INTEGER
00135 NTAPI
00136 KeQueryPerformanceCounter(
00137     OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
00138 {
00139     LARGE_INTEGER Result;
00140 
00141     /* Make sure it's calibrated */
00142     ASSERT(HalpCpuClockFrequency.QuadPart != 0);
00143 
00144     /* Does the caller want the frequency? */
00145     if (PerformanceFrequency)
00146     {
00147         /* Return tsc frequency */
00148         *PerformanceFrequency = HalpCpuClockFrequency;
00149     }
00150 
00151     /* Return the current value */
00152     Result.QuadPart = __rdtsc();
00153     return Result;
00154 }
00155 
00156 VOID
00157 NTAPI
00158 KeStallExecutionProcessor(ULONG MicroSeconds)
00159 {
00160     ULONG64 StartTime, EndTime;
00161 
00162     /* Get the initial time */
00163     StartTime = __rdtsc();
00164 
00165     /* Calculate the ending time */
00166     EndTime = StartTime + KeGetPcr()->StallScaleFactor * MicroSeconds;
00167 
00168     /* Loop until time is elapsed */
00169     while (__rdtsc() < EndTime);
00170 }
00171 
00172 VOID
00173 NTAPI
00174 HalCalibratePerformanceCounter(
00175     IN volatile PLONG Count,
00176     IN ULONGLONG NewCount)
00177 {
00178     UNIMPLEMENTED;
00179     ASSERT(FALSE);
00180 }
00181 

Generated on Tue May 22 2012 04:32:43 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.