Leaked source code of windows server 2003
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.

216 lines
3.9 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. pmrtc.c
  5. Abstract:
  6. This module implements the code for ACPI-related RTC functions.
  7. Author:
  8. Jake Oshins (jakeo) March 28, 1997
  9. Environment:
  10. Kernel mode only.
  11. Revision History:
  12. Split from pmclock.asm due to PIIX4 bugs.
  13. Forrest Foltz (forrestf) 24-Oct-2000
  14. Ported from pmrtc.asm to pmrtc.c
  15. --*/
  16. #include <halp.h>
  17. #include <acpitabl.h>
  18. #include <xxacpi.h>
  19. #include "io_cmos.h"
  20. VOID
  21. HalpInitializeCmos (
  22. VOID
  23. )
  24. /*++
  25. Routine Description
  26. This routine reads CMOS and initializes globals required for CMOS access,
  27. such as the location of the century byte.
  28. Arguments
  29. None
  30. Return Value
  31. None
  32. --*/
  33. {
  34. UCHAR centuryAlarmIndex;
  35. //
  36. // If the century byte is filled in, use it... otherwise assume
  37. // a default value.
  38. //
  39. centuryAlarmIndex = HalpFixedAcpiDescTable.century_alarm_index;
  40. if (centuryAlarmIndex == 0) {
  41. centuryAlarmIndex = RTC_OFFSET_CENTURY;
  42. }
  43. HalpCmosCenturyOffset = centuryAlarmIndex;
  44. }
  45. NTSTATUS
  46. HalpSetWakeAlarm (
  47. IN ULONG64 WakeSystemTime,
  48. IN PTIME_FIELDS WakeTimeFields
  49. )
  50. /*++
  51. Routine Description:
  52. This routine sets the real-time clock's alarm to go
  53. off at a specified time in the future and programs
  54. the ACPI chipset so that this wakes the computer.
  55. Arguments:
  56. WakeSystemTime - amount of time that passes before we wake
  57. WakeTimeFields - time to wake broken down into TIME_FIELDS
  58. Return Value:
  59. status
  60. --*/
  61. {
  62. UCHAR alarmPort;
  63. UCHAR value;
  64. HalpAcquireCmosSpinLockAndWait();
  65. CMOS_WRITE_BCD(RTC_OFFSET_SECOND_ALARM,(UCHAR)WakeTimeFields->Second);
  66. CMOS_WRITE_BCD(RTC_OFFSET_MINUTE_ALARM,(UCHAR)WakeTimeFields->Minute);
  67. CMOS_WRITE_BCD(RTC_OFFSET_HOUR_ALARM,(UCHAR)WakeTimeFields->Hour);
  68. alarmPort = HalpFixedAcpiDescTable.day_alarm_index;
  69. if (alarmPort != 0) {
  70. CMOS_WRITE_BCD(alarmPort,(UCHAR)WakeTimeFields->Day);
  71. alarmPort = HalpFixedAcpiDescTable.month_alarm_index;
  72. if (alarmPort != 0) {
  73. CMOS_WRITE_BCD(alarmPort,(UCHAR)WakeTimeFields->Month);
  74. }
  75. }
  76. //
  77. // Enable the alarm. Be sure to preserve the daylight savings time
  78. // bit.
  79. //
  80. value = CMOS_READ(CMOS_STATUS_B);
  81. value &= REGISTER_B_DAYLIGHT_SAVINGS_TIME;
  82. value |= REGISTER_B_ENABLE_ALARM_INTERRUPT | REGISTER_B_24HOUR_MODE;
  83. CMOS_WRITE(CMOS_STATUS_B,value);
  84. CMOS_READ(CMOS_STATUS_C);
  85. CMOS_READ(CMOS_STATUS_D);
  86. HalpReleaseCmosSpinLock();
  87. return STATUS_SUCCESS;
  88. }
  89. VOID
  90. HalpSetClockBeforeSleep (
  91. VOID
  92. )
  93. /*++
  94. Routine Description:
  95. This routine sets the RTC such that it will not generate
  96. periodic interrupts while the machine is sleeping, as this
  97. could be interpretted as an RTC wakeup event.
  98. Arguments:
  99. Return Value:
  100. None
  101. --*/
  102. {
  103. UCHAR value;
  104. HalpAcquireCmosSpinLock();
  105. HalpRtcRegA = CMOS_READ(CMOS_STATUS_A);
  106. HalpRtcRegB = CMOS_READ(CMOS_STATUS_B);
  107. value = HalpRtcRegB & ~REGISTER_B_ENABLE_PERIODIC_INTERRUPT;
  108. value |= REGISTER_B_24HOUR_MODE;
  109. CMOS_WRITE(CMOS_STATUS_B,value);
  110. CMOS_READ(CMOS_STATUS_C);
  111. CMOS_READ(CMOS_STATUS_D);
  112. HalpReleaseCmosSpinLock();
  113. }
  114. VOID
  115. HalpSetClockAfterSleep (
  116. VOID
  117. )
  118. /*++
  119. Routine Description:
  120. This routine sets the RTC back to the way it was
  121. before a call to HalpSetClockBeforeSleep.
  122. Arguments:
  123. Return Value:
  124. None
  125. --*/
  126. {
  127. UCHAR value;
  128. HalpAcquireCmosSpinLock();
  129. CMOS_WRITE(CMOS_STATUS_A,HalpRtcRegA);
  130. value = HalpRtcRegB;
  131. value &= ~REGISTER_B_ENABLE_ALARM_INTERRUPT;
  132. value |= REGISTER_B_24HOUR_MODE;
  133. CMOS_WRITE(CMOS_STATUS_B,value);
  134. CMOS_READ(CMOS_STATUS_C);
  135. CMOS_READ(CMOS_STATUS_D);
  136. HalpReleaseCmosSpinLock();
  137. }