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.

1509 lines
36 KiB

  1. ;++
  2. ;
  3. ; Copyright (c) 1989 Microsoft Corporation
  4. ;
  5. ; Module Name:
  6. ;
  7. ; kimacro.inc
  8. ;
  9. ; Abstract:
  10. ;
  11. ; This module contains the macros used by kernel assembler code.
  12. ; It includes macros to manipulate interrupts, support system
  13. ; entry and exit for syscalls, faults, and interrupts, and
  14. ; manipulate floating point state.
  15. ;
  16. ; Author:
  17. ;
  18. ; Shie-Lin (shielint) 24-Jan-1990
  19. ;
  20. ; Revision History:
  21. ;
  22. ; BryanWi 17-Aug-90
  23. ; Replace GENERATE_MACHINE... and RESTORE... with ENTER_...
  24. ; and EXIT_ALL macros.
  25. ;
  26. ;--
  27. ;++
  28. ;
  29. ; These constants are used by the fpo directives in this file.
  30. ; This directive causes the assembler to output a .debug$f segment
  31. ; in the obj file. The segment will contain 1 fpo record for each
  32. ; directive present during assembly.
  33. ;
  34. ; Although the assembler will accept all valid values, the value of 7
  35. ; in the FPO_REGS field indicates to the debugger that a trap frame is
  36. ; generated by the function. The value of 7 can be used because the
  37. ; C/C++ compiler puts a maximum value of 3 in the field.
  38. ;
  39. FPO_LOCALS equ 0 ; 32 bits, size of locals in dwords
  40. FPO_PARAMS equ 0 ; 32 bits, size of parameters in dwords
  41. FPO_PROLOG equ 0 ; 12 bits, 0-4095, # of bytes in prolog
  42. FPO_REGS equ 0 ; 3 bits, 0-7, # regs saved in prolog
  43. FPO_USE_EBP equ 0 ; 1 bit, 0-1, is ebp used?
  44. FPO_TRAPFRAME equ 1 ; 2 bits, 0=fpo, 1=trap frame, 2=tss
  45. ;
  46. ;--
  47. ;++
  48. ;
  49. ; POLL_DEBUGGER
  50. ;
  51. ; Macro Description:
  52. ;
  53. ; Call the debugger so it can check for control-c. If it finds
  54. ; it, it will report our iret address as address of break-in.
  55. ;
  56. ; N.B. This macro should be used when all the caller's registers
  57. ; have been restored. (Otherwise, the kernel debugger register
  58. ; dump will not have correct state.) The only exception is
  59. ; fs. This is because Kd may need to access PCR or PRCB.
  60. ;
  61. ; Arguments:
  62. ;
  63. ; There MUST be an iret frame on the stack when this macro
  64. ; is invoked.
  65. ;
  66. ; Exit:
  67. ;
  68. ; Debugger will iret for us, so we don't usually return from
  69. ; this macro, but remember that it generates nothing for non-DEVL
  70. ; kernels.
  71. ;--
  72. POLL_DEBUGGER macro
  73. local a, b, c_
  74. if DEVL
  75. EXTRNP _DbgBreakPointWithStatus,1
  76. stdCall _KdPollBreakIn
  77. or al,al
  78. jz short c_
  79. stdCall _DbgBreakPointWithStatus,<DBG_STATUS_CONTROL_C>
  80. c_:
  81. endif ; DEVL
  82. endm
  83. ;++
  84. ;
  85. ; ASSERT_FS
  86. ;
  87. ; Try to catch funky condition wherein we get FS=r3 value while
  88. ; running in kernel mode.
  89. ;
  90. ;--
  91. ASSERT_FS macro
  92. local a,b
  93. if DBG
  94. EXTRNP _KeBugCheck,1
  95. mov bx,fs
  96. cmp bx,KGDT_R0_PCR
  97. jnz short a
  98. cmp dword ptr fs:[0], 0
  99. jne short b
  100. a:
  101. stdCall _KeBugCheck,<-1>
  102. align 4
  103. b:
  104. endif
  105. endm
  106. ;++
  107. ;
  108. ;
  109. ; Copy data from various places into base of TrapFrame, net effect
  110. ; is to allow dbg KB command to trace accross trap frame, and to
  111. ; allow user to find arguments to system calls.
  112. ;
  113. ; USE ebx and edi.
  114. ;--
  115. SET_DEBUG_DATA macro
  116. ife FPO
  117. ;
  118. ; This macro is used by ENTER_SYSTEM_CALL, ENTER_TRAP and ENTER_INTERRUPT
  119. ; and is used at the end of above macros. It is safe to destroy ebx, edi.
  120. ;
  121. mov ebx,[ebp]+TsEbp
  122. mov edi,[ebp]+TsEip
  123. mov [ebp]+TsDbgArgPointer,edx
  124. mov [ebp]+TsDbgArgMark,0BADB0D00h
  125. mov [ebp]+TsDbgEbp,ebx
  126. mov [ebp]+TsDbgEip,edi
  127. endif
  128. endm
  129. ;++
  130. ;
  131. ; ENTER_DR_ASSIST EnterLabel, ExitLabel, NoAbiosAssist, NoV86Assist
  132. ;
  133. ; Macro Description:
  134. ;
  135. ; Jumped to by ENTER_ macros to deal with DR register work,
  136. ; abios work and v86 work. The main purpose of this macro is
  137. ; that interrupt/trap/systemCall EnterMacros can jump here to
  138. ; deal with some special cases such that most of the times the
  139. ; main ENTER_ execution flow can proceed without being branched.
  140. ;
  141. ; If (previousmode == usermode) {
  142. ; save DR* in trapframe
  143. ; load DR* from Prcb
  144. ; }
  145. ;
  146. ; Arguments:
  147. ; EnterLabel - label to emit
  148. ; ExitLabel - label to branch to when done
  149. ;
  150. ; Entry-conditions:
  151. ; Dr work:
  152. ; DebugActive == TRUE
  153. ; (esi)->Thread object
  154. ; (esp)->base of trap frame
  155. ; (ebp)->base of trap frame
  156. ;
  157. ; Abios work:
  158. ; v86 work:
  159. ;
  160. ; Exit-conditions:
  161. ; Dr work:
  162. ; Interrupts match input state (this routine doesn't change IEF)
  163. ; (esp)->base of trap frame
  164. ; (ebp)->base of trap frame
  165. ; Preserves entry eax, edx
  166. ; Abios work:
  167. ; v86 work:
  168. ;
  169. ;--
  170. ENTER_DR_ASSIST macro EnterLabel, ExitLabel, NoAbiosAssist, NoV86Assist, V86R
  171. local a,b
  172. public Dr_&EnterLabel
  173. align 4
  174. Dr_&EnterLabel:
  175. ;
  176. ; Test if we came from user-mode. If not, do nothing.
  177. ;
  178. test dword ptr [ebp]+TsEFlags,EFLAGS_V86_MASK
  179. jnz short a
  180. test dword ptr [ebp]+TsSegCs,MODE_MASK
  181. jz Dr_&ExitLabel ; called from kmode, go continue
  182. ;
  183. ; Save user-mode Dr* regs in TrapFrame
  184. ;
  185. ; We are safe to destroy ebx, ecx, edi because in ENTER_INTERRUPT and
  186. ; ENTER_TRAP these registers are saved already. In ENTER_SYSTEMCALL
  187. ; ebx, edi is saved and ecx is don't-care.
  188. ;
  189. a: mov ebx,dr0
  190. mov ecx,dr1
  191. mov edi,dr2
  192. mov [ebp]+TsDr0,ebx
  193. mov [ebp]+TsDr1,ecx
  194. mov [ebp]+TsDr2,edi
  195. mov ebx,dr3
  196. mov ecx,dr6
  197. mov edi,dr7
  198. mov [ebp]+TsDr3,ebx
  199. mov [ebp]+TsDr6,ecx
  200. mov ebx,0
  201. mov [ebp]+TsDr7,edi
  202. ;
  203. ; Make Dr7 safe before loading junk from save area
  204. ;
  205. mov dr7,ebx
  206. ;
  207. ; Load KernelDr* into processor
  208. ;
  209. mov edi,dword ptr fs:[PcPrcb]
  210. mov ebx,[edi].PbProcessorState.PsSpecialRegisters.SrKernelDr0
  211. mov ecx,[edi].PbProcessorState.PsSpecialRegisters.SrKernelDr1
  212. mov dr0,ebx
  213. mov dr1,ecx
  214. mov ebx,[edi].PbProcessorState.PsSpecialRegisters.SrKernelDr2
  215. mov ecx,[edi].PbProcessorState.PsSpecialRegisters.SrKernelDr3
  216. mov dr2,ebx
  217. mov dr3,ecx
  218. mov ebx,[edi].PbProcessorState.PsSpecialRegisters.SrKernelDr6
  219. mov ecx,[edi].PbProcessorState.PsSpecialRegisters.SrKernelDr7
  220. mov dr6,ebx
  221. mov dr7,ecx
  222. ifnb <V86R>
  223. test dword ptr [ebp]+TsEFlags,EFLAGS_V86_MASK
  224. jz short b
  225. jmp Dr_&V86R
  226. endif
  227. b:
  228. jmp Dr_&ExitLabel
  229. ifb <NoAbiosAssist>
  230. public Abios_&EnterLabel
  231. align 4
  232. Abios_&EnterLabel:
  233. ;
  234. ; INTERRUPT_STACK16_TO_STACK32
  235. ;
  236. ; This macro remaps current 32bit stack to 16bit stack at interrupt
  237. ; time.
  238. ;
  239. ; Arguments:
  240. ;
  241. ; (esp)->trap frame.
  242. ; (eax)->Entry Esp.
  243. ;
  244. mov eax, [esp].TsErrCode ; (eax) = Entry Esp
  245. mov ecx, KGDT_R0_DATA
  246. mov edx, esp
  247. shl eax, 16
  248. add edx, fs:[PcstackLimit]
  249. mov [esp].TsErrCode, eax
  250. mov ss, cx
  251. mov esp, edx ; Interrupts are off
  252. mov ebp, edx
  253. jmp Abios_&ExitLabel
  254. endif ; NoAbiosAssist
  255. ifb <NoV86Assist>
  256. public V86_&EnterLabel
  257. align 4
  258. V86_&EnterLabel:
  259. ;
  260. ; Move the V86 segment registers to the correct place in the frame
  261. ;
  262. mov eax,dword ptr [ebp].TsV86Fs
  263. mov ebx,dword ptr [ebp].TsV86Gs
  264. mov ecx,dword ptr [ebp].TsV86Es
  265. mov edx,dword ptr [ebp].TsV86Ds
  266. mov [ebp].TsSegFs,ax
  267. mov [ebp].TsSegGs,bx
  268. mov [ebp].TsSegEs,cx
  269. mov [ebp].TsSegDs,dx
  270. jmp V86_&ExitLabel
  271. endif ; NoV86Assist
  272. endm
  273. ;++
  274. ;
  275. ; ENTER_SYSCALL AssistLabel, TagetLabel, NoFSLoad
  276. ;
  277. ; Macro Description:
  278. ;
  279. ; Build the frame and set registers needed by a system call.
  280. ;
  281. ; Save:
  282. ; Errorpad,
  283. ; Non-volatile regs,
  284. ; FS,
  285. ; ExceptionList,
  286. ; PreviousMode
  287. ;
  288. ; Don't Save:
  289. ; Volatile regs
  290. ; Seg regs
  291. ; Floating point state
  292. ;
  293. ; Set:
  294. ; FS,
  295. ; ExceptionList,
  296. ; PreviousMode,
  297. ; Direction
  298. ;
  299. ; Arguments:
  300. ; AssistLabel - label ENTER_ASSIST macro is at
  301. ; TargetLabel - label to emit for ENTER_ASSIST to jump to
  302. ; NoFSLoad - Don't set FS(it is already set to KGDT_R0_PCR at entry).
  303. ;
  304. ; Exit-conditions:
  305. ; Interrupts match input state (this routine doesn't change IEF)
  306. ; (esp)->base of trap frame
  307. ; (ebp)->base of trap frame
  308. ; Preserves entry eax, edx
  309. ;
  310. ; Note:
  311. ; The DS: reference to PreviousMode is *required* for correct
  312. ; functioning of lazy selector loads. If you remove this use
  313. ; of DS:, put a DS: override on something.
  314. ;
  315. ;--
  316. ENTER_SYSCALL macro AssistLabel, TargetLabel, NoFSLoad
  317. .FPO ( FPO_LOCALS, FPO_PARAMS, FPO_PROLOG, FPO_REGS, FPO_USE_EBP, FPO_TRAPFRAME )
  318. ifdef KERNELONLY
  319. ;
  320. ; Construct trap frame.
  321. ;
  322. ; N.B. The initial part of the trap frame is constructed by pushing values
  323. ; on the stack. If the format of the trap frame is changed, then the
  324. ; following code must alos be changed.
  325. ;
  326. push 0 ; put pad dword for error on stack
  327. push ebp ; save the non-volatile registers
  328. push ebx ;
  329. push esi ;
  330. push edi ;
  331. ifb <NoFSLoad>
  332. push fs ; save and set FS to PCR.
  333. mov ebx,KGDT_R0_PCR ; set PCR segment number
  334. mov fs,bx ;
  335. else
  336. ; FS already contains KGDT_R0_PCR(entry via PentiumPro fast system call)
  337. push KGDT_R3_TEB OR RPL_MASK
  338. endif ; NoFSLoad
  339. ;
  340. ; Save the old exception list in trap frame and initialize a new empty
  341. ; exception list.
  342. ;
  343. push PCR[PcExceptionList] ; save old exception list
  344. mov PCR[PcExceptionList],EXCEPTION_CHAIN_END ; set new empty list
  345. ;
  346. ; Save the old previous mode in trap frame, allocate remainder of trap frame,
  347. ; and set the new previous mode.
  348. ;
  349. mov esi,PCR[PcPrcbData+PbCurrentThread] ; get current thread address
  350. push [esi]+ThPreviousMode ; save old previous mode
  351. sub esp,TsPreviousPreviousMode ; allocate remainder of trap frame
  352. mov ebx,[esp+TsSegCS] ; compute new previous mode
  353. and ebx,MODE_MASK ;
  354. mov [esi]+ThPreviousMode,bl ; set new previous mode
  355. ;
  356. ; Save the old trap frame address and set the new trap frame address.
  357. ;
  358. mov ebp,esp ; set trap frame address
  359. mov ebx,[esi].ThTrapFrame ; save current trap frame address
  360. mov [ebp].TsEdx,ebx ;
  361. mov [esi].ThTrapFrame,ebp ; set new trap frame address
  362. cld ; make sure direction is forward
  363. SET_DEBUG_DATA ; Note this destroys edi
  364. test byte ptr [esi]+ThDebugActive,-1 ; test if debugging active
  365. jnz Dr_&AssistLabel ; if nz, debugging is active on thread
  366. Dr_&TargetLabel: ;
  367. sti ; enable interrupts
  368. else
  369. %out ENTER_SYSCAL outside of kernel
  370. .err
  371. endif
  372. endm
  373. ;++
  374. ;
  375. ; ENTER_INTERRUPT AssistLabel, TargetLabel
  376. ;
  377. ; Macro Description:
  378. ;
  379. ; Build the frame and set registers needed by an interrupt.
  380. ;
  381. ; Save:
  382. ; Errorpad,
  383. ; Non-volatile regs,
  384. ; FS,
  385. ; ExceptionList,
  386. ; PreviousMode
  387. ; Volatile regs
  388. ; Seg regs from V86 mode
  389. ; DS, ES, GS
  390. ;
  391. ; Don't Save:
  392. ; Floating point state
  393. ;
  394. ; Set:
  395. ; FS,
  396. ; ExceptionList,
  397. ; Direction,
  398. ; DS, ES
  399. ;
  400. ; Don't Set:
  401. ; PreviousMode
  402. ;
  403. ; Arguments:
  404. ; AssistLabel - label ENTER_ASSIST macro is at
  405. ; TargetLabel - label to emit for ENTER_ASSIST to jump to
  406. ;
  407. ; Exit-conditions:
  408. ; Interrupts match input state (this routine doesn't change IEF)
  409. ; (esp)->base of trap frame
  410. ; (ebp)->base of trap frame
  411. ; Preserves entry eax, ecx, edx
  412. ;
  413. ;--
  414. ENTER_INTERRUPT macro AssistLabel, TargetLabel, PassParm
  415. local b
  416. .FPO ( FPO_LOCALS+2, FPO_PARAMS, FPO_PROLOG, FPO_REGS, FPO_USE_EBP, FPO_TRAPFRAME )
  417. ;
  418. ; Fill in parts of frame we care about
  419. ;
  420. ifb <PassParm>
  421. push esp ; Use Error code field to save 16bit esp
  422. endif
  423. push ebp ; Save the non-volatile registers
  424. push ebx
  425. push esi
  426. push edi
  427. sub esp, TsEdi
  428. mov ebp,esp
  429. mov [esp]+TsEax, eax ; Save volatile registers
  430. mov [esp]+TsEcx, ecx
  431. mov [esp]+TsEdx, edx
  432. if DBG
  433. mov dword ptr [esp]+TsPreviousPreviousMode, -1 ; ThPreviousMode not pushed on interrupt
  434. endif
  435. test dword ptr [esp].TsEflags,EFLAGS_V86_MASK
  436. jnz V86_&AssistLabel
  437. cmp word ptr [esp]+TsSegCs, KGDT_R0_CODE
  438. jz short @f
  439. mov [esp]+TsSegFs, fs ; Save and set FS to PCR.
  440. mov [esp]+TsSegDs, ds
  441. mov [esp]+TsSegEs, es
  442. mov [esp]+TsSegGs, gs
  443. V86_&TargetLabel:
  444. mov ebx,KGDT_R0_PCR
  445. mov eax,KGDT_R3_DATA OR RPL_MASK
  446. mov fs, bx
  447. mov ds, ax
  448. mov es, ax
  449. @@:
  450. mov ebx, fs:[PcExceptionList] ;Save, set ExceptionList
  451. mov fs:[PcExceptionList],EXCEPTION_CHAIN_END
  452. mov [esp]+TsExceptionList, ebx
  453. ifnb <PassParm>
  454. lea eax, [esp].TsErrCode
  455. lea ecx, [esp].TsEip ; Move eax to EIP field
  456. mov ebx, ss:[eax] ; (ebx) = parameter to pass
  457. mov ss:[eax], ecx ; save 16bit esp
  458. endif
  459. ;
  460. ; Remap ABIOS 16 bit stack to 32 bit stack, if necessary.
  461. ;
  462. cmp esp, 10000h
  463. jb Abios_&AssistLabel
  464. mov dword ptr [esp].TsErrCode, 0 ; Indicate no remapping.
  465. Abios_&TargetLabel:
  466. ;
  467. ; end of Abios stack checking
  468. ;
  469. cld
  470. ifnb <PassParm>
  471. push ebx ; push parameter as argument
  472. endif
  473. SET_DEBUG_DATA
  474. test byte ptr PCR[PcDebugActive], -1
  475. jnz Dr_&AssistLabel
  476. Dr_&TargetLabel:
  477. endm
  478. ;++
  479. ;
  480. ; ENTER_INTERRUPT_FORCE_STATE AssistLabel, TargetLabel
  481. ;
  482. ; Macro Description:
  483. ;
  484. ; Build the frame and set registers needed by an interrupt.
  485. ;
  486. ; This macro is the same as ENTER_INTERRUPT except that it forces the
  487. ; needed state and does not save previous state.
  488. ;
  489. ; This macro is currently only used by HalpApicRebootService which does not
  490. ; return;
  491. ;
  492. ; Save:
  493. ; Errorpad,
  494. ; Non-volatile regs,
  495. ; ExceptionList,
  496. ; PreviousMode
  497. ; Volatile regs
  498. ; Seg regs from V86 mode
  499. ;
  500. ; Don't Save:
  501. ; FS,
  502. ; DS, ES, GS
  503. ; Floating point state
  504. ;
  505. ; Set:
  506. ; FS,
  507. ; ExceptionList,
  508. ; Direction,
  509. ; DS, ES
  510. ;
  511. ; Don't Set:
  512. ; PreviousMode
  513. ;
  514. ; Arguments:
  515. ; AssistLabel - label ENTER_ASSIST macro is at
  516. ; TargetLabel - label to emit for ENTER_ASSIST to jump to
  517. ;
  518. ; Exit-conditions:
  519. ; Interrupts match input state (this routine doesn't change IEF)
  520. ; (esp)->base of trap frame
  521. ; (ebp)->base of trap frame
  522. ; Preserves entry eax, ecx, edx
  523. ;
  524. ;--
  525. ENTER_INTERRUPT_FORCE_STATE macro AssistLabel, TargetLabel, PassParm
  526. local b
  527. .FPO ( FPO_LOCALS+2, FPO_PARAMS, FPO_PROLOG, FPO_REGS, FPO_USE_EBP, FPO_TRAPFRAME )
  528. ;
  529. ; Fill in parts of frame we care about
  530. ;
  531. ifb <PassParm>
  532. push esp ; Use Error code field to save 16bit esp
  533. endif
  534. push ebp ; Save the non-volatile registers
  535. push ebx
  536. push esi
  537. push edi
  538. sub esp, TsEdi
  539. mov ebp,esp
  540. mov [esp]+TsEax, eax ; Save volatile registers
  541. mov [esp]+TsEcx, ecx
  542. mov [esp]+TsEdx, edx
  543. if DBG
  544. mov dword ptr [esp]+TsPreviousPreviousMode, -1 ; ThPreviousMode not pushed on interrupt
  545. endif
  546. test dword ptr [esp].TsEflags,EFLAGS_V86_MASK
  547. jnz V86_&AssistLabel
  548. V86_&TargetLabel:
  549. mov ebx,KGDT_R0_PCR
  550. mov eax,KGDT_R3_DATA OR RPL_MASK
  551. mov fs, bx
  552. mov ds, ax
  553. mov es, ax
  554. @@:
  555. mov ebx, fs:[PcExceptionList] ;Save, set ExceptionList
  556. mov fs:[PcExceptionList],EXCEPTION_CHAIN_END
  557. mov [esp]+TsExceptionList, ebx
  558. ifnb <PassParm>
  559. lea eax, [esp].TsErrCode
  560. lea ecx, [esp].TsEip ; Move eax to EIP field
  561. mov ebx, ss:[eax] ; (ebx) = parameter to pass
  562. mov ss:[eax], ecx ; save 16bit esp
  563. endif
  564. ;
  565. ; Remap ABIOS 16 bit stack to 32 bit stack, if necessary.
  566. ;
  567. cmp esp, 10000h
  568. jb Abios_&AssistLabel
  569. mov dword ptr [esp].TsErrCode, 0 ; Indicate no remapping.
  570. Abios_&TargetLabel:
  571. ;
  572. ; end of Abios stack checking
  573. ;
  574. cld
  575. ifnb <PassParm>
  576. push ebx ; push parameter as argument
  577. endif
  578. SET_DEBUG_DATA
  579. test byte ptr PCR[PcDebugActive], -1
  580. jnz Dr_&AssistLabel
  581. Dr_&TargetLabel:
  582. endm
  583. ;++
  584. ;
  585. ; ENTER_TRAP AssistLabel, TargetLabel
  586. ;
  587. ; Macro Description:
  588. ;
  589. ; Build the frame and set registers needed by a trap or exception.
  590. ;
  591. ; Save:
  592. ; Non-volatile regs,
  593. ; FS,
  594. ; ExceptionList,
  595. ; PreviousMode,
  596. ; Volatile regs
  597. ; Seg Regs from V86 mode
  598. ; DS, ES, GS
  599. ;
  600. ; Don't Save:
  601. ; Floating point state
  602. ;
  603. ; Set:
  604. ; FS,
  605. ; Direction,
  606. ; DS, ES
  607. ;
  608. ; Don't Set:
  609. ; PreviousMode,
  610. ; ExceptionList
  611. ;
  612. ; Arguments:
  613. ; AssistLabel - label ENTER_ASSIST macro is at
  614. ; TargetLabel - label to emit for ENTER_ASSIST to jump to
  615. ;
  616. ; Exit-conditions:
  617. ; Interrupts match input state (this routine doesn't change IEF)
  618. ; (esp)->base of trap frame
  619. ; (ebp)->base of trap frame
  620. ; Preserves entry eax
  621. ;
  622. ;--
  623. ENTER_TRAP macro AssistLabel, TargetLabel
  624. local b
  625. .FPO ( FPO_LOCALS, FPO_PARAMS, FPO_PROLOG, FPO_REGS, FPO_USE_EBP, FPO_TRAPFRAME )
  626. ;
  627. ; Fill in parts of frame we care about
  628. ;
  629. if DBG
  630. ifndef _Ki16BitStackException
  631. EXTRNP _Ki16BitStackException
  632. endif
  633. endif ; DBG
  634. mov word ptr [esp+2], 0 ; Clear upper word of ErrorCode
  635. push ebp ; Save the non-volatile registers
  636. push ebx
  637. push esi
  638. push edi
  639. push fs ; Save and set FS to PCR.
  640. mov ebx,KGDT_R0_PCR
  641. mov fs,bx
  642. mov ebx, fs:[PcExceptionList] ;Save ExceptionList
  643. push ebx
  644. if DBG
  645. push -1 ; Don't need to save ThPreviousMode from trap
  646. else
  647. sub esp, 4 ; pad dword
  648. endif
  649. push eax ; Save the volatile registers
  650. push ecx
  651. push edx
  652. push ds ; Save segments
  653. push es
  654. push gs
  655. ;
  656. ; Skip allocate reset of trap frame and Set up DS/ES, they may be trash
  657. ;
  658. mov ax,KGDT_R3_DATA OR RPL_MASK
  659. sub esp,TsSegGs
  660. mov ds,ax
  661. mov es,ax
  662. if DBG
  663. ;
  664. ; The code here check if the exception occurred in ring 0
  665. ; ABIOS code. If yes, this is a fatal condition. We will
  666. ; put out message and bugcheck.
  667. ;
  668. cmp esp, 10000h ; Is the trap in abios?
  669. jb _Ki16BitStackException ; if b, yes, switch stack and bugcheck.
  670. endif ; DBG
  671. mov ebp,esp
  672. test dword ptr [esp].TsEflags,EFLAGS_V86_MASK
  673. jnz V86_&AssistLabel
  674. V86_&TargetLabel:
  675. cld
  676. SET_DEBUG_DATA
  677. test byte ptr PCR[PcDebugActive], -1
  678. jnz Dr_&AssistLabel
  679. Dr_&TargetLabel:
  680. endm
  681. ;++
  682. ;
  683. ; EXIT_ALL NoRestoreSegs, NoRestoreVolatiles, NoPreviousMode
  684. ;
  685. ; Macro Description:
  686. ;
  687. ; Load a syscall frame back into the machine.
  688. ;
  689. ; Restore:
  690. ; Volatile regs, IF NoRestoreVolatiles blank
  691. ; NoPreviousMode,
  692. ; ExceptionList,
  693. ; FS,
  694. ; Non-volatile regs
  695. ;
  696. ; If the frame is a kernel mode frame, AND esp has been edited,
  697. ; then TsSegCs will have a special value. Test for that value
  698. ; and execute special code for that case.
  699. ;
  700. ; N.B. This macro generates an IRET! (i.e. It exits!)
  701. ;
  702. ; Arguments:
  703. ;
  704. ; NoRestoreSegs - non-blank if DS, ES, GS are NOT to be restored
  705. ;
  706. ; NoRestoreVolatiles - non-blank if Volatile regs are NOT to be restored
  707. ;
  708. ; NoPreviousMode - if nb pop ThPreviousMode
  709. ;
  710. ; Entry-conditions:
  711. ;
  712. ; (esp)->base of trap frame
  713. ; (ebp)->Base of trap frame
  714. ;
  715. ; Exit-conditions:
  716. ;
  717. ; Does not exit, returns.
  718. ; Preserves eax, ecx, edx, IFF NoRestoreVolatiles is set
  719. ;
  720. ;--
  721. ?adjesp = 0
  722. ?RestoreAll = 1
  723. EXIT_ALL macro NoRestoreSegs, NoRestoreVolatiles, NoPreviousMode
  724. local a, b, f, x
  725. local Dr_ExitHelp, Dr_ExitHelp_Target
  726. local Db_NotATrapFrame, Db_A, Db_NotValidEntry, NonFlatPm_Target
  727. ;
  728. ; Sanity check some values and setup globals for macro
  729. ;
  730. ?adjesp = TsSegGs
  731. ?RestoreAll = 1
  732. ifnb <NoRestoreSegs>
  733. ?RestoreAll = 0
  734. ?adjesp = ?adjesp + 12
  735. endif
  736. ifnb <NoRestoreVolatiles>
  737. if ?RestoreAll eq 1
  738. %out "EXIT_ALL NoRestoreVolatiles requires NoRestoreSegs"
  739. .err
  740. endif
  741. ?adjesp = ?adjesp + 12
  742. endif
  743. ifb <NoPreviousMode>
  744. ifndef KERNELONLY
  745. %out EXIT_ALL can not restore previousmode outside kernel
  746. .err
  747. endif
  748. endif
  749. ; All callers are responsible for getting here with interrupts disabled.
  750. if DBG
  751. pushfd
  752. pop edx
  753. test edx, EFLAGS_INTERRUPT_MASK
  754. jnz Db_NotValidEntry
  755. cmp esp, ebp ; make sure esp = ebp
  756. jne Db_NotValidEntry
  757. ; Make sure BADB0D00 sig is present. If not this isn't a trap frame!
  758. Db_A: sub [esp]+TsDbgArgMark,0BADB0D00h
  759. jne Db_NotATrapFrame
  760. endif
  761. ASSERT_FS
  762. mov edx, [esp]+TsExceptionList
  763. if DBG
  764. or edx, edx
  765. jnz short @f
  766. int 3
  767. @@:
  768. endif
  769. mov ebx, fs:[PcDebugActive] ; (ebx) = DebugActive flag
  770. mov fs:[PcExceptionList], edx ; Restore ExceptionList
  771. ifb <NoPreviousMode>
  772. mov ecx, [esp]+TsPreviousPreviousMode ; Restore PreviousMode
  773. if DBG
  774. cmp ecx, -1 ; temporary debugging code
  775. jne @f ; to make sure no one tries to pop ThPreviousMode
  776. int 3 ; when it wasn't saved
  777. @@:
  778. endif
  779. mov esi,fs:[PcPrcbData+PbCurrentThread]
  780. mov [esi]+ThPreviousMode,cl
  781. else
  782. if DBG
  783. mov ecx, [esp]+TsPreviousPreviousMode
  784. cmp ecx, -1 ; temporary debugging code
  785. je @f ; to make sure no one pushed ThPreviousMode and
  786. int 3 ; is now exiting without restoreing it
  787. @@:
  788. endif
  789. endif
  790. test ebx, 0fh
  791. jnz Dr_ExitHelp
  792. Dr_ExitHelp_Target:
  793. test dword ptr [esp].TsEflags,EFLAGS_V86_MASK
  794. jnz V86ExitHelp
  795. test word ptr [esp]+TsSegCs,FRAME_EDITED
  796. jz b ; Edited frame pop out.
  797. if ?RestoreAll eq 0
  798. .errnz MODE_MASK-1
  799. cmp word ptr [esp]+TsSegCs,KGDT_R3_CODE OR RPL_MASK ; set/clear ZF
  800. bt word ptr [esp]+TsSegCs,0 ; test MODE_MASK set/clear CF
  801. cmc ; (CF=1 and ZF=0)
  802. ja f ; jmp if CF=0 and ZF=0
  803. endif
  804. ifb <NoRestoreVolatiles>
  805. mov edx, [esp]+TsEdx ; Restore volitales
  806. mov ecx, [esp]+TsEcx
  807. ; must restore eax before any
  808. mov eax, [esp].TsEax ; selectors! (see trap0e handler)
  809. endif
  810. cmp word ptr [ebp]+TsSegCs, KGDT_R0_CODE
  811. jz short @f
  812. ifb <NoRestoreSegs>
  813. lea esp, [ebp]+TsSegGs
  814. pop gs ; Restore Segs
  815. pop es
  816. pop ds
  817. endif
  818. NonFlatPm_Target:
  819. lea esp, [ebp]+TsSegFs
  820. pop fs
  821. @@:
  822. lea esp, [ebp]+TsEdi ; Skip PreMode, ExceptList and fs
  823. pop edi ; restore non-volatiles
  824. pop esi
  825. pop ebx
  826. pop ebp
  827. ;
  828. ; Esp MUST point to the Error Code on the stack. Because we use it to
  829. ; store the entering esp.
  830. ;
  831. cmp word ptr [esp+8], 80h ; check for abios code segment?
  832. ja AbiosExitHelp
  833. add esp, 4 ; remove error code from trap frame
  834. ifnb <NoRestoreVolatiles>
  835. public _KiSystemCallExitBranch
  836. public _KiSystemCallExit
  837. public _KiSystemCallExit2
  838. public _KiSystemCallExit3
  839. ; NoRestoreVolatiles is only used for return from System Service.
  840. ; If returning to Kernel mode, the processor state does not need
  841. ; to be altered (CS, CPL stays the same etc), so simply unwind the
  842. ; kernel frame and branch to the saved EIP.
  843. test dword ptr [esp+4], MODE_MASK
  844. ; If the following branch is taken, we are returning to usermode.
  845. ; If this processor supports the SYSEXIT instruction, the branch
  846. ; will be adjusted at boot time to use the appropriate code sequence.
  847. _KiSystemCallExitBranch:
  848. jnz short _KiSystemCallExit
  849. ; Exit to kernel mode from system call, faster than IRETD,
  850. ; unwind the frame and branch to return address.
  851. pop edx ; get eip
  852. pop ecx ; remove CS from stack
  853. popfd ; restore eflags
  854. jmp edx
  855. if 0
  856. ; one day we should test and see if the following is faster
  857. ; than the above (and still valid).
  858. sti ; reenable interrupts
  859. ret 8 ; return to @esp and pop CS and EFLAGs
  860. endif
  861. _KiSystemCallExit:
  862. iretd ; return
  863. _KiSystemCallExit2:
  864. pop edx ; pop EIP
  865. add esp, 8 ; Remove CS & Eflags
  866. pop ecx ; pop ESP
  867. sti ; sysexit does not reload flags
  868. iSYSEXIT
  869. _KiSystemCallExit3:
  870. ; AMD
  871. pop ecx ; pop EIP
  872. add esp, 8
  873. pop esp
  874. ; mov esp, [esp+8] ; remove CS & Eflags, get ESP
  875. iSYSRET
  876. endif ;; <NoRestoreVolatiles>
  877. iretd ; return
  878. if DBG
  879. Db_NotATrapFrame:
  880. add [esp]+TsDbgArgMark,0BADB0D00h ; put back the orig value
  881. Db_NotValidEntry:
  882. int 3
  883. jmp Db_A
  884. endif
  885. ;
  886. ; EXIT_HELPER
  887. ;
  888. ; if (PreviousMode == UserMode) {
  889. ; DR* regs = TF.Dr* regs
  890. ; }
  891. ;
  892. ; Entry-Conditions:
  893. ;
  894. ; DebugActive == TRUE
  895. ; (ebp)->TrapFrame
  896. ;
  897. ;--
  898. align dword
  899. Dr_ExitHelp:
  900. test dword ptr [ebp]+TsEFlags,EFLAGS_V86_MASK
  901. jnz short x
  902. test dword ptr [ebp]+TsSegCs,MODE_MASK
  903. jz Dr_ExitHelp_Target
  904. x: mov ebx,0
  905. mov esi,[ebp]+TsDr0
  906. mov edi,[ebp]+TsDr1
  907. mov dr7,ebx
  908. mov dr0,esi
  909. mov ebx,[ebp]+TsDr2
  910. mov dr1,edi
  911. mov dr2,ebx
  912. mov esi,[ebp]+TsDr3
  913. mov edi,[ebp]+TsDr6
  914. mov ebx,[ebp]+TsDr7
  915. mov dr3,esi
  916. mov dr6,edi
  917. mov dr7,ebx
  918. jmp Dr_ExitHelp_Target
  919. ;
  920. if ?RestoreAll eq 0
  921. ;
  922. ; Restore segs and volatiles for non-flat R3 PM (VDM in PM)
  923. ;
  924. f: mov eax,[esp].TsEax ; restore eax before any selectors
  925. ; (see trap0e handler)
  926. add esp,TsSegGs
  927. pop gs
  928. pop es
  929. pop ds
  930. pop edx
  931. pop ecx
  932. jmp NonFlatPm_Target
  933. endif ; not ?RestoreAll
  934. ;
  935. ; TsSegCs contains the special value that means the frame was edited
  936. ; in a way that affected esp, AND it's a kernel mode frame.
  937. ; (Special value is null selector except for RPL.)
  938. ;
  939. ; Put back the real CS.
  940. ; push eflags, eip onto target stack
  941. ; restore
  942. ; switch to target stack
  943. ; iret
  944. ;
  945. b: mov ebx,[esp]+TsTempSegCs
  946. mov [esp]+TsSegCs,ebx
  947. ;
  948. ; There is no instruction that will load esp with an arbitrary value
  949. ; (i.e. one out of a frame) and do a return, if no privledge transition
  950. ; is occuring. Therefore, if we are returning to kernel mode, and
  951. ; esp has been edited, we must "emulate" a kind of iretd.
  952. ;
  953. ; We do this by logically pushing the eip,cs,eflags onto the new
  954. ; logical stack, loading that stack, and doing an iretd. This
  955. ; requires that the new logical stack is at least 1 dword higher
  956. ; than the unedited esp would have been. (i.e. It is not legal
  957. ; to edit esp to have a new value < the old value.)
  958. ;
  959. ; KeContextToKframes enforces this rule.
  960. ;
  961. ;
  962. ; Compute new logical stack address
  963. ;
  964. mov ebx,[esp]+TsTempEsp
  965. sub ebx,12
  966. mov [esp]+TsErrCode,ebx
  967. ;
  968. ; Copy eip,cs,eflags to new stack. note we do this high to low
  969. ;
  970. mov esi,[esp]+TsEflags
  971. mov [ebx+8],esi
  972. mov esi,[esp]+TsSegCs
  973. mov [ebx+4],esi
  974. mov esi,[esp]+TsEip
  975. mov [ebx],esi
  976. ;
  977. ; Do a standard restore sequence.
  978. ;
  979. ; Observe that RestoreVolatiles is honored. Editing a volatile
  980. ; register has no effect when returning from a system call.
  981. ;
  982. ifb <NoRestoreVolatiles>
  983. mov eax,[esp].TsEax
  984. endif
  985. ; add esp,TsSegGs
  986. ;
  987. ;ifb <NoRestoreSegs>
  988. ; pop gs
  989. ; pop es
  990. ; pop ds
  991. ;else
  992. ; add esp,12
  993. ;endif
  994. ifb <NoRestoreVolatiles>
  995. mov edx, [esp]+TsEdx
  996. mov ecx, [esp]+TsEcx
  997. endif
  998. ;ifnb <NoPreviousMode>
  999. ; add esp, 4 ; Skip previous mode
  1000. ;else
  1001. ; pop ebx ; Restore PreviousMode
  1002. ; mov esi,fs:[PcPrcbData+PbCurrentThread]
  1003. ; mov ss:[esi]+ThPreviousMode,bl
  1004. ;endif
  1005. ;
  1006. ; pop ebx
  1007. ;
  1008. ; mov fs:[PcExceptionList], ebx ;Restore ExceptionList
  1009. ; pop fs
  1010. add esp, TsEdi
  1011. pop edi ; restore non-volatiles
  1012. pop esi
  1013. pop ebx
  1014. pop ebp
  1015. ;
  1016. ; (esp)->TsErrCode, where we saved the new esp
  1017. ;
  1018. mov esp,[esp] ; Do move not push to avoid increment
  1019. iretd
  1020. endm
  1021. ;++
  1022. ;
  1023. ; INTERRUPT_EXIT
  1024. ;
  1025. ; Macro Description:
  1026. ;
  1027. ; This macro is executed on return from an interrupt vector service
  1028. ; service routine. Its function is to restore privileged processor
  1029. ; state, and continue thread execution. If control is returning to
  1030. ; user mode and there is a user APC pending, then APC level interupt
  1031. ; will be requested and control is transfered to the user APC delivery
  1032. ; routine, if no higher level interrupt pending.
  1033. ;
  1034. ; Arguments:
  1035. ;
  1036. ; (TOS) = previous irql
  1037. ; (TOS+4) = irq vector to eoi
  1038. ; (TOS+8 ...) = machine_state frame
  1039. ; (ebp)-> machine state frame (trap frame)
  1040. ;
  1041. ;--
  1042. INTERRUPT_EXIT macro DebugCheck
  1043. local a
  1044. ifnb <DebugCheck>
  1045. POLL_DEBUGGER
  1046. endif
  1047. if DBG ; save current eip for
  1048. a: mov esi, offset a ; debugging bad trap frames
  1049. endif
  1050. ifdef __imp_Kei386EoiHelper@0
  1051. cli
  1052. call _HalEndSystemInterrupt@8
  1053. jmp dword ptr [__imp_Kei386EoiHelper@0]
  1054. else
  1055. cli
  1056. call dword ptr [__imp__HalEndSystemInterrupt@8]
  1057. jmp Kei386EoiHelper@0
  1058. endif
  1059. endm
  1060. ;++
  1061. ;
  1062. ; SPURIOUS_INTERRUPT_EXIT
  1063. ;
  1064. ; Macro Description:
  1065. ;
  1066. ; To exit an interrupt without performing the EOI.
  1067. ;
  1068. ; Arguments:
  1069. ;
  1070. ; (TOS) = machine_state frame
  1071. ; (ebp)-> machine state frame (trap frame)
  1072. ;
  1073. ;--
  1074. SPURIOUS_INTERRUPT_EXIT macro
  1075. local a
  1076. if DBG ; save current eip for
  1077. a: mov esi, offset a ; debugging bad trap frames
  1078. endif
  1079. ifdef __imp_Kei386EoiHelper@0
  1080. jmp dword ptr [__imp_Kei386EoiHelper@0]
  1081. else
  1082. jmp Kei386EoiHelper@0
  1083. endif
  1084. endm
  1085. ;++
  1086. ;
  1087. ; ENTER_TRAPV86
  1088. ;
  1089. ; Macro Description:
  1090. ;
  1091. ; Construct trap frame for v86 mode traps.
  1092. ;
  1093. ;--
  1094. ENTER_TRAPV86 macro DRENTER,V86ENTER
  1095. sub esp, TsErrCode
  1096. mov word ptr [esp].TsErrCode + 2, 0
  1097. mov [esp].TsEbx, ebx
  1098. mov [esp].TsEax, eax
  1099. mov [esp].TsEbp, ebp
  1100. mov [esp].TsEsi, esi
  1101. mov [esp].TsEdi, edi
  1102. mov ebx, KGDT_R0_PCR
  1103. mov eax, KGDT_R3_DATA OR RPL_MASK
  1104. mov [esp].TsEcx, ecx
  1105. mov [esp].TsEdx, edx
  1106. if DBG
  1107. mov [esp].TsPreviousPreviousMode, -1
  1108. mov [esp]+TsDbgArgMark, 0BADB0D00h
  1109. endif
  1110. mov fs, bx
  1111. mov ds, ax
  1112. mov es, ax
  1113. mov ebp, esp
  1114. cld ; CHECKIT_SUDEEP ; do we really need it
  1115. test byte ptr PCR[PcDebugActive], -1
  1116. jnz Dr_&DRENTER
  1117. Dr_&V86ENTER:
  1118. endm
  1119. ;
  1120. ; Taken from ntos\vdm\i386\vdmtb.inc
  1121. ;
  1122. FIXED_NTVDMSTATE_LINEAR_PC_AT equ 0714H
  1123. FIXED_NTVDMSTATE_LINEAR_PC_98 equ 0614H
  1124. MACHINE_TYPE_MASK equ 0ff00H
  1125. VDM_VIRTUAL_INTERRUPTS equ 0200H
  1126. ;++
  1127. ;
  1128. ; EXIT_TRAPV86
  1129. ;
  1130. ; Macro Description:
  1131. ;
  1132. ; if UserApc is pending deliver it
  1133. ; if User Context is v86 mode
  1134. ; Exit from kernel (does not return)
  1135. ; else
  1136. ; return (expected to execute EXIT_ALL)
  1137. ;--
  1138. EXIT_TRAPV86 macro
  1139. local w, x, y, z
  1140. z: mov ebx, PCR[PcPrcbData+PbCurrentThread]
  1141. mov byte ptr [ebx]+ThAlerted, 0
  1142. cmp byte ptr [ebx]+ThApcState.AsUserApcPending, 0
  1143. jne short w
  1144. ;
  1145. ; Kernel exit to V86 mode
  1146. ;
  1147. add esp,TsEdx
  1148. pop edx
  1149. pop ecx
  1150. pop eax
  1151. test byte ptr PCR[PcDebugActive], -1
  1152. jnz short x
  1153. y:
  1154. add esp,12 ; unused fields
  1155. pop edi
  1156. pop esi
  1157. pop ebx
  1158. pop ebp
  1159. add esp,4 ; clear error code
  1160. iretd
  1161. x: mov esi,[ebp]+TsDr0
  1162. mov edi,[ebp]+TsDr1
  1163. mov ebx,[ebp]+TsDr2
  1164. mov dr0,esi
  1165. mov dr1,edi
  1166. mov dr2,ebx
  1167. mov esi,[ebp]+TsDr3
  1168. mov edi,[ebp]+TsDr6
  1169. mov ebx,[ebp]+TsDr7
  1170. mov dr3,esi
  1171. mov dr6,edi
  1172. mov dr7,ebx
  1173. jmp short y
  1174. w:
  1175. ;
  1176. ; Dispatch user mode APC
  1177. ; The APC routine runs with interrupts on and at APC level
  1178. ;
  1179. mov ecx, APC_LEVEL
  1180. fstCall KfRaiseIrql
  1181. push eax ; Save OldIrql
  1182. sti
  1183. stdCall _KiDeliverApc, <1, 0, ebp> ; ebp - Trap frame
  1184. ; 0 - Null exception frame
  1185. ; 1 - Previous mode
  1186. pop ecx ; (TOS) = OldIrql
  1187. fstCall KfLowerIrql
  1188. cli
  1189. ;
  1190. ; UserApc may have changed to vdm Monitor context (user flat 32)
  1191. ; If it has cannot use the v86 only kernel exit
  1192. ;
  1193. test dword ptr [ebp]+TsEFlags,EFLAGS_V86_MASK
  1194. jnz short z
  1195. ; Exit to do EXIT_ALL
  1196. endm
  1197. ;++
  1198. ;
  1199. ; KERNEL ICECAP PROBE MACROS
  1200. ;
  1201. ; Macro Description:
  1202. ;
  1203. ; Used to wrap selected calls in .asm routines with the same
  1204. ; probe calls inserted by the C compiler when /fastcap is used.
  1205. ; The X-suffix versions of the probe calls are used only in
  1206. ; KiSystemService and log additional information such as
  1207. ; Pid, Tid, image file name, etc.
  1208. ;
  1209. ; Arguments:
  1210. ;
  1211. ; Current Function
  1212. ; Called Function
  1213. ;
  1214. ;--
  1215. IFDEF _CAPKERN
  1216. extrn __CAP_Start_Profiling@8:PROC
  1217. extrn __CAP_End_Profiling@4:PROC
  1218. CAPSTART macro ArgList
  1219. stdCall __CAP_Start_Profiling, <ArgList>
  1220. endm
  1221. CAPEND macro ArgList
  1222. stdCall __CAP_End_Profiling, <ArgList>
  1223. endm
  1224. CAPSTARTX macro ArgList
  1225. push eax
  1226. stdCall __CAP_ThreadID
  1227. pop eax
  1228. stdCall __CAP_Start_Profiling, <ArgList>
  1229. endm
  1230. CAPENDX macro ArgList
  1231. stdCall __CAP_End_Profiling, <ArgList>
  1232. push eax
  1233. stdCall __CAP_SetCPU
  1234. pop eax
  1235. endm
  1236. ELSE
  1237. CAPSTART macro ArgList
  1238. endm
  1239. CAPEND macro ArgList
  1240. endm
  1241. CAPSTARTX macro ArgList
  1242. endm
  1243. CAPENDX macro ArgList
  1244. endm
  1245. ENDIF
  1246. ;++
  1247. ;
  1248. ; PERF_GET_TIMESTAMP
  1249. ;
  1250. ; Macro Description:
  1251. ;
  1252. ;
  1253. ; Return a time stamp that for event tracing in EDX:EAX
  1254. ;
  1255. ; NOTE: This may trash ECX
  1256. ;
  1257. ; In retail, get the clock value from WmiGetCpuClock. Else if using
  1258. ; reserved memory for logging, get cycle counter.
  1259. ;
  1260. ;--
  1261. PERF_GET_TIMESTAMP macro
  1262. extrn _WmiGetCpuClock:DWORD
  1263. call [_WmiGetCpuClock]
  1264. endm