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.

421 lines
11 KiB

  1. // TITLE("Miscellaneous Kernel Functions")
  2. //++
  3. //
  4. // Copyright (c) 1990 Microsoft Corporation
  5. //
  6. // Module Name:
  7. //
  8. // miscs.s
  9. //
  10. // Abstract:
  11. //
  12. // This module implements machine dependent miscellaneous kernel functions.
  13. // Functions are provided to request a software interrupt, continue thread
  14. // execution, and perform last chance exception processing.
  15. //
  16. // Author:
  17. //
  18. // David N. Cutler (davec) 31-Mar-1990
  19. //
  20. // Environment:
  21. //
  22. // Kernel mode only.
  23. //
  24. // Revision History:
  25. //
  26. // Thomas Van Baak (tvb) 29-Jul-1992
  27. //
  28. // Adapted for Alpha AXP.
  29. //
  30. //--
  31. #include "ksalpha.h"
  32. SBTTL("Request Software Interrupt")
  33. //++
  34. //
  35. // VOID
  36. // KiRequestSoftwareInterrupt (
  37. // KIRQL RequestIrql
  38. // )
  39. //
  40. // Routine Description:
  41. //
  42. // This function requests a software interrupt at the specified IRQL
  43. // level.
  44. //
  45. // Arguments:
  46. //
  47. // RequestIrql (a0) - Supplies the requested IRQL value.
  48. //
  49. // Return Value:
  50. //
  51. // None.
  52. //
  53. //--
  54. LEAF_ENTRY(KiRequestSoftwareInterrupt)
  55. //
  56. // If an interrupt routine is active, do not request an interrupt from the
  57. // PAL. Indicate the interrupt has been requested in the PRCB. The interrupt
  58. // exit code will dispatch the software interrupt directly.
  59. //
  60. GET_PROCESSOR_CONTROL_BLOCK_BASE // get current prcb address
  61. LDP t0, PbInterruptTrapFrame(v0) // get interrupt trap frame
  62. beq t0, 10f // if eq, no interrupt active
  63. blbs a0, 10f // if lbs, APC interrupt requested
  64. stl a0, PbSoftwareInterrupts(v0) // set interrupt request bit in PRCB
  65. ret zero, (ra) //
  66. //
  67. // Request software interrupt.
  68. //
  69. 10: REQUEST_SOFTWARE_INTERRUPT // request software interrupt
  70. ret zero, (ra) // return
  71. .end KiRequestSoftwareInterrupt
  72. SBTTL("Continue Execution System Service")
  73. //++
  74. //
  75. // NTSTATUS
  76. // NtContinue (
  77. // IN PCONTEXT ContextRecord,
  78. // IN BOOLEAN TestAlert
  79. // )
  80. //
  81. // Routine Description:
  82. //
  83. // This routine is called as a system service to continue execution after
  84. // an exception has occurred. Its function is to transfer information from
  85. // the specified context record into the trap frame that was built when the
  86. // system service was executed, and then exit the system as if an exception
  87. // had occurred.
  88. //
  89. // Arguments:
  90. //
  91. // ContextRecord (a0) - Supplies a pointer to a context record.
  92. //
  93. // TestAlert (a1) - Supplies a boolean value that specifies whether alert
  94. // should be tested for the previous processor mode.
  95. //
  96. // N.B. Register fp is assumed to contain the address of a trap frame.
  97. //
  98. // Return Value:
  99. //
  100. // Normally there is no return from this routine. However, if the specified
  101. // context record is misaligned or is not accessible, then the appropriate
  102. // status code is returned.
  103. //
  104. //--
  105. NESTED_ENTRY(NtContinue, ExceptionFrameLength, zero)
  106. lda sp, -ExceptionFrameLength(sp) // allocate exception frame
  107. stq ra, ExIntRa(sp) // save return address
  108. PROLOGUE_END
  109. //
  110. // Save the nonvolatile machine state so that it can be restored by exception
  111. // exit if it is not overwritten by the specified context record.
  112. //
  113. stq s0, ExIntS0(sp) // save nonvolatile integer state
  114. stq s1, ExIntS1(sp) //
  115. stq s2, ExIntS2(sp) //
  116. stq s3, ExIntS3(sp) //
  117. stq s4, ExIntS4(sp) //
  118. stq s5, ExIntS5(sp) //
  119. stt f2, ExFltF2(sp) // save nonvolatile floating state
  120. stt f3, ExFltF3(sp) //
  121. stt f4, ExFltF4(sp) //
  122. stt f5, ExFltF5(sp) //
  123. stt f6, ExFltF6(sp) //
  124. stt f7, ExFltF7(sp) //
  125. stt f8, ExFltF8(sp) //
  126. stt f9, ExFltF9(sp) //
  127. //
  128. // Transfer information from the context frame to the exception and trap
  129. // frames.
  130. //
  131. mov a1, s0 // preserve test alert argument in s0
  132. mov sp, a1 // set address of exception frame
  133. mov fp, a2 // set address of trap frame
  134. bsr ra, KiContinue // transfer context to kernel frames
  135. //
  136. // If the kernel continuation routine returns success, then exit via the
  137. // exception exit code. Otherwise return to the system service dispatcher.
  138. //
  139. bne v0, 20f // if ne, transfer failed
  140. //
  141. // Check to determine if alert should be tested for the previous processor
  142. // mode and restore the previous mode in the thread object.
  143. //
  144. GET_CURRENT_THREAD // get current thread address
  145. LDP t3, TrTrapFrame(fp) // get old trap frame address
  146. ldl t2, TrPreviousMode(fp) // get old previous mode
  147. LoadByte(a0, ThPreviousMode(v0)) // get current previous mode
  148. STP t3, ThTrapFrame(v0) // restore old trap frame address
  149. StoreByte(t2, ThPreviousMode(v0)) // restore old previous mode
  150. beq s0, 10f // if eq, don't test for alert
  151. bsr ra, KeTestAlertThread // test alert for current thread
  152. //
  153. // Exit the system via exception exit which will restore the nonvolatile
  154. // machine state.
  155. //
  156. 10: br zero, KiExceptionExit // finish in exception exit
  157. //
  158. // Context record is misaligned or not accessible.
  159. //
  160. 20: ldq ra, ExIntRa(sp) // restore return address
  161. lda sp, ExceptionFrameLength(sp) // deallocate stack frame
  162. ret zero, (ra) // return
  163. .end NtContinue
  164. SBTTL("Raise Exception System Service")
  165. //++
  166. //
  167. // NTSTATUS
  168. // NtRaiseException (
  169. // IN PEXCEPTION_RECORD ExceptionRecord,
  170. // IN PCONTEXT ContextRecord,
  171. // IN BOOLEAN FirstChance
  172. // )
  173. //
  174. // Routine Description:
  175. //
  176. // This routine is called as a system service to raise an exception.
  177. // The exception can be raised as a first or second chance exception.
  178. //
  179. // Arguments:
  180. //
  181. // ExceptionRecord (a0) - Supplies a pointer to an exception record.
  182. //
  183. // ContextRecord (a1) - Supplies a pointer to a context record.
  184. //
  185. // FirstChance (a2) - Supplies a boolean value that determines whether
  186. // this is the first (TRUE) or second (FALSE) chance for dispatching
  187. // the exception.
  188. //
  189. // N.B. Register fp is assumed to contain the address of a trap frame.
  190. //
  191. // Return Value:
  192. //
  193. // Normally there is no return from this routine. However, if the specified
  194. // context record or exception record is misaligned or is not accessible,
  195. // then the appropriate status code is returned.
  196. //
  197. //--
  198. NESTED_ENTRY(NtRaiseException, ExceptionFrameLength, zero)
  199. lda sp, -ExceptionFrameLength(sp) // allocate exception frame
  200. stq ra, ExIntRa(sp) // save return address
  201. stq s0, ExIntS0(sp) // save S0 and S1 in the prologue
  202. stq s1, ExIntS1(sp) // so that Get/SetContext can find
  203. // the right ones.
  204. PROLOGUE_END
  205. //
  206. // Save the nonvolatile machine state so that it can be restored by exception
  207. // exit if it is not overwritten by the specified context record.
  208. //
  209. stq s2, ExIntS2(sp) //
  210. stq s3, ExIntS3(sp) //
  211. stq s4, ExIntS4(sp) //
  212. stq s5, ExIntS5(sp) //
  213. stt f2, ExFltF2(sp) // save nonvolatile floating state
  214. stt f3, ExFltF3(sp) //
  215. stt f4, ExFltF4(sp) //
  216. stt f5, ExFltF5(sp) //
  217. stt f6, ExFltF6(sp) //
  218. stt f7, ExFltF7(sp) //
  219. stt f8, ExFltF8(sp) //
  220. stt f9, ExFltF9(sp) //
  221. //
  222. // Call the raise exception kernel routine which will marshall the arguments
  223. // and then call the exception dispatcher.
  224. //
  225. // KiRaiseException requires five arguments: the first two are the same as
  226. // the first two of this function and the other three are set here.
  227. //
  228. mov a2, a4 // set first chance argument
  229. mov sp, a2 // set address of exception frame
  230. mov fp, a3 // set address of trap frame
  231. bsr ra, KiRaiseException // call raise exception routine
  232. //
  233. // If the raise exception routine returns success, then exit via the exception
  234. // exit code. Otherwise return to the system service dispatcher.
  235. //
  236. bis v0, zero, t0 // save return status
  237. LDP t1, TrTrapFrame(fp) // get old trap frame address
  238. GET_CURRENT_THREAD // get current thread address
  239. bne t0, 10f // if ne, dispatch not successful
  240. STP t1, ThTrapFrame(v0) // restore old trap frame address
  241. //
  242. // Exit the system via exception exit which will restore the nonvolatile
  243. // machine state.
  244. //
  245. br zero, KiExceptionExit // finish in exception exit
  246. //
  247. // The context or exception record is misaligned or not accessible, or the
  248. // exception was not handled.
  249. //
  250. 10: ldq ra, ExIntRa(sp) // restore return address
  251. lda sp, ExceptionFrameLength(sp) // deallocate stack frame
  252. ret zero, (ra) // return
  253. .end NtRaiseException
  254. SBTTL("Instruction Memory Barrier")
  255. //++
  256. //
  257. // VOID
  258. // KiImb (
  259. // VOID
  260. // )
  261. //
  262. // Routine Description:
  263. //
  264. // This routine is called to flush the instruction cache on the
  265. // current processor.
  266. //
  267. // Arguments:
  268. //
  269. // None.
  270. //
  271. // Return Value:
  272. //
  273. // None.
  274. //
  275. //--
  276. LEAF_ENTRY(KiImb)
  277. IMB // flush the icache via PALcode
  278. ret zero, (ra) // return
  279. .end KiImb
  280. SBTTL("Memory Barrier")
  281. //++
  282. //
  283. // VOID
  284. // KiImb (
  285. // VOID
  286. // )
  287. //
  288. // Routine Description:
  289. //
  290. // This routine is called to issue a memory barrier on the current
  291. // processor.
  292. //
  293. // Arguments:
  294. //
  295. // None.
  296. //
  297. // Return Value:
  298. //
  299. // None.
  300. //
  301. //--
  302. LEAF_ENTRY(KiMb)
  303. mb // memory barrier
  304. ret zero, (ra) // return
  305. .end KiMb
  306. //++
  307. //
  308. // VOID
  309. // KiEnablePALAlignmentFixups(
  310. // VOID
  311. // )
  312. //
  313. // Routine Description:
  314. //
  315. // Enable PAL fixups and PAL counting of alignment faults.
  316. //
  317. // Arguments:
  318. //
  319. // None
  320. //
  321. // Return Value:
  322. //
  323. // None.
  324. //
  325. //--
  326. LEAF_ENTRY(KiEnablePALAlignmentFixups)
  327. ENABLE_ALIGNMENT_FIXUPS // enable alignment fixups
  328. ret zero, (ra) // return
  329. .end KiEnablePALAlignmentFixups
  330. //++
  331. //
  332. // VOID
  333. // KiDisablePALAlignmentFixups(
  334. // VOID
  335. // )
  336. //
  337. // Routine Description:
  338. //
  339. // Disable PAL fixups and force all alignment faults to
  340. // the kernel.
  341. //
  342. // Arguments:
  343. //
  344. // None
  345. //
  346. // Return Value:
  347. //
  348. // None.
  349. //
  350. //--
  351. LEAF_ENTRY(KiDisablePALAlignmentFixups)
  352. DISABLE_ALIGNMENT_FIXUPS // disable alignment fixups
  353. ret zero, (ra) // return
  354. .end KiDisablePALAlignmentFixups
  355.