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.

174 lines
3.6 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. xxclock.c
  5. Abstract:
  6. This module implements the function necesssary to change the clock
  7. interrupt rate.
  8. Author:
  9. David N. Cutler (davec) 7-Feb-1994
  10. Environment:
  11. Kernel mode only.
  12. Revision History:
  13. --*/
  14. #include "halp.h"
  15. #include "eisa.h"
  16. //
  17. // Define clock count and time table.
  18. //
  19. typedef struct _COUNT_ENTRY {
  20. ULONG Count;
  21. ULONG Time;
  22. } COUNT_ENTRY, *PCOUNT_ENTRY;
  23. COUNT_ENTRY TimeTable[] = {
  24. {1197, 10032},
  25. {2394, 20064},
  26. {3591, 30096},
  27. {4767, 39952},
  28. {5964, 49984},
  29. {7161, 60016},
  30. {8358, 70048},
  31. {9555, 80080},
  32. {10731, 89936},
  33. {11928, 99968}
  34. };
  35. //
  36. // Define global data used to communicate new clock rates to the clock
  37. // interrupt service routine.
  38. //
  39. ULONG HalpCurrentTimeIncrement;
  40. ULONG HalpNextIntervalCount;
  41. ULONG HalpNextTimeIncrement;
  42. ULONG HalpNewTimeIncrement;
  43. VOID
  44. HalpProgramIntervalTimer(
  45. IN ULONG IntervalCount
  46. )
  47. /*++
  48. Routine Description:
  49. This function is called to program the interval timer. It is used during
  50. Phase 1 initialization to start the heartbeat timer. It also used by
  51. the clock interrupt interrupt routine to change the hearbeat timer rate
  52. when a call to HalSetTimeIncrement has been made in the previous time slice.
  53. Arguments:
  54. IntervalCount - Supplies cound value to be placed in the timer/counter.
  55. Return Value:
  56. None
  57. --*/
  58. {
  59. PEISA_CONTROL controlBase;
  60. TIMER_CONTROL timerControl;
  61. //
  62. // Set the system clock timer to the correct mode.
  63. //
  64. timerControl.BcdMode = 0;
  65. timerControl.Mode = TM_SQUARE_WAVE;
  66. timerControl.SelectByte = SB_LSB_THEN_MSB;
  67. timerControl.SelectCounter = SELECT_COUNTER_0;
  68. controlBase = HalpEisaControlBase;
  69. WRITE_REGISTER_UCHAR(&controlBase->CommandMode1, *((PUCHAR) &timerControl));
  70. //
  71. // Set the system clock timer to the correct frequency.
  72. //
  73. WRITE_REGISTER_UCHAR(&controlBase->Timer1, (UCHAR)IntervalCount);
  74. WRITE_REGISTER_UCHAR(&controlBase->Timer1, (UCHAR)(IntervalCount >> 8));
  75. }
  76. ULONG
  77. HalSetTimeIncrement (
  78. IN ULONG DesiredIncrement
  79. )
  80. /*++
  81. Routine Description:
  82. This function is called to set the clock interrupt rate to the frequency
  83. required by the specified time increment value.
  84. N.B. This function is only executed on the processor that keeps the
  85. system time.
  86. Arguments:
  87. DesiredIncrement - Supplies desired number of 100ns units between clock
  88. interrupts.
  89. Return Value:
  90. The actual time increment in 100ns units.
  91. --*/
  92. {
  93. ULONG Index;
  94. KIRQL OldIrql;
  95. //
  96. // Raise IRQL to the highest level, set the new clock interrupt
  97. // parameters, lower IRQl, and return the new time increment value.
  98. //
  99. KeRaiseIrql(HIGH_LEVEL, &OldIrql);
  100. //
  101. // The new clock count value is selected from a precomputed table of
  102. // count/time pairs. The values in the table were selected for their
  103. // accuracy and closeness to the values of 1ms, 2ms, 3ms, etc. to 10ms.
  104. //
  105. // N.B. The NT executive guarantees that this function will never
  106. // be called with the desired incrment less than the minimum
  107. // increment or greater than the maximum increment.
  108. //
  109. for (Index = 0; Index < sizeof(TimeTable) / sizeof(COUNT_ENTRY); Index += 1) {
  110. if (DesiredIncrement <= TimeTable[Index].Time) {
  111. break;
  112. }
  113. }
  114. if (DesiredIncrement < TimeTable[Index].Time) {
  115. Index -= 1;
  116. }
  117. HalpNextIntervalCount = TimeTable[Index].Count;
  118. HalpNewTimeIncrement = TimeTable[Index].Time;
  119. KeLowerIrql(OldIrql);
  120. return HalpNewTimeIncrement;
  121. }