3 * Copyright (C) 2000 David Welch <welch@cwcom.net>
5 * Moved to MSVC-compatible inline assembler by Mike Nordell, 2003-12-26
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * FILE: ntoskrnl/ke/i386/vm86_sup.S
23 * PURPOSE: V86 mode support
24 * PROGRAMMER: David Welch (welch@cwcom.net)
29 /* INCLUDES ******************************************************************/
33 #include <ddk/ntddk.h>
34 #include <ddk/status.h>
35 #include <internal/i386/segment.h>
36 #include <internal/i386/fpu.h>
37 #include <internal/ps.h>
38 #include <ddk/defines.h>
39 #include <internal/v86m.h>
41 //#include <ntos/service.h>
42 #include <internal/trap.h>
43 #include <internal/ps.h>
46 #include <internal/ntoskrnl.h>
47 #include <internal/i386/segment.h>
50 #define EXCEPTION_UNWINDING 0x02
52 #define EREC_FLAGS 0x04
54 #define ExceptionContinueExecution 0
55 #define ExceptionContinueSearch 1
56 #define ExceptionNestedException 2
57 #define ExceptionCollidedUnwind 3
59 //.globl _RtlpExecuteHandlerForException
60 //.globl _RtlpExecuteHandlerForUnwind
62 #define CONTEXT_FLAGS 0x00
63 #define CONTEXT_SEGGS 0x8C
64 #define CONTEXT_SEGFS 0x90
65 #define CONTEXT_SEGES 0x94
66 #define CONTEXT_SEGDS 0x98
67 #define CONTEXT_EDI 0x9C
68 #define CONTEXT_ESI 0xA0
69 #define CONTEXT_EBX 0xA4
70 #define CONTEXT_EDX 0xA8
71 #define CONTEXT_ECX 0xAC
72 #define CONTEXT_EAX 0xB0
73 #define CONTEXT_EBP 0xB4
74 #define CONTEXT_EIP 0xB8
75 #define CONTEXT_SEGCS 0xBC
76 #define CONTEXT_EFLAGS 0xC0
77 #define CONTEXT_ESP 0xC4
78 #define CONTEXT_SEGSS 0xC8
81 #define RCC_CONTEXT 0x08
85 AsmDebug(ULONG Value
);
88 // EAX = value to print
103 #define REH_ERECORD 0x08
104 #define REH_RFRAME 0x0C
105 #define REH_CONTEXT 0x10
106 #define REH_DCONTEXT 0x14
107 #define REH_EROUTINE 0x18
112 // [EBP+08h] - PEXCEPTION_RECORD ExceptionRecord
113 // [EBP+0Ch] - PEXCEPTION_REGISTRATION RegistrationFrame
114 // [EBP+10h] - PVOID Context
115 // [EBP+14h] - PVOID DispatcherContext
116 // [EBP+18h] - PEXCEPTION_HANDLER ExceptionRoutine
117 // EDX - Address of protecting exception handler
119 // EXCEPTION_DISPOSITION
121 // Setup the protecting exception handler and call the exception
122 // handler in the right context.
124 void RtlpExecuteHandler()
136 // Prepare to call the exception handler
137 push REH_DCONTEXT
[ebp
]
138 push REH_CONTEXT
[ebp
]
140 push REH_ERECORD
[ebp
]
142 // Now call the exception handler
143 mov eax
, REH_EROUTINE
[ebp
]
147 jne reh_stack_looks_ok
149 // This should not happen
162 // Return to the 'front-end' for this function
174 #define REP_ERECORD 0x04
175 #define REP_RFRAME 0x08
176 #define REP_CONTEXT 0x0C
177 #define REP_DCONTEXT 0x10
180 // [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
181 // [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
182 // [ESP+0Ch] - PCONTEXT Context
183 // [ESP+10h] - PVOID DispatcherContext
187 // EXCEPTION_DISPOSITION
189 // This exception handler protects the exception handling
190 // mechanism by detecting nested exceptions.
192 void RtlpExceptionProtector()
196 mov eax
, ExceptionContinueSearch
197 mov ecx
, REP_ERECORD
[esp
]
198 test EREC_FLAGS
[ecx
], EXCEPTION_UNWINDING
201 // Unwinding is not taking place, so return ExceptionNestedException
203 // Set DispatcherContext field to the exception registration for the
204 // exception handler that executed when a nested exception occurred
205 mov ecx
, REP_DCONTEXT
[esp
]
206 mov eax
, REP_RFRAME
[esp
]
208 mov eax
, ExceptionNestedException
217 // [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
218 // [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
219 // [ESP+0Ch] - PCONTEXT Context
220 // [ESP+10h] - PVOID DispatcherContext
221 // [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler
225 // EXCEPTION_DISPOSITION
229 void RtlpExecuteHandlerForException()
233 mov edx
, RtlpExceptionProtector
234 jmp RtlpExecuteHandler
239 #define RUP_ERECORD 0x04
240 #define RUP_RFRAME 0x08
241 #define RUP_CONTEXT 0x0C
242 #define RUP_DCONTEXT 0x10
245 // [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
246 // [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
247 // [ESP+0Ch] - PCONTEXT Context
248 // [ESP+10h] - PVOID DispatcherContext
252 // EXCEPTION_DISPOSITION
254 // This exception handler protects the exception handling
255 // mechanism by detecting collided unwinds.
257 void RtlpUnwindProtector()
261 mov eax
, ExceptionContinueSearch
262 mov RUP_ERECORD
[esp
], ecx
263 test EREC_FLAGS
[ecx
], EXCEPTION_UNWINDING
266 // Unwinding is taking place, so return ExceptionCollidedUnwind
268 mov ecx
, RUP_RFRAME
[esp
]
269 mov edx
, RUP_DCONTEXT
[esp
]
271 // Set DispatcherContext field to the exception registration for the
272 // exception handler that executed when a collision occurred
273 mov eax
, RUP_RFRAME
[ecx
]
275 mov eax
, ExceptionCollidedUnwind
284 // [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
285 // [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
286 // [ESP+0Ch] - PCONTEXT Context
287 // [ESP+10h] - PVOID DispatcherContext
288 // [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler
292 // EXCEPTION_DISPOSITION
294 void RtlpExecuteHandlerForUnwind()
296 __asm mov edx
, RtlpUnwindProtector
297 __asm jmp RtlpExecuteHandler