Source code of Windows XP (NT5)
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.

328 lines
7.6 KiB

  1. title "ACPI Real Time Clock Functions"
  2. ;++
  3. ;
  4. ; Copyright (c) 1989 Microsoft Corporation
  5. ;
  6. ; Module Name:
  7. ;
  8. ; pmclock.asm
  9. ;
  10. ; Abstract:
  11. ;
  12. ; This module implements the code for ACPI-related RTC
  13. ; functions.
  14. ;
  15. ; Author:
  16. ;
  17. ; Jake Oshins (jakeo) March 28, 1997
  18. ;
  19. ; Environment:
  20. ;
  21. ; Kernel mode only.
  22. ;
  23. ; Revision History:
  24. ;
  25. ; Split from pmclock.asm due to PIIX4 bugs.
  26. ;
  27. ;--
  28. .386p
  29. .xlist
  30. include hal386.inc
  31. include callconv.inc ; calling convention macros
  32. include mac386.inc
  33. include i386\ix8259.inc
  34. include i386\ixcmos.inc
  35. include xxacpi.h
  36. .list
  37. extrn _HalpFixedAcpiDescTable:DWORD
  38. EXTRNP _DbgBreakPoint,0,IMPORT
  39. EXTRNP _HalpAcquireCmosSpinLock ,0
  40. EXTRNP _HalpReleaseCmosSpinLock ,0
  41. extrn _HalpRtcRegA:BYTE
  42. extrn _HalpRtcRegB:BYTE
  43. extrn _HalpCmosCenturyOffset:DWORD
  44. INIT SEGMENT DWORD PUBLIC 'CODE'
  45. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  46. ;++
  47. ;
  48. ; VOID
  49. ; HalpInitializeCmos(
  50. ; VOID
  51. ; )
  52. ;
  53. ; This routine reads CMOS and initializes globals required for
  54. ; CMOS access, such as the location of the century byte.
  55. ;
  56. ;--
  57. cPublicProc _HalpInitializeCmos,0
  58. cPublicFpo 0,0
  59. ;
  60. ; If the century byte is filled in, use it.
  61. ;
  62. movzx eax, byte ptr [RTC_CENTURY]
  63. or al, al
  64. jnz short @f
  65. ;
  66. ; Assume default
  67. ;
  68. mov eax, RTC_OFFSET_CENTURY
  69. @@:
  70. mov _HalpCmosCenturyOffset, eax
  71. stdRET _HalpInitializeCmos
  72. stdENDP _HalpInitializeCmos
  73. INIT ends
  74. _TEXT$03 SEGMENT DWORD PUBLIC 'CODE'
  75. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  76. ; NTSTATUS
  77. ; HalpSetWakeAlarm (
  78. ; IN ULONGLONG WakeSystemTime,
  79. ; IN PTIME_FIELDS WakeTimeFields OPTIONAL
  80. ; )
  81. ; /*++
  82. ;
  83. ; Routine Description:
  84. ;
  85. ; This routine sets the real-time clock's alarm to go
  86. ; off at a specified time in the future and programs
  87. ; the ACPI chipset so that this wakes the computer.
  88. ;
  89. ; Arguments:
  90. ;
  91. ; WakeSystemTime - amount of time that passes before we wake
  92. ; WakeTimeFields - time to wake broken down into TIME_FIELDS
  93. ;
  94. ; Return Value:
  95. ;
  96. ; status
  97. ;
  98. ; --*/
  99. WakeSystemTime equ [esp + 4]
  100. WakeTimeFields equ [esp + 12]
  101. cPublicProc _HalpSetWakeAlarm, 3
  102. cPublicFpo 3, 0
  103. if DBG
  104. hswawait0:
  105. mov ecx, 100
  106. hswawait:
  107. push ecx
  108. else
  109. hswawait:
  110. endif
  111. stdCall _HalpAcquireCmosSpinLock
  112. mov ecx, 100
  113. align 4
  114. hswa00: mov al, 0Ah ; Specify register A
  115. CMOS_READ ; (al) = CMOS register A
  116. test al, CMOS_STATUS_BUSY ; Is time update in progress?
  117. jz short hswa10 ; if z, no, go write CMOS time
  118. loop short hswa00 ; otherwise, try again.
  119. ;
  120. ; CMOS is still busy. Try again ...
  121. ;
  122. stdCall _HalpReleaseCmosSpinLock
  123. if DBG
  124. pop ecx
  125. loop short hswawait
  126. stdCall _DbgBreakPoint
  127. jmp short hswawait0
  128. else
  129. jmp short hswawait
  130. endif
  131. align 4
  132. if DBG
  133. hswa10:
  134. pop ecx
  135. else
  136. hswa10:
  137. endif
  138. mov edx, WakeTimeFields ; (edx)-> TIME_FIELDS structure
  139. mov al, [edx].TfSecond ; Read second in TIME_FIELDS
  140. BIN_TO_BCD
  141. mov ah, al
  142. mov al, RTC_OFFSET_SECOND_ALARM
  143. CMOS_WRITE
  144. mov al, [edx].TfMinute ; Read minute in TIME_FIELDS
  145. BIN_TO_BCD
  146. mov ah, al
  147. mov al, RTC_OFFSET_MINUTE_ALARM
  148. CMOS_WRITE
  149. mov al, [edx].TfHour ; Read Hour in TIME_FIELDS
  150. BIN_TO_BCD
  151. mov ah, al
  152. mov al, RTC_OFFSET_HOUR_ALARM
  153. CMOS_WRITE
  154. ; test to see if RTC_DAY_ALRM is supported
  155. mov cl, byte ptr [RTC_DAY_ALRM]
  156. or cl, cl
  157. jz hswa20
  158. mov al, [edx].TfDay ; Read day in TIME_FIELDS
  159. BIN_TO_BCD
  160. mov ah, al
  161. mov al, cl
  162. CMOS_WRITE
  163. ; test to see if RTC_MON_ALRM is supported
  164. mov cl, byte ptr [RTC_MON_ALRM]
  165. or cl, cl
  166. jz hswa20
  167. mov al, [edx].TfMonth ; Read month in TIME_FIELDS
  168. BIN_TO_BCD
  169. mov ah, al
  170. mov al, cl
  171. CMOS_WRITE
  172. ;
  173. ; Don't clobber the Daylight Savings Time bit in register B, because we
  174. ; stash the LastKnownGood "environment variable" there.
  175. ;
  176. hswa20:
  177. mov ax, 0bh
  178. CMOS_READ
  179. and al, 1
  180. mov ah, al
  181. or ah, REGISTER_B_ENABLE_ALARM_INTERRUPT or REGISTER_B_24HOUR_MODE
  182. mov al, 0bh
  183. CMOS_WRITE ; Initialize it
  184. mov al,0CH ; Register C
  185. CMOS_READ ; Read to initialize
  186. mov al,0DH ; Register D
  187. CMOS_READ ; Read to initialize
  188. stdCall _HalpReleaseCmosSpinLock
  189. xor eax, eax ; return STATUS_SUCCESS
  190. stdRET _HalpSetWakeAlarm
  191. stdENDP _HalpSetWakeAlarm
  192. _TEXT$03 ends
  193. PAGELK SEGMENT DWORD PUBLIC 'CODE'
  194. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  195. ;++
  196. ;
  197. ; VOID
  198. ; HalpSetClockBeforeSleep (
  199. ; VOID
  200. ; )
  201. ;
  202. ; Routine Description:
  203. ;
  204. ; This routine sets the RTC such that it will not generate
  205. ; periodic interrupts while the machine is sleeping, as this
  206. ; could be interpretted as an RTC wakeup event.
  207. ;
  208. ; Arguments:
  209. ;
  210. ; Return Value:
  211. ;
  212. ; None
  213. ;
  214. ;--
  215. cPublicProc _HalpSetClockBeforeSleep, 0
  216. cPublicFpo 0, 0
  217. stdCall _HalpAcquireCmosSpinLock
  218. mov al, 0ah
  219. CMOS_READ
  220. mov _HalpRtcRegA, al ; save RTC Register A
  221. or al, al
  222. jnz @f ; TEMP - debug stop
  223. int 3 ; looking for reg-a corruption
  224. @@:
  225. mov al, 0bh
  226. CMOS_READ
  227. mov _HalpRtcRegB, al ; save RTC Register B
  228. and al, not REGISTER_B_ENABLE_PERIODIC_INTERRUPT
  229. or al, REGISTER_B_24HOUR_MODE
  230. mov ah, al
  231. mov al, 0bh
  232. CMOS_WRITE ; Initialize it
  233. mov al,0CH ; Register C
  234. CMOS_READ ; Read to initialize
  235. mov al,0DH ; Register D
  236. CMOS_READ ; Read to initialize
  237. stdCall _HalpReleaseCmosSpinLock
  238. stdRET _HalpSetClockBeforeSleep
  239. stdENDP _HalpSetClockBeforeSleep
  240. ;++
  241. ;
  242. ; VOID
  243. ; HalpSetClockAfterSleep (
  244. ; VOID
  245. ; )
  246. ;
  247. ; Routine Description:
  248. ;
  249. ; This routine sets the RTC back to the way it was
  250. ; before a call to HalpSetClockBeforeSleep.
  251. ;
  252. ; Arguments:
  253. ;
  254. ; Return Value:
  255. ;
  256. ; None
  257. ;
  258. ;--
  259. cPublicProc _HalpSetClockAfterSleep, 0
  260. cPublicFpo 0, 0
  261. stdCall _HalpAcquireCmosSpinLock
  262. mov ah, _HalpRtcRegA ; restore RTC Register A
  263. mov al, 0ah
  264. CMOS_WRITE
  265. mov ah, _HalpRtcRegB ; restore RTC Register B
  266. and ah, not REGISTER_B_ENABLE_ALARM_INTERRUPT
  267. or ah, REGISTER_B_24HOUR_MODE
  268. mov al, 0bh
  269. CMOS_WRITE ; Initialize it
  270. mov al,0CH ; Register C
  271. CMOS_READ ; Read to initialize
  272. mov al,0DH ; Register D
  273. CMOS_READ ; Read to initialize
  274. stdCall _HalpReleaseCmosSpinLock
  275. stdRET _HalpSetClockAfterSleep
  276. stdENDP _HalpSetClockAfterSleep
  277. PAGELK ends
  278. end