ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 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

rtctimer.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 doxygen 1.7.6.1

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