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.

110 lines
3.1 KiB

  1. // TITLE("Asynchronous Procedure Call (APC) Interrupt")
  2. //++
  3. //
  4. // Copyright (c) 1990 Microsoft Corporation
  5. //
  6. // Module Name:
  7. //
  8. // apcint.s
  9. //
  10. // Abstract:
  11. //
  12. // This module implements the code necessary to field and process the
  13. // Asynchronous Procedure Call (APC) interrupt.
  14. //
  15. // Author:
  16. //
  17. // David N. Cutler (davec) 3-Apr-1990
  18. // Joe Notarangelo 15-Jul-1992 alpha version
  19. //
  20. // Environment:
  21. //
  22. // Kernel mode only, IRQL APC_LEVEL.
  23. //
  24. // Revision History:
  25. //
  26. //--
  27. #include "ksalpha.h"
  28. SBTTL("Asynchronous Procedure Call Interrupt")
  29. //++
  30. //
  31. // Routine Description:
  32. //
  33. // This routine is entered as the result of a software interrupt generated
  34. // at APC_LEVEL. Its function is to allocate an exception frame and call
  35. // the kernel APC delivery routine to deliver kernel mode APCs and to check
  36. // if a user mode APC should be delivered. If a user mode APC should be
  37. // delivered, then the kernel APC delivery routine constructs a context
  38. // frame on the user stack and alters the exception and trap frames so that
  39. // control will be transfered to the user APC dispatcher on return from the
  40. // interrupt.
  41. //
  42. // N.B. On entry to this routine only the volatile integer registers have
  43. // been saved. The remainder of the machine state is saved if and only
  44. // if the previous mode was user mode. It is assumed that none of the
  45. // APC delivery code, nor any of the kernel mode APC routines themselves
  46. // use any floating point instructions.
  47. //
  48. // Arguments:
  49. //
  50. // s6/fp - Supplies a pointer to a trap frame.
  51. //
  52. // Return Value:
  53. //
  54. // None.
  55. //
  56. //--
  57. NESTED_ENTRY(KiApcInterrupt, ExceptionFrameLength, zero)
  58. lda sp, -ExceptionFrameLength(sp) // allocate exception frame
  59. stq ra, ExIntRa(sp) // save return address
  60. PROLOGUE_END
  61. //
  62. // Save the volatile floating state and determine the previous mode.
  63. //
  64. bsr ra, KiSaveVolatileFloatState // save volatile floats
  65. ldl t0, TrPsr(fp) // get saved processor status
  66. and t0, PSR_MODE_MASK, a0 // isolate previous mode
  67. beq a0, 10f // if eq, kernel mode
  68. //
  69. // The previous mode was user.
  70. //
  71. // Save the nonvolatile machine state so a context record can be
  72. // properly constructed to deliver an APC to user mode if required.
  73. // It is also necessary to save the volatile floating state for
  74. // suspend/resume operations.
  75. //
  76. stq s0, ExIntS0(sp) // save nonvolatile integer state
  77. stq s1, ExIntS1(sp) //
  78. stq s2, ExIntS2(sp) //
  79. stq s3, ExIntS3(sp) //
  80. stq s4, ExIntS4(sp) //
  81. stq s5, ExIntS5(sp) //
  82. bsr ra, KiSaveNonVolatileFloatState // save floating state
  83. //
  84. // Attempt to deliver an APC.
  85. //
  86. 10: bis sp, zero, a1 // set address of exception frame
  87. bis fp, zero, a2 // set address of trap frame
  88. bsr ra, KiDeliverApc // call APC delivery routine
  89. //
  90. // Restore the volatile floating state and return from the interrupt.
  91. //
  92. bsr ra, KiRestoreVolatileFloatState // restore floating state
  93. ldq ra, ExIntRa(sp) // restore return address
  94. lda sp, ExceptionFrameLength(sp) // deallocate exception frame
  95. ret zero, (ra) // return
  96. .end KiApcInterrupt
  97.