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.

190 lines
5.9 KiB

  1. // TITLE("LPC Move Message Support")
  2. //++
  3. //
  4. // Copyright (c) 1990 Microsoft Corporation
  5. // Copyright (c) 1992 Digital Equipment Corporation
  6. //
  7. // Module Name:
  8. //
  9. // lpcmove.s
  10. //
  11. // Abstract:
  12. //
  13. // This module implements functions to support the efficient movement of
  14. // LPC Message blocks.
  15. //
  16. // Author:
  17. //
  18. // David N. Cutler (davec) 11-Apr-1990
  19. //
  20. // Environment:
  21. //
  22. // Kernel mode only.
  23. //
  24. // Revision History:
  25. //
  26. // Thomas Van Baak (tvb) 19-May-1992
  27. //
  28. // Adapted for Alpha AXP.
  29. //
  30. //--
  31. #include "ksalpha.h"
  32. SBTTL("Move Message")
  33. //++
  34. //
  35. // VOID
  36. // LpcpMoveMessage (
  37. // OUT PPORT_MESSAGE DstMsg
  38. // IN PPORT_MESSAGE SrcMsg
  39. // IN PUCHAR SrcMsgData
  40. // IN ULONG MsgType OPTIONAL,
  41. // IN PCLIENT_ID ClientId OPTIONAL
  42. // )
  43. //
  44. // Routine Description:
  45. //
  46. // This function moves an LPC message block and optionally sets the message
  47. // type and client id to the specified values.
  48. //
  49. // Arguments:
  50. //
  51. // DstMsg (a0) - Supplies a pointer to the destination message.
  52. //
  53. // SrcMsg (a1) - Supplies a pointer to the source message.
  54. //
  55. // SrcMsgData (a2) - Supplies a pointer to the source message data to
  56. // copy to destination.
  57. //
  58. // MsgType (a3) - If non-zero, then store in type field of the destination
  59. // message.
  60. //
  61. // ClientId (a4) - If non-NULL, then points to a ClientId to copy to
  62. // the destination message.
  63. //
  64. // N.B. The messages are assumed to be quadword aligned.
  65. //
  66. // Return Value:
  67. //
  68. // None.
  69. //
  70. //--
  71. LEAF_ENTRY(LpcpMoveMessage)
  72. ldq t0, PmLength(a1) // load first quadword of source
  73. //
  74. // The message length is in the low word of the first quadword.
  75. //
  76. addq t0, 3, t1 // round length to
  77. bic t1, 3, t0 // nearest 4-byte multiple
  78. //
  79. // The message type is in the low half of the high longword. If a message
  80. // type was specified, use it instead of the message type in the source
  81. // message.
  82. //
  83. sll a3, 32, t2 // shift message type into position
  84. zap t0, 0x30, t3 // clear message type field
  85. or t3, t2, t1 // merge into new field
  86. cmovne a3, t1, t0 // if a3!=0 use new message field
  87. stq t0, PmLength(a0) // store first quadword of destination
  88. //
  89. // The client id is the third and fourth items. If a client id was
  90. // specified, use it instead of the client id in the source message.
  91. //
  92. lda t3, PmClientId(a1) // get address of source client id
  93. cmovne a4, a4, t3 // if a4!=0, use client id address in a4
  94. //
  95. // Move the process and thread ids into place. Note that for axp32, (t3) isn't
  96. // necessarily quadword aligned.
  97. //
  98. LDP t2, CidUniqueProcess(t3)// load low part of client id
  99. LDP t1, CidUniqueThread(t3) // load high part of client id
  100. STP t2, PmProcess(a0) // store third longword of destination
  101. STP t1, PmThread(a0) // store fourth longword of destination
  102. #if defined(_AXP64_)
  103. //
  104. // Copy MessageId and ClientViewSize.
  105. //
  106. ldl t2,PmMessageId(a1)
  107. stl t2,PmMessageId(a0)
  108. ldq t2,PmClientViewSize(a1)
  109. stq t2,PmClientViewSize(a0)
  110. #else
  111. //
  112. // PmClientViewSize is adjacent to PmMessageId, both can be moved at once
  113. // with a single quadword move.
  114. //
  115. ldq t2,PmMessageId(a1) // get next quadword of source
  116. stq t2,PmMessageId(a0) // set next quadword of destination
  117. #endif
  118. and t0, 0xfff8, t3 // isolate quadword move count
  119. beq t3,20f // if eq, no quadwords to move
  120. and a2, 7, t1 // check if source is quadword aligned
  121. bne t1, UnalignedSource // if ne, not quadword aligned
  122. //
  123. // Source and destination are both quadword aligned, use ldq/stq. Use of
  124. // the constant "PortMessageLength-8" is used in lieu of an additional
  125. // instruction to increment a0 by that amount before entering the copy
  126. // loop.
  127. //
  128. 5: ldq t1, 0(a2) // get source qword
  129. ADDP a0, 8, a0 // advance destination address
  130. ADDP a2, 8, a2 // advance source address
  131. subq t3, 8, t3 // decrement number of bytes remaining
  132. stq t1, PortMessageLength-8(a0) // store destination qword
  133. bne t3, 5b // if ne, more quadwords to store
  134. br zero, 20f // move remaining longword
  135. //
  136. // We know that the destination is quadword aligned, but the source is
  137. // not. Use ldq_u to load the low and high parts of the source quadword,
  138. // merge them with EXTQx and store them as one quadword.
  139. //
  140. // By reusing the result of the second ldq_u as the source for the
  141. // next quadword's EXTQL we end up doing one ldq_u/stq for each quadword,
  142. // regardless of the source's alignment.
  143. //
  144. UnalignedSource: //
  145. ldq_u t1, 0(a2) // prime t1 with low half of qword
  146. 10: extql t1, a2, t2 // t2 is aligned low part
  147. ADDP a0, 8, a0 // advance destination address
  148. subq t3, 8, t3 // reduce number of bytes remaining
  149. ldq_u t1, 7(a2) // t1 has high part
  150. extqh t1, a2, t4 // t4 is aligned high part
  151. ADDP a2, 8, a2 // advance source address
  152. bis t2, t4, t5 // merge high and low parts
  153. stq t5, PortMessageLength-8(a0) // store result
  154. bne t3, 10b // if ne, more quadwords to move
  155. //
  156. // Move remaining longword (if any)
  157. //
  158. 20: and t0, 4, t0 // check if longword to move
  159. beq t0, 50f // if eq, no longword to move
  160. ldl t1, 0(a2) // move last longword to move
  161. stl t1, PortMessageLength(a0) //
  162. 50: ret zero, (ra) // return
  163. .end LpcpMoveMessage