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.

255 lines
5.0 KiB

  1. // TITLE ("Memory Fences, Load Acquires and Store Acquires")
  2. /*++
  3. Copyright (c) 1995 Intel Corporation
  4. Module Name:
  5. i64itm.s assembly routines for updating ITM.
  6. Abstract:
  7. This module implements the I/O port access routines.
  8. Author:
  9. Bernard Lint, M. Jayakumar 17 Sep '97
  10. Environment:
  11. Kernel mode
  12. Revision History:
  13. --*/
  14. #include "ksia64.h"
  15. .file "i64itm.s"
  16. .global HalpClockCount
  17. .global HalpITMUpdateLatency
  18. .global HalpITCTicksPer100ns
  19. // Temp until compiler fixed
  20. LEAF_ENTRY(HalpInitLINT)
  21. LEAF_SETUP(1,0,0,0)
  22. mov t0 = 0x10000
  23. ;;
  24. mov cr.lrr0 = t0
  25. mov cr.lrr1 = t0
  26. ;;
  27. // Clear pending interrupts from irr's
  28. // read ivr until spurious (0xf)
  29. // set tpr level to zero to unmask all ints
  30. mov t2 = cr.tpr
  31. ;;
  32. mov cr.tpr = zero
  33. ;;
  34. srlz.d
  35. mov t0 = 0xf
  36. ;;
  37. Hil_loop:
  38. mov t1 = cr.ivr
  39. ;;
  40. cmp.ne pt0 = t0, t1
  41. ;;
  42. (pt0) mov cr.eoi = zero
  43. (pt0) br.spnt Hil_loop
  44. // Restore tpr
  45. mov cr.tpr = t2
  46. ;;
  47. srlz.d
  48. LEAF_RETURN
  49. LEAF_EXIT(HalpInitLINT)
  50. /*++
  51. BOOLEAN
  52. HalpDisableInterrupts (
  53. )
  54. Routine Description:
  55. This function disables interrupts.
  56. Arguements:
  57. None.
  58. Return Value:
  59. TRUE if interrupts were previously enabled else FALSE
  60. --*/
  61. LEAF_ENTRY(HalpDisableInterrupts)
  62. mov t0 = psr
  63. mov v0 = TRUE // set return value -- TRUE if enabled
  64. ;;
  65. tbit.z pt1 = t0, PSR_I // pt1 = 1 if disabled
  66. ;;
  67. FAST_DISABLE_INTERRUPTS
  68. (pt1) mov v0 = FALSE // FALSE if disabled
  69. br.ret.sptk brp
  70. LEAF_EXIT(HalpDisableInterrupts)
  71. /*++
  72. VOID
  73. HalpTurnOffInterrupts (
  74. VOID
  75. )
  76. Routine Description:
  77. This function turns off interrupts and interruption resources collection.
  78. Arguements:
  79. None.
  80. Return Value:
  81. None.
  82. --*/
  83. LEAF_ENTRY(HalpTurnOffInterrupts)
  84. rsm 1 << PSR_I
  85. ;;
  86. rsm 1 << PSR_IC
  87. ;;
  88. srlz.d
  89. LEAF_RETURN
  90. LEAF_EXIT(HalpTurnOffInterrupts)
  91. /*++
  92. VOID
  93. HalpTurnOnInterrupts (
  94. VOID
  95. )
  96. Routine Description:
  97. This function turns on interruption resources collection and interrupts.
  98. Arguements:
  99. None.
  100. Return Value:
  101. None.
  102. --*/
  103. LEAF_ENTRY(HalpTurnOnInterrupts)
  104. ssm 1 << PSR_IC // set PSR.ic bit again
  105. ;;
  106. srlz.i // serialize
  107. ;;
  108. ssm 1 << PSR_I // set PSR.i bit again
  109. LEAF_RETURN
  110. LEAF_EXIT(HalpTurnOnInterrupts)
  111. /*++
  112. VOID
  113. HalpSetNextClockInterrupts (
  114. VOID
  115. )
  116. Routine Description:
  117. This function reads the current ITC and updates accordingly the ITM
  118. register with interruption resources collection and interrupts off.
  119. The interruption resources collection and interrupts are turned on
  120. returning to the caller.
  121. Arguements:
  122. None.
  123. Return Value:
  124. currentITCValue - previousITMValue.
  125. --*/
  126. LEAF_ENTRY(HalpSetNextClockInterrupt)
  127. .regstk 0, 2, 0, 0
  128. alloc r2 = 0, 2, 0, 0
  129. addl r31 = @gprel(HalpClockCount),gp
  130. movl r9 = KiPcr+PcHalReserved // CURRENT_ITM_VALUE_INDEX = 0
  131. addl r30 = @gprel(HalpITMUpdateLatency),gp
  132. ;;
  133. ld8.acq r11 = [r9] // r11 = currentITMValue
  134. ld8 r10 = [r31] // r10 = HalpClockCount
  135. ;;
  136. // 08/16/2000 TF
  137. // We should check if r11 == cr.itm here...
  138. //
  139. add r32 = r11, r10 // r32 = compareITCValue = currentITMValue + HalpClockCount
  140. ;;
  141. rsm 1 << PSR_I
  142. ;;
  143. rsm 1 << PSR_IC
  144. ;;
  145. srlz.d
  146. retry_itm_read:
  147. mov cr.itm = r32 // set itm with the most common scenario
  148. ;;
  149. mov r30 = cr.itm
  150. retry_itc_read:
  151. mov r33 = ar.itc // r33 = currentITCValue
  152. ;;
  153. cmp.ne pt2 = r30, r32
  154. (pt2) br.cond.spnt retry_itm_read // this should not be taken,
  155. // this just makes sure itm is actually written
  156. #ifndef DISABLE_ITC_WORKAROUND
  157. cmp4.eq pt1 = -1, r33 // if lower 32 bits equal 0xffffffff
  158. (pt1) br.cond.spnt retry_itc_read
  159. ;;
  160. #endif // DISABLE_ITC_WORKAROUND
  161. sub r30 = r32, r33 // calculate a ITM/ITC delta
  162. ;;
  163. cmp.lt pt0 = r30, r0 // if a delta is negative set pt0
  164. ;;
  165. (pt0) add r32 = r32, r10 // r32 = updated currentITMValue + HalpClockCount
  166. (pt0) br.cond.spnt retry_itm_read
  167. ;;
  168. ssm 1 << PSR_IC // set PSR.ic bit again
  169. ;;
  170. srlz.d // serialize
  171. ssm 1 << PSR_I // set PSR.i bit again
  172. st8 [r9] = r32
  173. sub r8 = r33, r11 // r8 = currentITCValue - previousITMValue
  174. LEAF_RETURN
  175. LEAF_EXIT(HalpSetNextClockInterrupt)