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.

205 lines
5.8 KiB

4 years ago
  1. // TITLE("Clock and Eisa Interrupt Handlers")
  2. //++
  3. //
  4. // Copyright (c) 1993 Digital Equipment Corporation
  5. //
  6. // Module Name:
  7. //
  8. // jxintsup.s
  9. //
  10. // Abstract:
  11. //
  12. // This module implements the first level interrupt handlers
  13. // for JENSEN.
  14. //
  15. // Author:
  16. //
  17. // Joe Notarangelo 08-Jul-1993
  18. //
  19. // Environment:
  20. //
  21. // Kernel mode only.
  22. //
  23. // Revision History:
  24. //
  25. //--
  26. #include "ksalpha.h"
  27. #include "jnsnrtc.h"
  28. SBTTL("System Clock Interrupt")
  29. //++
  30. //
  31. // VOID
  32. // HalpClockInterrupt(
  33. // )
  34. //
  35. // Routine Description:
  36. //
  37. // This function is executed for each interval timer interrupt on
  38. // the JENSEN. The routine is responsible for acknowledging the
  39. // interrupt and calling the kernel to update the system time.
  40. // In addition, this routine checks for breakins from the kernel debugger
  41. // and maintains the 64 bit performance counter based upon the
  42. // processor cycle counter.
  43. //
  44. // Arguments:
  45. //
  46. // TrapFrame (fp/s6) - Supplies a pointer to the trap frame for
  47. // the interrupt.
  48. //
  49. // Return Value:
  50. //
  51. // None.
  52. //
  53. //--
  54. .struct 0
  55. .space 8 // filler for octaword alignment
  56. CiRa: .space 8 // space for return address
  57. CiFrameLength: //
  58. NESTED_ENTRY(HalpClockInterrupt, CiFrameLength, zero )
  59. lda sp, -CiFrameLength(sp) // allocate stack frame
  60. stq ra, CiRa(sp) // save return address
  61. PROLOGUE_END
  62. //
  63. // Acknowledge the clock interrupt, by reading the control register c of
  64. // the Real Time Clock in the 82C106 (VTI Combo Chip).
  65. //
  66. ldil a0, RTC_APORT // get the address port for rtc
  67. ldil a1, RTC_CONTROL_REGISTERC // address for control register
  68. bsr ra, HalpWriteVti // write the address port
  69. ldil a0, RTC_DPORT // get the data port for the rtc
  70. bsr ra, HalpReadVti // read the data port
  71. //
  72. // Call the kernel to update the system time.
  73. //
  74. ldl a1, HalpCurrentTimeIncrement
  75. bis fp, zero, a0 // a0 = pointer to trap frame
  76. ldl t0, __imp_KeUpdateSystemTime
  77. jsr ra, (t0) // call kernel to update system time
  78. ldl t0, HalpNextTimeIncrement // Get next time increment
  79. stl t0, HalpCurrentTimeIncrement // Set CurrentTimeIncrement to NextTimeIncrement
  80. ldl a0, HalpNextRateSelect // Get NextIntervalCount. If 0, no change required
  81. beq a0, 5f
  82. stl zero, HalpNextRateSelect // Set NextRateSelect to 0
  83. bsr ra, HalpProgramIntervalTimer // Program timer with new rate select
  84. ldl t0, HalpNewTimeIncrement // Get HalpNewTimeIncrement
  85. stl t0, HalpNextTimeIncrement // Set HalpNextTimeIncrement to HalpNewTimeIncrement
  86. 5:
  87. //
  88. // Update the 64-bit performance counter.
  89. //
  90. // N.B. - This code is careful to update the 64-bit counter atomically.
  91. //
  92. lda t0, HalpRpccTime // get address of 64-bit rpcc global
  93. ldq t4, 0(t0) // read rpcc global
  94. rpcc t1 // read processor cycle counter
  95. addl t1, zero, t1 // make t1 a longword
  96. addl t4, 0, t2 // get low longword of rpcc global
  97. cmpult t1, t2, t3 // is new rpcc < old rpcc
  98. bne t3, 10f // if ne[true] rpcc wrapped
  99. br zero, 20f // rpcc did not wrap
  100. //
  101. // The rpcc has wrapped, increment the high part of the 64-bit counter.
  102. //
  103. 10:
  104. lda t2, 1(zero) // t2 = 1
  105. sll t2, 32, t2 // t2 = 1 0000 0000
  106. addq t4, t2, t4 // increment high part by one
  107. 20:
  108. zap t4, 0x0f, t4 // clean low part of rpcc global
  109. zap t1, 0xf0, t1 // clean high part of rpcc
  110. addq t4, t1, t4 // merge new rpcc as low part of global
  111. stq t4, 0(t0) // store the updated counter
  112. #if DEVL
  113. //
  114. // Check for a breakin request from the kernel debugger.
  115. //
  116. ldl t0, __imp_KdPollBreakIn
  117. jsr ra, (t0) // check for breakin requested
  118. beq v0, 30f // if eq[false], no breakin
  119. ldl t0, __imp_DbgBreakPointWithStatus
  120. lda a0, DBG_STATUS_CONTROL_C
  121. jsr ra, (t0) // send status to debugger
  122. 30:
  123. #endif //DEVL
  124. //
  125. // Return to the caller.
  126. //
  127. ldq ra, CiRa(sp) // restore return address
  128. lda sp, CiFrameLength(sp) // deallocate stack frame
  129. ret zero, (ra) // return to caller
  130. .end HalpClockInterrupt
  131. SBTTL("Eisa Interrupt")
  132. //++
  133. //
  134. // VOID
  135. // HalpEisaInterruptHandler
  136. // IN PKINTERRUPT Interrupt,
  137. // IN PVOID ServiceContext
  138. // )
  139. //
  140. // Routine Description:
  141. //
  142. // This function is executed as the result of an interrupt on the EISA
  143. // bus. The function is responsible for calling HalpEisaDispatch to
  144. // appropriately dispatch the EISA interrupt.
  145. //
  146. // N.B. This function exists only to capture the trap frame and forward
  147. // the interrupt to HalpEisaDispatch.
  148. //
  149. // Arguments:
  150. //
  151. // Interrupt (a0) - Supplies a pointer to the interrupt object.
  152. //
  153. // ServiceContext (a1) - Supplies a pointer to the service context for
  154. // EISA interrupts.
  155. //
  156. // TrapFrame (fp/s6) - Supplies a pointer to the trap frame for
  157. // the interrupt.
  158. //
  159. // Return Value:
  160. //
  161. // None.
  162. //
  163. //--
  164. LEAF_ENTRY(HalpEisaInterruptHandler)
  165. bis fp, zero, a2 // capture trap frame as argument
  166. br zero, HalpEisaDispatch // dispatch the interrupt
  167. ret zero, (ra) // will never get here
  168. .end HalpEisaInterruptHandler