_KiGetTickCount:
_KiCallbackReturn:
-_KiRaiseAssertion:
/* FIXME: TODO */
UNHANDLED_PATH
/* 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]
/* FIXME: TODO */
UNHANDLED_PATH
+.func KiRaiseAssertion
+TRAP_FIXUPS kira_a, kira_t, DoFixupV86, DoFixupAbios
+_KiRaiseAssertion:
+
+ /* Push error code */
+ push 0
+
+ /* Enter trap */
+ TRAP_PROLOG kira_a, kira_t
+
+ /*
+ * Modify EIP so it points to the faulting instruction and set it as the
+ * exception address. Note that the 'int 2C' instruction used for this call
+ * is 2 bytes long as opposed to 1 byte 'int 3'.
+ */
+ sub dword ptr [ebp+KTRAP_FRAME_EIP], 2
+ mov ebx, [ebp+KTRAP_FRAME_EIP]
+
+ /* Raise an assertion failure */
+ mov eax, STATUS_ASSERTION_FAILURE
+ jmp _DispatchNoParam
+.endfunc
+
.func KiDebugService
TRAP_FIXUPS kids_a, kids_t, DoFixupV86, DoFixupAbios
_KiDebugService:
/* Enter trap */
TRAP_PROLOG kit3_a, kit3_t
- /* Set status code */
- mov eax, 0 //STATUS_SUCCESS
+ /*
+ * Set the special code to indicate that this is a software breakpoint
+ * and not a debug service call
+ */
+ mov eax, BREAKPOINT_BREAK
/* Check for V86 */
PrepareInt3:
/* Enter V86 Trap */
V86_TRAP_PROLOG kit6_a, kit6_v
+VdmOpCodeFault:
/* Not yet supported (Invalid OPCODE from V86) */
UNHANDLED_PATH
/* Enter trap */
TRAP_PROLOG kit6_a, kit6_t
+DispatchLockErrata:
/* Check if this happened in kernel mode */
test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jz KmodeOpcode
.globl _KiTrap8
.func KiTrap8
_KiTrap8:
-
/* Can't really do too much */
mov eax, 8
jmp _KiSystemFatalException
cmp eax, offset CheckPrivilegedInstruction
jbe KmodeGpf
cmp eax, offset CheckPrivilegedInstruction2
+ jae KmodeGpf
/* FIXME: TODO */
UNHANDLED_PATH
NoFixUp:
mov edi, cr2
- /* ROS HACK: Sometimes we get called with INTS DISABLED! WTF? */
+ /* Check if this processor has the cmpxchg8b lock errata */
+ cmp byte ptr _KiI386PentiumLockErrataPresent, 0
+ jnz HandleLockErrata
+
+NotLockErrata:
+ /* HACK: Handle page faults with interrupts disabled */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
je HandlePf
/* Enable interrupts and check if we got here with interrupts disabled */
sti
+#ifdef HACK_ABOVE_FIXED
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
jz IllegalState
+#endif
HandlePf:
/* Send trap frame and check if this is kernel-mode or usermode */
/* FIXME: NOT SUPPORTED */
UNHANDLED_PATH
+
+HandleLockErrata:
+
+ /* Fail if this isn't a write fault */
+ test word ptr [ebp+KTRAP_FRAME_ERROR_CODE], 0x4
+ jnz NotLockErrata
+
+ /* Also make sure the page fault is for IDT entry 6 */
+ mov eax, PCR[KPCR_IDT]
+ add eax, 0x30
+ cmp eax, edi
+ jne NotLockErrata
+
+ /*
+ * This is a write fault to the Invalid Opcode handler entry.
+ * We assume this is the lock errata and not a real write fault.
+ */
+
+ /* Clear the error code */
+ and dword ptr [ebp+KTRAP_FRAME_ERROR_CODE], 0
+
+ /* Check if this happened in V86 mode */
+ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
+ jnz VdmOpCodeFault
+
+ /* Dispatch this to the invalid opcode handler */
+ jmp DispatchLockErrata
.endfunc
.func KiTrap0F
.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 */
/* 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