.globl _KiIdtDescriptor
_KiIdtDescriptor:
- .short 0x800
+ .short 0
+ .short 0x7FF
.long _KiIdt
.globl _KiUnexpectedEntrySize
_UnhandledMsg:
.asciz "\n\x7\x7!!! Unhandled or Unexpected Code at line: %lx!!!\n"
+_IsrTimeoutMsg:
+ .asciz "\n*** ISR at %lx took over .5 second\n"
+
+_IsrOverflowMsg:
+ .asciz "\n*** ISR at %lx appears to have an interrupt storm\n"
+
_KiTrapPrefixTable:
.byte 0xF2 /* REP */
.byte 0xF3 /* REP INS/OUTS */
UNHANDLED_PATH
.func KiSystemService
-Dr_kss: DR_TRAP_FIXUP
+TRAP_FIXUPS kss_a, kss_t, DoNotFixupV86, DoNotFixupAbios
_KiSystemService:
/* Enter the shared system call prolog */
- SYSCALL_PROLOG kss
+ SYSCALL_PROLOG kss_a, kss_t
/* Jump to the actual handler */
jmp SharedCode
.endfunc
.func KiFastCallEntry
-Dr_FastCallDrSave: DR_TRAP_FIXUP
+TRAP_FIXUPS FastCallDrSave, FastCallDrReturn, DoNotFixupV86, DoNotFixupAbios
_KiFastCallEntry:
/* Enter the fast system call prolog */
- FASTCALL_PROLOG FastCallDrSave
+ FASTCALL_PROLOG FastCallDrSave, FastCallDrReturn
SharedCode:
jnz NotWin32K
/* Get the TEB */
- mov ecx, [fs:KPCR_TEB]
+ mov ecx, PCR[KPCR_TEB]
/* Check if we should flush the User Batch */
xor ebx, ebx
/* Flush it */
push edx
push eax
- //call [_KeGdiFlushUserBatch]
+ call [_KeGdiFlushUserBatch]
pop eax
pop edx
NotWin32K:
/* Increase total syscall count */
- inc dword ptr fs:[KPCR_SYSTEM_CALLS]
+ inc dword ptr PCR[KPCR_SYSTEM_CALLS]
-#ifdef DBG
+#if DBG
/* Increase per-syscall count */
mov ecx, [edi+SERVICE_DESCRIPTOR_COUNT]
jecxz NoCountTable
call ebx
AfterSysCall:
-#ifdef DBG
+#if DBG
/* Make sure the user-mode call didn't return at elevated IRQL */
test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jz SkipCheck
mov eax, esi /* Restore it */
/* Get our temporary current thread pointer for sanity check */
- mov ecx, fs:[KPCR_CURRENT_THREAD]
+ mov ecx, PCR[KPCR_CURRENT_THREAD]
/* Make sure that we are not attached and that APCs are not disabled */
mov dl, [ecx+KTHREAD_APC_STATE_INDEX]
KeReturnFromSystemCall:
/* Get the Current Thread */
- mov ecx, [fs:KPCR_CURRENT_THREAD]
+ mov ecx, PCR[KPCR_CURRENT_THREAD]
/* Restore the old trap frame pointer */
mov edx, [ebp+KTRAP_FRAME_EDX]
BadStack:
/* Restore ESP0 stack */
- mov ecx, [fs:KPCR_TSS]
+ mov ecx, PCR[KPCR_TSS]
mov esp, ss:[ecx+KTSS_ESP0]
/* Generate V86M Stack for Trap 6 */
push 0
jmp _KiTrap6
-#ifdef DBG
+#if DBG
InvalidIrql:
/* Save current IRQL */
- push fs:[KPCR_IRQL]
+ push PCR[KPCR_IRQL]
/* Set us at passive */
- mov dword ptr fs:[KPCR_IRQL], 0
+ mov dword ptr PCR[KPCR_IRQL], 0
cli
/* Bugcheck */
UNHANDLED_PATH
.func KiDebugService
-Dr_kids: DR_TRAP_FIXUP
-V86_kids: V86_TRAP_FIXUP
+TRAP_FIXUPS kids_a, kids_t, DoFixupV86, DoFixupAbios
_KiDebugService:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kids
+ TRAP_PROLOG kids_a, kids_t
/* Increase EIP so we skip the INT3 */
inc dword ptr [ebp+KTRAP_FRAME_EIP]
/* Call debug service dispatcher */
mov eax, [ebp+KTRAP_FRAME_EAX]
mov ecx, [ebp+KTRAP_FRAME_ECX]
- mov edx, [ebp+KTRAP_FRAME_EAX]
+ mov edx, [ebp+KTRAP_FRAME_EDX]
/* Jump to INT3 handler */
jmp PrepareInt3
push ebp
/* Get the current thread and restore its trap frame */
- mov ebx, [fs:KPCR_CURRENT_THREAD]
+ mov ebx, PCR[KPCR_CURRENT_THREAD]
mov edx, [ebp+KTRAP_FRAME_EDX]
mov [ebx+KTHREAD_TRAP_FRAME], edx
/* Get the exception list and restore */
mov eax, [ebx+KTRAP_FRAME_EXCEPTION_LIST]
- mov [fs:KPCR_EXCEPTION_LIST], eax
+ mov PCR[KPCR_EXCEPTION_LIST], eax
/* Get the parameters */
mov edx, [ebp+16] /* Search frames */
push ebp
/* Get the current thread and restore its trap frame */
- mov ebx, [fs:KPCR_CURRENT_THREAD]
+ mov ebx, PCR[KPCR_CURRENT_THREAD]
mov edx, [ebp+KTRAP_FRAME_EDX]
mov [ebx+KTHREAD_TRAP_FRAME], edx
mov [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], ecx
/* Check parameter count */
- cmp eax, 0
+ cmp ecx, 0
jz NoParams
/* Get information */
/* Set the record in ECX and check if this was V86 */
mov ecx, esp
- test dword ptr [esp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
+ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jz SetPreviousMode
/* Set V86 mode */
SetPreviousMode:
- /* Calculate the previous mode */
+ /* Get the caller's CS */
mov eax, [ebp+KTRAP_FRAME_CS]
+
MaskMode:
+ /* Check if it was user-mode or kernel-mode */
and eax, MODE_MASK
/* Dispatch the exception */
call _CommonDispatchException
.endfunc
-.func DispatchOneParam
-_DispatchOneParam:
+.func DispatchOneParamZero
+_DispatchOneParamZero:
/* Call the common dispatcher */
xor edx, edx
mov ecx, 1
call _CommonDispatchException
.endfunc
+.func DispatchTwoParamZero
+_DispatchTwoParamZero:
+ /* Call the common dispatcher */
+ xor edx, edx
+ mov ecx, 2
+ call _CommonDispatchException
+.endfunc
+
.func DispatchTwoParam
_DispatchTwoParam:
/* Call the common dispatcher */
- xor edx, edx
mov ecx, 2
call _CommonDispatchException
.endfunc
.endfunc
.func KiTrap0
-Dr_kit0: DR_TRAP_FIXUP
-V86_kit0: V86_TRAP_FIXUP
+TRAP_FIXUPS kit0_a, kit0_t, DoFixupV86, DoNotFixupAbios
_KiTrap0:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit0
+ TRAP_PROLOG kit0_a, kit0_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
VdmCheck:
/* Check if this is a VDM process */
- mov ebx, [fs:KPCR_CURRENT_THREAD]
+ mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz SendException
.endfunc
.func KiTrap1
-Dr_kit1: DR_TRAP_FIXUP
-V86_kit1: V86_TRAP_FIXUP
+TRAP_FIXUPS kit1_a, kit1_t, DoFixupV86, DoNotFixupAbios
_KiTrap1:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit1
+ TRAP_PROLOG kit1_a, kit1_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
V86Int1:
/* Check if this is a VDM process */
- mov ebx, [fs:KPCR_CURRENT_THREAD]
+ mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz EnableInterrupts
.endfunc
.func KiTrap3
-Dr_kit3: DR_TRAP_FIXUP
-V86_kit3: V86_TRAP_FIXUP
+TRAP_FIXUPS kit3_a, kit3_t, DoFixupV86, DoNotFixupAbios
_KiTrap3:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit3
+ TRAP_PROLOG kit3_a, kit3_t
/* Set status code */
- mov eax, 0 //STATUS_SUCCESS
+ mov eax, STATUS_SUCCESS
/* Check for V86 */
PrepareInt3:
sti
PrepInt3:
+
/* Prepare the exception */
mov esi, ecx
mov edi, edx
/* Setup EIP, NTSTATUS and parameter count, then dispatch */
mov ebx, [ebp+KTRAP_FRAME_EIP]
dec ebx
- mov eax, STATUS_BREAKPOINT
mov ecx, 3
+ mov eax, STATUS_BREAKPOINT
call _CommonDispatchException
V86Int3:
/* Check if this is a VDM process */
- mov ebx, [fs:KPCR_CURRENT_THREAD]
+ mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz EnableInterrupts3
.endfunc
.func KiTrap4
-Dr_kit4: DR_TRAP_FIXUP
-V86_kit4: V86_TRAP_FIXUP
+TRAP_FIXUPS kit4_a, kit4_t, DoFixupV86, DoNotFixupAbios
_KiTrap4:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit4
+ TRAP_PROLOG kit4_a, kit4_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
VdmCheck4:
/* Check if this is a VDM process */
- mov ebx, [fs:KPCR_CURRENT_THREAD]
+ mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz SendException4
.endfunc
.func KiTrap5
-Dr_kit5: DR_TRAP_FIXUP
-V86_kit5: V86_TRAP_FIXUP
+TRAP_FIXUPS kit5_a, kit5_t, DoFixupV86, DoNotFixupAbios
_KiTrap5:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit5
+ TRAP_PROLOG kit5_a, kit5_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
VdmCheck5:
/* Check if this is a VDM process */
- mov ebx, [fs:KPCR_CURRENT_THREAD]
+ mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz SendException5
.endfunc
.func KiTrap6
-Dr_kit6: DR_TRAP_FIXUP
-V86_kit6: V86_TRAP_FIXUP
+TRAP_FIXUPS kit6_a, kit6_t, DoFixupV86, DoNotFixupAbios
_KiTrap6:
/* It this a V86 GPF? */
jz NotV86UD
/* Enter V86 Trap */
- V86_TRAP_PROLOG kit6
+ V86_TRAP_PROLOG kit6_a, kit6_v
/* Not yet supported (Invalid OPCODE from V86) */
UNHANDLED_PATH
push 0
/* Enter trap */
- TRAP_PROLOG kit6
+ TRAP_PROLOG kit6_a, kit6_t
/* Check if this happened in kernel mode */
test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jz UmodeOpcode
/* Check if the process is vDM */
- mov ebx, fs:[KPCR_CURRENT_THREAD]
+ mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jnz IsVdmOpcode
/* Setup a SEH frame */
push ebp
push OpcodeSEH
- push fs:[KPCR_EXCEPTION_LIST]
- mov fs:[KPCR_EXCEPTION_LIST], esp
+ push PCR[KPCR_EXCEPTION_LIST]
+ mov PCR[KPCR_EXCEPTION_LIST], esp
OpcodeLoop:
/* Get the instruction and check if it's LOCK */
loop OpcodeLoop
/* Undo SEH frame */
- pop fs:[KPCR_EXCEPTION_LIST]
+ pop PCR[KPCR_EXCEPTION_LIST]
add esp, 8
KmodeOpcode:
LockCrash:
/* Undo SEH Frame */
- pop fs:[KPCR_EXCEPTION_LIST]
+ pop PCR[KPCR_EXCEPTION_LIST]
add esp, 8
/* Setup invalid lock exception and dispatch it */
/* Get SEH frame */
mov esp, [esp+8]
- pop fs:[KPCR_EXCEPTION_LIST]
+ pop PCR[KPCR_EXCEPTION_LIST]
add esp, 4
pop ebp
.endfunc
.func KiTrap7
-Dr_kit7: DR_TRAP_FIXUP
-V86_kit7: V86_TRAP_FIXUP
+TRAP_FIXUPS kit7_a, kit7_t, DoFixupV86, DoNotFixupAbios
_KiTrap7:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit7
+ TRAP_PROLOG kit7_a, kit7_t
/* Get the current thread and stack */
StartTrapHandle:
- mov eax, [fs:KPCR_CURRENT_THREAD]
+ mov eax, PCR[KPCR_CURRENT_THREAD]
mov ecx, [eax+KTHREAD_INITIAL_STACK]
sub ecx, NPX_FRAME_LENGTH
/* Check if emulation is enabled */
- test dword ptr [ecx+FN_CR0_NPX_STATE], CR0_EM
+ test byte ptr [ecx+FN_CR0_NPX_STATE], CR0_EM
jnz EmulationEnabled
CheckState:
mov cr0, ebx
/* Check the NPX thread */
- mov edx, [fs:KPCR_NPX_THREAD]
+ mov edx, PCR[KPCR_NPX_THREAD]
or edx, edx
jz NoNpxThread
jmp AfterRestore
FrRestore:
- frstor [esi]
+ frstor [ecx]
AfterRestore:
/* Set state loaded */
mov byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_LOADED
- mov [fs:KPCR_NPX_THREAD], eax
+ mov PCR[KPCR_NPX_THREAD], eax
/* Enable interrupts to happen now */
sti
UserNpx:
/* Get the current thread */
- mov eax, fs:[KPCR_CURRENT_THREAD]
+ mov eax, PCR[KPCR_CURRENT_THREAD]
/* Check NPX state */
cmp byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
/* Update NPX state */
mov byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
- mov dword ptr fs:[KPCR_NPX_THREAD], 0
+ mov dword ptr PCR[KPCR_NPX_THREAD], 0
NoSaveRestore:
/* Clear the TS bit and re-enable interrupts */
/* Raise exception */
mov eax, STATUS_FLOAT_INVALID_OPERATION
- jmp _DispatchOneParam
+ jmp _DispatchOneParamZero
InvalidStack:
/* Raise exception */
mov eax, STATUS_FLOAT_STACK_CHECK
- jmp _DispatchTwoParam
+ jmp _DispatchTwoParamZero
ValidNpxOpcode:
/* Raise exception */
mov eax, STATUS_FLOAT_DIVIDE_BY_ZERO
- jmp _DispatchOneParam
+ jmp _DispatchOneParamZero
1:
/* Check for denormal */
/* Raise exception */
mov eax, STATUS_FLOAT_INVALID_OPERATION
- jmp _DispatchOneParam
+ jmp _DispatchOneParamZero
1:
/* Check for overflow */
/* Raise exception */
mov eax, STATUS_FLOAT_OVERFLOW
- jmp _DispatchOneParam
+ jmp _DispatchOneParamZero
1:
/* Check for underflow */
/* Raise exception */
mov eax, STATUS_FLOAT_UNDERFLOW
- jmp _DispatchOneParam
+ jmp _DispatchOneParamZero
1:
/* Check for precision fault */
/* Raise exception */
mov eax, STATUS_FLOAT_INEXACT_RESULT
- jmp _DispatchOneParam
+ jmp _DispatchOneParamZero
UnexpectedNpx:
V86Npx:
/* Check if this is a VDM */
- mov eax, fs:[KPCR_CURRENT_THREAD]
+ mov eax, PCR[KPCR_CURRENT_THREAD]
mov ebx, [eax+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz HandleUserNpx
.globl _KiTrap8
.func KiTrap8
_KiTrap8:
-
/* Can't really do too much */
mov eax, 8
jmp _KiSystemFatalException
.endfunc
.func KiTrap9
-Dr_kit9: DR_TRAP_FIXUP
-V86_kit9: V86_TRAP_FIXUP
+TRAP_FIXUPS kit9_a, kit9_t, DoFixupV86, DoNotFixupAbios
_KiTrap9:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit9
+ TRAP_PROLOG kit9_a, kit9_t
/* Enable interrupts and bugcheck */
sti
.endfunc
.func KiTrap10
-Dr_kit10: DR_TRAP_FIXUP
-V86_kit10: V86_TRAP_FIXUP
+TRAP_FIXUPS kita_a, kita_t, DoFixupV86, DoNotFixupAbios
_KiTrap10:
/* Enter trap */
- TRAP_PROLOG kit10
+ TRAP_PROLOG kita_a, kita_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
.endfunc
.func KiTrap11
-Dr_kit11: DR_TRAP_FIXUP
-V86_kit11: V86_TRAP_FIXUP
+TRAP_FIXUPS kitb_a, kitb_t, DoFixupV86, DoNotFixupAbios
_KiTrap11:
/* Enter trap */
- TRAP_PROLOG kit11
+ TRAP_PROLOG kitb_a, kitb_t
/* FIXME: ROS Doesn't handle segment faults yet */
mov eax, 11
.endfunc
.func KiTrap12
-Dr_kit12: DR_TRAP_FIXUP
-V86_kit12: V86_TRAP_FIXUP
+TRAP_FIXUPS kitc_a, kitc_t, DoFixupV86, DoNotFixupAbios
_KiTrap12:
/* Enter trap */
- TRAP_PROLOG kit12
+ TRAP_PROLOG kitc_a, kitc_t
/* FIXME: ROS Doesn't handle stack faults yet */
mov eax, 12
/* Setup SEH handler frame */
mov esp, [esp+8]
- pop fs:[KPCR_EXCEPTION_LIST]
+ pop PCR[KPCR_EXCEPTION_LIST]
add esp, 4
pop ebp
.endfunc
.func KiTrap13
-Dr_kitd: DR_TRAP_FIXUP
-V86_kitd: V86_TRAP_FIXUP
+TRAP_FIXUPS kitd_a, kitd_t, DoFixupV86, DoNotFixupAbios
_KiTrap13:
/* It this a V86 GPF? */
jz NotV86
/* Enter V86 Trap */
- V86_TRAP_PROLOG kitd
+ V86_TRAP_PROLOG kitd_a, kitd_v
/* Make sure that this is a V86 process */
- mov ecx, [fs:KPCR_CURRENT_THREAD]
+ mov ecx, PCR[KPCR_CURRENT_THREAD]
mov ecx, [ecx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ecx+EPROCESS_VDM_OBJECTS], 0
jnz RaiseIrql
/* Otherwise, something is very wrong, raise an exception */
sti
- mov ebx, [ebp+KTRAP_FRAME_EIP]
- mov esi, -1
- mov eax, STATUS_ACCESS_VIOLATION
- jmp _DispatchTwoParam
+ jmp SetException
RaiseIrql:
NotV86:
/* Enter trap */
- TRAP_PROLOG kitd
-
+ TRAP_PROLOG kitd_a, kitd_t
+
/* Check if this was from kernel-mode */
test dword ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jnz UserModeGpf
/* Check if we have a VDM alert */
- cmp dword ptr fs:[KPCR_VDM_ALERT], 0
+ cmp dword ptr PCR[KPCR_VDM_ALERT], 0
jnz VdmAlertGpf
/* Check for GPF during GPF */
cmp eax, offset CheckPrivilegedInstruction
jbe KmodeGpf
cmp eax, offset CheckPrivilegedInstruction2
+ jae KmodeGpf
/* FIXME: TODO */
UNHANDLED_PATH
NotBiosGpf:
/* Check if the thread was in kernel mode */
- mov ebx, [fs:KPCR_CURRENT_THREAD]
+ mov ebx, PCR[KPCR_CURRENT_THREAD]
test byte ptr [ebx+KTHREAD_PREVIOUS_MODE], 0xFF
jz UserModeGpf
mov esi, [ebp+KTRAP_FRAME_ERROR_CODE]
and esi, 0xFFFF
mov eax, STATUS_ACCESS_VIOLATION
- jmp _DispatchTwoParam
+ jmp _DispatchTwoParamZero
MsrCheck:
jz _KiSystemFatalException
/* Get the process and check which CS this came from */
- mov ebx, fs:[KPCR_CURRENT_THREAD]
+ mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
jz CheckVdmGpf
/* Setup a SEH handler */
push ebp
push offset _KiTrapExceptHandler
- push fs:[KPCR_EXCEPTION_LIST]
- mov fs:[KPCR_EXCEPTION_LIST], esp
+ push PCR[KPCR_EXCEPTION_LIST]
+ mov PCR[KPCR_EXCEPTION_LIST], esp
/* Get EIP */
mov esi, [ebp+KTRAP_FRAME_EIP]
/* If it's not a prefix byte, check other instructions */
jnz NotPrefixByte
+
+ /* Keep looping */
+ loop InstLoop
+
+ /* Fixup the stack */
+ pop PCR[KPCR_EXCEPTION_LIST]
+ add esp, 8
- /* FIXME */
- UNHANDLED_PATH
+ /* Illegal instruction */
+ jmp KmodeOpcode
NotPrefixByte:
- /* FIXME: Check if it's a HLT */
+ /* Check if it's a HLT */
+ cmp al, 0x0F4
+ je IsPrivInstruction
/* Check if the instruction has two bytes */
cmp al, 0xF
jne CheckRing3Io
-
- /* FIXME */
- UNHANDLED_PATH
+
+ /* Check if this is a LLDT or LTR */
+ lods byte ptr [esi]
+ cmp al, 0
+ jne NotLldt
+
+ /* Check if this is an LLDT */
+ lods byte ptr [esi]
+ and al, 0x38
+ cmp al, 0x10
+ je IsPrivInstruction
+
+ /* Check if this is an LTR */
+ cmp al, 0x18
+ je IsPrivInstruction
+
+ /* Otherwise, access violation */
+ jmp NotIoViolation
+
+NotLldt:
+ /* Check if this is LGDT or LIDT or LMSW */
+ cmp al, 0x01
+ jne NotGdt
+
+ /* Check if this is an LGDT */
+ lods byte ptr [esi]
+ and al, 0x38
+ cmp al, 0x10
+ je IsPrivInstruction
+
+ /* Check if this is an LIDT */
+ cmp al, 0x18
+ je IsPrivInstruction
+
+ /* Check if this is an LMSW */
+ cmp al, 0x30
+ je IsPrivInstruction
+
+ /* Otherwise, access violation */
+ jmp NotIoViolation
+
+NotGdt:
+ /* Check if it's INVD or WBINVD */
+ cmp al, 0x8
+ je IsPrivInstruction
+ cmp al, 0x9
+ je IsPrivInstruction
+
+ /* Check if it's sysexit */
+ cmp al, 0x35
+ je IsPrivInstruction
+
+ /* Check if it's a DR move */
+ cmp al, 0x26
+ je IsPrivInstruction
+
+ /* Check if it's a CLTS */
+ cmp al, 0x6
+ je IsPrivInstruction
+
+ /* Check if it's a CR move */
+ cmp al, 0x20
+ jb NotIoViolation
+
+ /* Check if it's a DR move */
+ cmp al, 0x24
+ jbe IsPrivInstruction
+
+ /* Everything else is an access violation */
+ jmp NotIoViolation
CheckRing3Io:
/* Get EFLAGS and IOPL */
mov ebx, [ebp+KTRAP_FRAME_EFLAGS]
- and ebx, 0x3000
+ and ebx, EFLAGS_IOPL
shr ebx, 12
/* Check the CS's RPL mask */
IsPrivInstruction:
/* Cleanup the SEH frame */
- pop fs:[KPCR_EXCEPTION_LIST]
+ pop PCR[KPCR_EXCEPTION_LIST]
add esp, 8
/* Setup the exception */
NotIoViolation:
/* Cleanup the SEH frame */
- pop fs:[KPCR_EXCEPTION_LIST]
+ pop PCR[KPCR_EXCEPTION_LIST]
add esp, 8
SetException:
mov ebx, [ebp+KTRAP_FRAME_EIP]
mov esi, -1
mov eax, STATUS_ACCESS_VIOLATION
- jmp _DispatchTwoParam
+ jmp _DispatchTwoParamZero
DispatchV86Gpf:
/* FIXME */
.endfunc
.func KiTrap14
-Dr_kit14: DR_TRAP_FIXUP
-V86_kit14: V86_TRAP_FIXUP
+TRAP_FIXUPS kite_a, kite_t, DoFixupV86, DoNotFixupAbios
_KiTrap14:
/* Enter trap */
- TRAP_PROLOG kit14
+ TRAP_PROLOG kite_a, kite_t
/* Check if we have a VDM alert */
- cmp dword ptr fs:[KPCR_VDM_ALERT], 0
+ cmp dword ptr PCR[KPCR_VDM_ALERT], 0
jnz VdmAlertGpf
/* Get the current thread */
- mov edi, fs:[KPCR_CURRENT_THREAD]
+ mov edi, PCR[KPCR_CURRENT_THREAD]
/* Get the stack address of the frame */
lea eax, [esp+KTRAP_FRAME_LENGTH+NPX_FRAME_LENGTH]
jb NoFixUp
/* Check if we have a TEB */
- mov eax, fs:[KPCR_TEB]
+ mov eax, PCR[KPCR_TEB]
or eax, eax
jle NoFixUp
NoFixUp:
mov edi, cr2
- /* ROS HACK: Sometimes we get called with INTS DISABLED! WTF? */
+ /* REACTOS Mm Hack of Doom */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
je HandlePf
/* Enable interrupts and check if we got here with interrupts disabled */
sti
- test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
- jz IllegalState
+ /* test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
+ jz IllegalState */
HandlePf:
/* Send trap frame and check if this is kernel-mode or usermode */
/* Check if the fault occured in a V86 mode */
CheckVdmPf:
mov ecx, [ebp+KTRAP_FRAME_ERROR_CODE]
- and ecx, 1
shr ecx, 1
+ and ecx, 1
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz VdmPF
/* Check if the fault occured in a VDM */
- mov esi, fs:[KPCR_CURRENT_THREAD]
+ mov esi, PCR[KPCR_CURRENT_THREAD]
mov esi, [esi+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [esi+EPROCESS_VDM_OBJECTS], 0
jz CheckStatus
.endfunc
.func KiTrap0F
-Dr_kit15: DR_TRAP_FIXUP
-V86_kit15: V86_TRAP_FIXUP
+TRAP_FIXUPS kitf_a, kitf_t, DoFixupV86, DoNotFixupAbios
_KiTrap0F:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit15
+ TRAP_PROLOG kitf_a, kitf_t
sti
/* Raise a fatal exception */
.endfunc
.func KiTrap16
-Dr_kit16: DR_TRAP_FIXUP
-V86_kit16: V86_TRAP_FIXUP
+TRAP_FIXUPS kit10_a, kit10_t, DoFixupV86, DoNotFixupAbios
_KiTrap16:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit16
+ TRAP_PROLOG kit10_a, kit10_t
/* Check if this is the NPX Thread */
- mov eax, fs:[KPCR_CURRENT_THREAD]
- cmp eax, fs:[KPCR_NPX_THREAD]
+ mov eax, PCR[KPCR_CURRENT_THREAD]
+ cmp eax, PCR[KPCR_NPX_THREAD]
/* Get the initial stack and NPX frame */
mov ecx, [eax+KTHREAD_INITIAL_STACK]
.endfunc
.func KiTrap17
-Dr_kit17: DR_TRAP_FIXUP
-V86_kit17: V86_TRAP_FIXUP
+TRAP_FIXUPS kit11_a, kit11_t, DoFixupV86, DoNotFixupAbios
_KiTrap17:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit17
+ TRAP_PROLOG kit11_a, kit11_t
/* FIXME: ROS Doesn't handle alignment faults yet */
mov eax, 17
jmp _KiSystemFatalException
.endfunc
+.globl _KiTrap19
+.func KiTrap19
+TRAP_FIXUPS kit19_a, kit19_t, DoFixupV86, DoNotFixupAbios
+_KiTrap19:
+ /* Push error code */
+ push 0
+
+ /* Enter trap */
+ TRAP_PROLOG kit19_a, kit19_t
+
+ /* Check if this is the NPX Thread */
+ mov eax, PCR[KPCR_CURRENT_THREAD]
+ cmp eax, PCR[KPCR_NPX_THREAD]
+
+ /* If this is a valid fault, handle it */
+ jz HandleXmmiFault
+
+ /* Otherwise, bugcheck */
+ mov eax, 19
+ jmp _KiSystemFatalException
+
+HandleXmmiFault:
+ /* Get the initial stack and NPX frame */
+ mov ecx, [eax+KTHREAD_INITIAL_STACK]
+ lea ecx, [ecx-NPX_FRAME_LENGTH]
+
+ /* Check if the trap came from V86 mode */
+ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
+ jnz V86Xmmi
+
+ /* Check if it came from kernel mode */
+ test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
+ jz KernelXmmi
+
+ /* Check if it came from a VDM */
+ cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
+ jne VdmXmmi
+
+HandleUserXmmi:
+ /* Set new CR0 */
+ mov ebx, cr0
+ and ebx, ~(CR0_MP + CR0_EM + CR0_TS)
+ mov cr0, ebx
+
+ /* Check if we have FX support */
+ test byte ptr _KeI386FxsrPresent, 1
+ jz XmmiFnSave2
+
+ /* Save the state */
+ fxsave [ecx]
+ jmp XmmiMakeCr0Dirty
+XmmiFnSave2:
+ fnsave [ecx]
+ wait
+
+XmmiMakeCr0Dirty:
+ /* Make CR0 state not loaded */
+ or ebx, NPX_STATE_NOT_LOADED
+ or ebx, [ecx+FN_CR0_NPX_STATE]
+ mov cr0, ebx
+
+ /* Update NPX state */
+ mov byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
+ mov dword ptr PCR[KPCR_NPX_THREAD], 0
+
+ /* Clear the TS bit and re-enable interrupts */
+ and dword ptr [ecx+FN_CR0_NPX_STATE], ~CR0_TS
+
+ /* Re-enable interrupts for user-mode and send the exception */
+ sti
+ mov ebx, [ebp+KTRAP_FRAME_EIP]
+
+ /* Get MxCSR and get current mask (bits 7-12) */
+ movzx eax, word ptr [ecx+FX_MXCSR]
+ mov edx, eax
+ shr edx, 7
+ not edx
+
+ /* Set faulting opcode address to 0 */
+ mov esi, 0
+
+ /* Apply legal exceptions mask */
+ and eax, 0x3f
+
+ /* Apply the mask we got in MXCSR itself */
+ and eax, edx
+
+ /* Check for invalid operation */
+ test al, 1
+ jz 1f
+
+ /* Raise exception */
+ mov eax, STATUS_FLOAT_MULTIPLE_TRAPS
+ jmp _DispatchOneParamZero
+
+1:
+ /* Check for zero divide */
+ test al, 2
+ jz 1f
+
+ /* Raise exception */
+ mov eax, STATUS_FLOAT_MULTIPLE_TRAPS
+ jmp _DispatchOneParamZero
+
+1:
+ /* Check for denormal */
+ test al, 4
+ jz 1f
+
+ /* Raise exception */
+ mov eax, STATUS_FLOAT_MULTIPLE_TRAPS
+ jmp _DispatchOneParamZero
+
+1:
+ /* Check for overflow*/
+ test al, 8
+ jz 1f
+
+ /* Raise exception */
+ mov eax, STATUS_FLOAT_MULTIPLE_FAULTS
+ jmp _DispatchOneParamZero
+
+1:
+ /* Check for denormal */
+ test al, 16
+ jz 1f
+
+ /* Raise exception */
+ mov eax, STATUS_FLOAT_MULTIPLE_FAULTS
+ jmp _DispatchOneParamZero
+
+1:
+ /* Check for Precision */
+ test al, 32
+ jz UnexpectedXmmi
+
+ /* Raise exception */
+ mov eax, STATUS_FLOAT_MULTIPLE_FAULTS
+ jmp _DispatchOneParamZero
+
+UnexpectedXmmi:
+ /* Strange result, bugcheck the OS */
+ sti
+ push ebp
+ push 1
+ push 0
+ push eax
+ push 13
+ push TRAP_CAUSE_UNKNOWN
+ call _KeBugCheckWithTf@24
+
+VdmXmmi:
+ /* Check if this is a VDM */
+ mov eax, PCR[KPCR_CURRENT_THREAD]
+ mov ebx, [eax+KTHREAD_APCSTATE_PROCESS]
+ cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
+ jz HandleUserXmmi
+
+V86Xmmi:
+ /* V86 XMMI not handled */
+ UNHANDLED_PATH
+
+KernelXmmi:
+ /* Another weird situation */
+ push ebp
+ push 2
+ push 0
+ push eax
+ push 13
+ push TRAP_CAUSE_UNKNOWN
+ call _KeBugCheckWithTf@24
+.endfunc
+
+
.func KiSystemFatalException
_KiSystemFatalException:
_KiCoprocessorError@0:
/* Get the NPX Thread's Initial stack */
- mov eax, [fs:KPCR_NPX_THREAD]
+ mov eax, PCR[KPCR_NPX_THREAD]
mov eax, [eax+KTHREAD_INITIAL_STACK]
/* Make space for the FPU Save area */
push esp
/* Go to kernel mode thread stack */
- mov eax, fs:[KPCR_CURRENT_THREAD]
+ mov eax, PCR[KPCR_CURRENT_THREAD]
add esp, [eax+KTHREAD_INITIAL_STACK]
/* Switch to good stack segment */
jmp _KiUnexpectedInterruptTail
.func KiUnexpectedInterruptTail
-V86_kui: V86_TRAP_FIXUP
-Dr_kui: DR_TRAP_FIXUP
+TRAP_FIXUPS kui_a, kui_t, DoFixupV86, DoFixupAbios
_KiUnexpectedInterruptTail:
/* Enter interrupt trap */
- INT_PROLOG kui, DoNotPushFakeErrorCode
+ INT_PROLOG kui_a, kui_t, DoNotPushFakeErrorCode
/* Increase interrupt count */
- inc dword ptr [fs:KPCR_PRCB_INTERRUPT_COUNT]
+ inc dword ptr PCR[KPCR_PRCB_INTERRUPT_COUNT]
/* Put vector in EBX and make space for KIRQL */
mov ebx, [esp]
_KiDispatchInterrupt@0:
/* Get the PCR and disable interrupts */
- mov ebx, [fs:KPCR_SELF]
+ mov ebx, PCR[KPCR_SELF]
cli
/* Check if we have to deliver DPCs, timers, or deferred threads */
/* Save the stack and switch to the DPC Stack */
mov edx, esp
- //mov esp, [ebx+KPCR_PRCB_DPC_STACK]
+ mov esp, [ebx+KPCR_PRCB_DPC_STACK]
push edx
/* Deliver DPCs */
mov edi, [ebx+KPCR_CURRENT_THREAD]
#ifdef CONFIG_SMP
- #error SMP Interrupt not handled!
+ /* Raise to synch level */
+ call _KeRaiseIrqlToSynchLevel@0
+
+ /* Set context swap busy */
+ mov byte ptr [edi+KTHREAD_SWAP_BUSY], 1
+
+ /* Acquire the PRCB Lock */
+ lock bts dword ptr [ebx+KPCR_PRCB_PRCB_LOCK], 0
+ jnb GetNext
+ lea ecx, [ebx+KPCR_PRCB_PRCB_LOCK]
+ call @KefAcquireSpinLockAtDpcLevel@4
#endif
+GetNext:
/* Get the next thread and clear it */
mov esi, [ebx+KPCR_PRCB_NEXT_THREAD]
and dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
/* Set us as the current running thread */
mov [ebx+KPCR_CURRENT_THREAD], esi
- mov byte ptr [esi+KTHREAD_STATE], Running
+ mov byte ptr [esi+KTHREAD_STATE_], Running
mov byte ptr [edi+KTHREAD_WAIT_REASON], WrDispatchInt
/* Put thread in ECX and get the PRCB in EDX */
mov cl, APC_LEVEL
call @KiSwapContextInternal@0
+#ifdef CONFIG_SMP
+ /* Lower IRQL back to dispatch */
+ mov cl, DISPATCH_LEVEL
+ call @KfLowerIrql@4
+#endif
+
/* Restore registers */
mov ebp, [esp+0]
mov edi, [esp+4]
.endfunc
.func KiInterruptTemplate
-V86_kit: V86_TRAP_FIXUP
-Dr_kit: DR_TRAP_FIXUP
_KiInterruptTemplate:
/* Enter interrupt trap */
- INT_PROLOG kit, DoPushFakeErrorCode
-.endfunc
+ INT_PROLOG kit_a, kit_t, DoPushFakeErrorCode
_KiInterruptTemplate2ndDispatch:
/* Dummy code, will be replaced by the address of the KINTERRUPT */
_KiInterruptTemplateDispatch:
/* Marks the end of the template so that the jump above can be edited */
+TRAP_FIXUPS kit_a, kit_t, DoFixupV86, DoFixupAbios
+.endfunc
+
.func KiChainedDispatch2ndLvl@0
_KiChainedDispatch2ndLvl@0:
- /* Not yet supported */
- UNHANDLED_PATH
+NextSharedInt:
+ /* Raise IRQL if necessary */
+ mov cl, [edi+KINTERRUPT_SYNCHRONIZE_IRQL]
+ cmp cl, [edi+KINTERRUPT_IRQL]
+ je 1f
+ call @KfRaiseIrql@4
+
+1:
+ /* Acquire the lock */
+ mov esi, [edi+KINTERRUPT_ACTUAL_LOCK]
+GetIntLock2:
+ ACQUIRE_SPINLOCK(esi, IntSpin2)
+
+ /* Make sure that this interrupt isn't storming */
+ VERIFY_INT kid2
+
+ /* Save the tick count */
+ mov esi, _KeTickCount
+
+ /* Call the ISR */
+ mov eax, [edi+KINTERRUPT_SERVICE_CONTEXT]
+ push eax
+ push edi
+ call [edi+KINTERRUPT_SERVICE_ROUTINE]
+
+ /* Save the ISR result */
+ mov bl, al
+
+ /* Check if the ISR timed out */
+ add esi, _KiISRTimeout
+ cmp _KeTickCount, esi
+ jnc ChainedIsrTimeout
+
+ReleaseLock2:
+ /* Release the lock */
+ mov esi, [edi+KINTERRUPT_ACTUAL_LOCK]
+ RELEASE_SPINLOCK(esi)
+
+ /* Lower IRQL if necessary */
+ mov cl, [edi+KINTERRUPT_IRQL]
+ cmp cl, [edi+KINTERRUPT_SYNCHRONIZE_IRQL]
+ je 1f
+ call @KfLowerIrql@4
+
+1:
+ /* Check if the interrupt is handled */
+ or bl, bl
+ jnz 1f
+
+ /* Try the next shared interrupt handler */
+ mov eax, [edi+KINTERRUPT_INTERRUPT_LIST_HEAD]
+ lea edi, [eax-KINTERRUPT_INTERRUPT_LIST_HEAD]
+ jmp NextSharedInt
+
+1:
+ ret
+
+#ifdef CONFIG_SMP
+IntSpin2:
+ SPIN_ON_LOCK(esi, GetIntLock2)
+#endif
+
+ChainedIsrTimeout:
+ /* Print warning message */
+ push [edi+KINTERRUPT_SERVICE_ROUTINE]
+ push offset _IsrTimeoutMsg
+ call _DbgPrint
+ add esp,8
+
+ /* Break into debugger, then continue */
+ int 3
+ jmp ReleaseLock2
+
+ /* Cleanup verification */
+ VERIFY_INT_END kid2, 0
.endfunc
.func KiChainedDispatch@0
_KiChainedDispatch@0:
/* Increase interrupt count */
- inc dword ptr [fs:KPCR_PRCB_INTERRUPT_COUNT]
+ inc dword ptr PCR[KPCR_PRCB_INTERRUPT_COUNT]
/* Save trap frame */
mov ebp, esp
call _KiChainedDispatch2ndLvl@0
/* Exit the interrupt */
- mov esi, $
- cli
- call _HalEndSystemInterrupt@8
- jmp _Kei386EoiHelper@0
+ INT_EPILOG 0
.endfunc
.func KiInterruptDispatch@0
_KiInterruptDispatch@0:
/* Increase interrupt count */
- inc dword ptr [fs:KPCR_PRCB_INTERRUPT_COUNT]
+ inc dword ptr PCR[KPCR_PRCB_INTERRUPT_COUNT]
/* Save trap frame */
mov ebp, esp
jz SpuriousInt
/* Acquire the lock */
-GetIntLock:
mov esi, [edi+KINTERRUPT_ACTUAL_LOCK]
+GetIntLock:
ACQUIRE_SPINLOCK(esi, IntSpin)
+ /* Make sure that this interrupt isn't storming */
+ VERIFY_INT kid
+
+ /* Save the tick count */
+ mov ebx, _KeTickCount
+
/* Call the ISR */
mov eax, [edi+KINTERRUPT_SERVICE_CONTEXT]
push eax
push edi
call [edi+KINTERRUPT_SERVICE_ROUTINE]
+ /* Check if the ISR timed out */
+ add ebx, _KiISRTimeout
+ cmp _KeTickCount, ebx
+ jnc IsrTimeout
+
+ReleaseLock:
/* Release the lock */
RELEASE_SPINLOCK(esi)
/* Exit the interrupt */
- cli
- call _HalEndSystemInterrupt@8
- jmp _Kei386EoiHelper@0
+ INT_EPILOG 0
SpuriousInt:
/* Exit the interrupt */
add esp, 8
- jmp _Kei386EoiHelper@0
+ INT_EPILOG 1
#ifdef CONFIG_SMP
IntSpin:
- SPIN_ON_LOCK esi, GetIntLock
+ SPIN_ON_LOCK(esi, GetIntLock)
#endif
+
+IsrTimeout:
+ /* Print warning message */
+ push [edi+KINTERRUPT_SERVICE_ROUTINE]
+ push offset _IsrTimeoutMsg
+ call _DbgPrint
+ add esp,8
+
+ /* Break into debugger, then continue */
+ int 3
+ jmp ReleaseLock
+
+ /* Cleanup verification */
+ VERIFY_INT_END kid, 0
+.endfunc
+
+.globl _KeSynchronizeExecution@12
+.func KeSynchronizeExecution@12
+_KeSynchronizeExecution@12:
+
+ /* Save EBX and put the interrupt object in it */
+ push ebx
+ mov ebx, [esp+8]
+
+ /* Go to DIRQL */
+ mov cl, [ebx+KINTERRUPT_SYNCHRONIZE_IRQL]
+ call @KfRaiseIrql@4
+ push eax
+
+#ifdef CONFIG_SMP
+ /* Acquire the interrupt spinlock FIXME: Write this in assembly */
+ mov ecx, [ebx+KINTERRUPT_ACTUAL_LOCK]
+ call @KefAcquireSpinLockAtDpcLevel@4
+#endif
+
+ /* Call the routine */
+ push [esp+20]
+ call [esp+20]
+
+#ifdef CONFIG_SMP
+ /* Release the interrupt spinlock FIXME: Write this in assembly */
+ push eax
+ mov ecx, [ebx+KINTERRUPT_ACTUAL_LOCK]
+ call @KefReleaseSpinLockFromDpcLevel@4
+ pop eax
+#endif
+
+ /* Lower IRQL */
+ mov ebx, eax
+ pop ecx
+ call @KfLowerIrql@4
+
+ /* Return status */
+ mov eax, ebx
+ pop ebx
+ ret 12
+.endfunc
+
+/*++
+ * Kii386SpinOnSpinLock
+ *
+ * FILLMEIN
+ *
+ * Params:
+ * SpinLock - FILLMEIN
+ *
+ * Flags - FILLMEIN
+ *
+ * Returns:
+ * None.
+ *
+ * Remarks:
+ * FILLMEIN
+ *
+ *--*/
+.globl _Kii386SpinOnSpinLock@8
+.func Kii386SpinOnSpinLock@8
+_Kii386SpinOnSpinLock@8:
+
+#ifdef CONFIG_SMP
+ /* FIXME: TODO */
+ int 3
+#endif
+
+ ret 8
.endfunc