Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

233 lines
5.2 KiB

4 years ago
  1. //#pragma comment(exestr, "$Header: /usr4/winnt/SOURCES/ddk35/src/hal/halsni/mips/RCS/xxclock.c,v 1.3 1995/02/13 12:54:54 flo Exp $")
  2. /*++
  3. Copyright (c) 1993-94 Siemens Nixdorf Informationssysteme AG
  4. Copyright (c) 1985-94 Microsoft Corporation
  5. Module Name:
  6. xxclock.c
  7. Abstract:
  8. This module implements the function necesssary to change the clock
  9. interrupt rate.
  10. Environment:
  11. Kernel mode only.
  12. Revision History:
  13. --*/
  14. #include "halp.h"
  15. #include "eisa.h"
  16. #include "i82C54.h"
  17. //
  18. // Define global data used to communicate new clock rates to the clock
  19. // interrupt service routine.
  20. //
  21. ULONG HalpCurrentTimeIncrement;
  22. ULONG HalpNextTimeIncrement;
  23. ULONG HalpNewTimeIncrement;
  24. ULONG
  25. HalSetTimeIncrement (
  26. IN ULONG DesiredIncrement
  27. )
  28. /*++
  29. Routine Description:
  30. This function is called to set the clock interrupt rate to the frequency
  31. required by the specified time increment value.
  32. N.B. This function is only executed on the processor that keeps the
  33. system time.
  34. Arguments:
  35. DesiredIncrement - Supplies desired number of 100ns units between clock
  36. interrupts.
  37. Return Value:
  38. The actual time increment in 100ns units.
  39. --*/
  40. {
  41. ULONG NewTimeIncrement;
  42. KIRQL OldIrql;
  43. if (DesiredIncrement < MINIMUM_INCREMENT) {
  44. DesiredIncrement = MINIMUM_INCREMENT;
  45. }
  46. if (DesiredIncrement > MAXIMUM_INCREMENT) {
  47. DesiredIncrement = MAXIMUM_INCREMENT;
  48. }
  49. //
  50. // Raise IRQL to the highest level, set the new clock interrupt
  51. // parameters, lower IRQl, and return the new time increment value.
  52. //
  53. KeRaiseIrql(HIGH_LEVEL, &OldIrql);
  54. NewTimeIncrement = DesiredIncrement / MINIMUM_INCREMENT;
  55. NewTimeIncrement = NewTimeIncrement * MINIMUM_INCREMENT;
  56. HalpNewTimeIncrement = NewTimeIncrement ;
  57. KeLowerIrql(OldIrql);
  58. return NewTimeIncrement;
  59. }
  60. VOID
  61. HalpProgramIntervalTimer (
  62. IN ULONG Interval
  63. )
  64. /*++
  65. Routine Description:
  66. This function is called to program the System clock according to the frequency
  67. required by the specified time increment value.
  68. N.B. this information was found in the jenson (ALPHA) HAL
  69. also valid for MIPS computer ???
  70. There are four different rates that are used under NT
  71. (see page 9-8 of KN121 System Module Programmer's Reference)
  72. .976562 ms
  73. 1.953125 ms
  74. 3.90625 ms
  75. 7.8125 ms
  76. Arguments:
  77. Interval - Supplies desired number of 100ns units between clock
  78. interrupts.
  79. Return Value:
  80. none.
  81. --*/
  82. {
  83. PEISA_CONTROL controlBase = (PEISA_CONTROL)HalpOnboardControlBase;
  84. ULONG Count;
  85. TIMER_CONTROL timerControl;
  86. KIRQL OldIrql;
  87. //
  88. // Raise IRQL to the highest level, set the new clock interrupt
  89. // parameters, lower IRQl, and return the new time increment value.
  90. //
  91. KeRaiseIrql(HIGH_LEVEL, &OldIrql);
  92. //
  93. // Start the system clock to interrupt at the desired interval.
  94. //
  95. //
  96. timerControl.BcdMode = 0;
  97. timerControl.Mode = TM_SQUARE_WAVE;
  98. timerControl.SelectByte = SB_LSB_THEN_MSB;
  99. timerControl.SelectCounter = SELECT_COUNTER_0;
  100. //
  101. // use timer in the onboard PC core
  102. //
  103. Count = TIMER_CLOCK_IN / ( 10000000 / Interval );
  104. WRITE_REGISTER_UCHAR(&controlBase->CommandMode1, *((PUCHAR) &timerControl));
  105. //
  106. // Set the system clock timer to the correct frequency.
  107. //
  108. WRITE_REGISTER_UCHAR(&controlBase->Timer1, (UCHAR)Count);
  109. WRITE_REGISTER_UCHAR(&controlBase->Timer1, (UCHAR)(Count >> 8));
  110. KeLowerIrql(OldIrql);
  111. }
  112. VOID
  113. HalpProgramExtraTimer (
  114. IN ULONG Interval
  115. )
  116. /*++
  117. Routine Description:
  118. This function is called to program the second clock generator in a multiprocessor System
  119. according to the frequency required by the specified Interval value (in 100ns units).
  120. Arguments:
  121. Interval - Supplies desired number of 100ns units between clock
  122. interrupts.
  123. Return Value:
  124. none.
  125. --*/
  126. {
  127. volatile PLOCAL_8254 pt = (PLOCAL_8254) RM400_EXTRA_TIMER_ADDR;
  128. ULONG Count;
  129. TIMER_CONTROL timerControl;
  130. KIRQL OldIrql;
  131. //
  132. // Raise IRQL to the highest level, set the new clock interrupt
  133. // parameters, lower IRQl, and return the new time increment value.
  134. //
  135. KeRaiseIrql(HIGH_LEVEL, &OldIrql);
  136. //
  137. // Start the system clock to interrupt at the desired interval.
  138. //
  139. //
  140. timerControl.BcdMode = 0;
  141. timerControl.Mode = TM_SQUARE_WAVE;
  142. timerControl.SelectByte = SB_LSB_THEN_MSB;
  143. timerControl.SelectCounter = SELECT_COUNTER_0;
  144. Count = EXTRA_TIMER_CLOCK_IN / (PRE_COUNT * 10000000 / Interval );
  145. WRITE_REGISTER_UCHAR( &pt->control, *((PUCHAR) &timerControl));
  146. WRITE_REGISTER_UCHAR(&(pt->counter0), (UCHAR)Count);
  147. WRITE_REGISTER_UCHAR(&(pt->counter0), (UCHAR)(Count >> 8));
  148. timerControl.BcdMode = 0;
  149. timerControl.Mode = TM_RATE_GENERATOR;
  150. timerControl.SelectByte = SB_LSB_THEN_MSB;
  151. timerControl.SelectCounter = SELECT_COUNTER_2;
  152. // the output of counter 2 is hardwired as input to counter 0/1
  153. // so we use it as a pre-counter
  154. WRITE_REGISTER_UCHAR( &pt->control, *((PUCHAR) &timerControl));
  155. WRITE_REGISTER_UCHAR(&(pt->counter2), (UCHAR)PRE_COUNT);
  156. WRITE_REGISTER_UCHAR(&(pt->counter2), (UCHAR)(PRE_COUNT >>8));
  157. KeLowerIrql(OldIrql);
  158. }