/* Increase total syscall count */
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
push 0
jmp _KiTrap6
-#ifdef DBG
+#if DBG
InvalidIrql:
/* Save current IRQL */
push PCR[KPCR_IRQL]
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 */
TRAP_PROLOG kit3_a, kit3_t
/* Set status code */
- mov eax, 0 //STATUS_SUCCESS
+ mov eax, STATUS_SUCCESS
/* Check for V86 */
PrepareInt3:
/* Raise exception */
mov eax, STATUS_FLOAT_INVALID_OPERATION
- jmp _DispatchOneParam
+ jmp _DispatchOneParamZero
InvalidStack:
/* Raise exception */
mov eax, STATUS_FLOAT_STACK_CHECK
- xor edx, edx
- 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:
.globl _KiTrap8
.func KiTrap8
_KiTrap8:
-
/* Can't really do too much */
mov eax, 8
jmp _KiSystemFatalException
/* Otherwise, something is very wrong, raise an exception */
sti
- mov ebx, [ebp+KTRAP_FRAME_EIP]
- mov esi, -1
- mov eax, STATUS_ACCESS_VIOLATION
- xor edx, edx
- jmp _DispatchTwoParam
+ jmp SetException
RaiseIrql:
NotV86:
/* Enter trap */
TRAP_PROLOG kitd_a, kitd_t
-
+
/* Check if this was from kernel-mode */
test dword ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jnz UserModeGpf
cmp eax, offset CheckPrivilegedInstruction
jbe KmodeGpf
cmp eax, offset CheckPrivilegedInstruction2
+ jae KmodeGpf
/* FIXME: TODO */
UNHANDLED_PATH
mov esi, [ebp+KTRAP_FRAME_ERROR_CODE]
and esi, 0xFFFF
mov eax, STATUS_ACCESS_VIOLATION
- xor edx, edx
- jmp _DispatchTwoParam
+ jmp _DispatchTwoParamZero
MsrCheck:
/* 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 */
mov ebx, [ebp+KTRAP_FRAME_EIP]
mov esi, -1
mov eax, STATUS_ACCESS_VIOLATION
- xor edx, edx
- jmp _DispatchTwoParam
+ jmp _DispatchTwoParamZero
DispatchV86Gpf:
/* FIXME */
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 */
/* Raise exception */
mov eax, STATUS_FLOAT_MULTIPLE_TRAPS
- jmp _DispatchOneParam
+ jmp _DispatchOneParamZero
1:
/* Check for zero divide */
/* Raise exception */
mov eax, STATUS_FLOAT_MULTIPLE_TRAPS
- jmp _DispatchOneParam
+ jmp _DispatchOneParamZero
1:
/* Check for denormal */
/* Raise exception */
mov eax, STATUS_FLOAT_MULTIPLE_TRAPS
- jmp _DispatchOneParam
+ jmp _DispatchOneParamZero
1:
/* Check for overflow*/
/* Raise exception */
mov eax, STATUS_FLOAT_MULTIPLE_FAULTS
- jmp _DispatchOneParam
+ jmp _DispatchOneParamZero
1:
/* Check for denormal */
/* Raise exception */
mov eax, STATUS_FLOAT_MULTIPLE_FAULTS
- jmp _DispatchOneParam
+ jmp _DispatchOneParamZero
1:
/* Check for Precision */
/* Raise exception */
mov eax, STATUS_FLOAT_MULTIPLE_FAULTS
- jmp _DispatchOneParam
+ jmp _DispatchOneParamZero
UnexpectedXmmi:
/* Strange result, bugcheck the OS */
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
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]
.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
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 */
#ifdef CONFIG_SMP
IntSpin:
- SPIN_ON_LOCK esi, GetIntLock
+ SPIN_ON_LOCK(esi, GetIntLock)
#endif
IsrTimeout:
/* 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 eax
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
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