diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index 8653573051b..c2bc29e4971 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -135,6 +135,9 @@ Author: #define KPCR_SELF 0x1C #define KPCR_PRCB 0x20 #define KPCR_IRQL 0x24 +#define KPCR_IRR 0x28 +#define KPCR_IRR_ACTIVE 0x2C +#define KPCR_IDR 0x30 #define KPCR_KD_VERSION_BLOCK 0x34 #define KPCR_IDT 0x38 #define KPCR_GDT 0x3C @@ -148,6 +151,7 @@ Author: #define KPCR_NPX_THREAD 0x640 #define KPCR_DR6 0x428 #define KPCR_DR7 0x42C +#define KPCR_PRCB_INTERRUPT_COUNT 0x644 #define KPCR_SYSTEM_CALLS 0x6B8 #define KPCR_PRCB_DPC_ROUTINE_ACTIVE 0x994 @@ -400,6 +404,9 @@ Author: // #define PASSIVE_LEVEL 0x0 #define APC_LEVEL 0x1 +#define DISPATCH_LEVEL 0x2 +#define CLOCK2_LEVEL 0x1C +#define HIGH_LEVEL 0x1F #endif // @@ -424,6 +431,11 @@ Author: #define MACHINE_TYPE_EISA 0x0001 #define MACHINE_TYPE_MCA 0x0002 +// +// Vector base +// +#define PRIMARY_VECTOR_BASE 0x30 + // // Kernel Feature Bits // diff --git a/reactos/ntoskrnl/include/internal/i386/asmmacro.S b/reactos/ntoskrnl/include/internal/i386/asmmacro.S index 9d1384e34f6..df366883c05 100644 --- a/reactos/ntoskrnl/include/internal/i386/asmmacro.S +++ b/reactos/ntoskrnl/include/internal/i386/asmmacro.S @@ -64,14 +64,17 @@ #endif // -// @name SET_TF_DEBUG_HEADER +// @name IDT // -// This macro sets up the debug header in the trap frame. +// This macro creates an IDT entry for the given handler // -// @param None. +// @param Handler +// Pointer to the IDT handler // -// @remark ebp = PKTRAP_FRAME. -// edi/ebx = Have been saved and can be used. +// @param Bits +// Descriptor Bits to associate +// +// @remark None. // .macro idt Handler, Bits .long \Handler @@ -79,6 +82,70 @@ .short KGDT_R0_CODE .endm +// +// @name GENERATE_IDT_STUB +// +// This macro creates an IDT entry for an unexpected interrupt handler. +// +// @param None. +// +// @remark None. +// +.macro GENERATE_IDT_STUB Number +idt _KiUnexpectedInterrupt&Number, INT_32_DPL0 +.endm + +// +// @name GENERATE_IDT_STUBS +// +// This macro creates unexpected interrupt IDT entries. +// +// @param None. +// +// @remark None. +// +.altmacro +.macro GENERATE_IDT_STUBS +.set i, 0 +.rept 208 + GENERATE_IDT_STUB %i + .set i, i + 1 +.endr +.endm + +// +// @name GENERATE_INT_HANDLER +// +// This macro creates an unexpected interrupt handler. +// +// @param None. +// +// @remark None. +// +.macro GENERATE_INT_HANDLER Number +_KiUnexpectedInterrupt&Number: + push PRIMARY_VECTOR_BASE + Number + jmp _KiEndUnexpected +.endm + +// +// @name GENERATE_INT_HANDLERS +// +// This macro creates the unexpected interrupt handlers. +// +// @param None. +// +// @remark None. +// +.altmacro +.macro GENERATE_INT_HANDLERS +.set i, 0 +.rept 208 + GENERATE_INT_HANDLER %i + .set i, i + 1 +.endr +.endm + // // @name SET_TF_DEBUG_HEADER // @@ -253,6 +320,93 @@ /* Set the Trap Frame Debug Header */ \ SET_TF_DEBUG_HEADER +// +// @name INT_PROLOG +// +// This macro creates a standard interrupt entry prologue. +// It should be used for entry into any interrupt, including software. +// +// @param Label +// Identifying name of the caller function; will be used to append +// to the name V86, ABIOS and DR helper functions, which must exist. +// +// @remark For software interrupts, make sure that a fake INT stack is created. +// +.macro INT_PROLOG Label + /* Save fake error code */ + push esp + + /* Save the non-volatiles */ + push ebp + push ebx + push esi + push edi + + /* Skip debug registers and other stuff */ + sub esp, 0x54 + + /* Set up frame */ + mov ebp, esp + + /* Save volatiles */ + mov [esp+KTRAP_FRAME_EAX], eax + mov [esp+KTRAP_FRAME_ECX], ecx + mov [esp+KTRAP_FRAME_EDX], edx + mov dword ptr [esp+KTRAP_FRAME_EXCEPTION_LIST], -1 + + /* Check if this was from V86 Mode */ + /* test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK */ + /* jnz V86_&Label*/ + + /* Check if this was kernel mode */ + cmp dword ptr [esp+KTRAP_FRAME_CS], KGDT_R0_CODE + jz 1f + + /* Set segments */ + mov word ptr [esp+KTRAP_FRAME_FS], fs + mov word ptr [esp+KTRAP_FRAME_DS], ds + mov word ptr [esp+KTRAP_FRAME_ES], es + mov word ptr [esp+KTRAP_FRAME_GS], gs + + /* Load the segment registers */ + mov ebx, KGDT_R0_PCR + mov eax, KGDT_R3_DATA | RPL_MASK + mov fs, bx + mov ds, ax + mov es, ax + +1: + /* Save the previous exception list */ + mov ebx, [fs:KPCR_EXCEPTION_LIST] + mov [esp+KTRAP_FRAME_EXCEPTION_LIST], ebx + + /* Set the exception handler chain terminator */ + mov dword ptr [fs:KPCR_EXCEPTION_LIST], -1 + + /* Check if this is the ABIOS stack */ + /* cmp esp, 0x10000*/ + /* jb Abios_Label*/ + + /* Delete error code */ + and dword ptr [esp+KTRAP_FRAME_ERROR_CODE], 0 + + /* Get the current thread and clear direction flag */ + mov ecx, [fs:KPCR_CURRENT_THREAD] + cld + + /* Flush DR7 */ + and dword ptr [ebp+KTRAP_FRAME_DR7], 0 + + /* Check if the thread was being debugged */ + test byte ptr [ecx+KTHREAD_DEBUG_ACTIVE], 0xFF + + /* Save DR registers if needed */ + //jnz Dr_&Label + + /* Set the trap frame debug header */ + SET_TF_DEBUG_HEADER +.endm + // // @name SYSCALL_PROLOG // diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index 62c77ee933b..ef30f8ef247 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -46,9 +46,7 @@ idt _KiRaiseAssertion, INT_32_DPL3 /* INT 2C: Debug Assertion Handler */ idt _KiDebugService, INT_32_DPL3 /* INT 2D: Debug Service Handler */ idt _KiSystemService, INT_32_DPL3 /* INT 2E: System Call Service Handler */ idt _KiTrap0F, INT_32_DPL0 /* INT 2F: RESERVED */ -.rept 220 -idt _KiTrap0F, INT_32_DPL0 /* INT 30-FF: UNDEFINED INTERRUPTS */ -.endr +GENERATE_IDT_STUBS /* INT 30-FF: UNEXPECTED INTERRUPTS */ /* System call entrypoints: */ .globl _KiFastCallEntry @@ -62,13 +60,14 @@ idt _KiTrap0F, INT_32_DPL0 /* INT 30-FF: UNDEFINED INTERRUPTS */ .globl _KiServiceExit /* Exit from syscall */ .globl _KiServiceExit2 /* Exit from syscall with complete frame*/ .globl _Kei386EoiHelper@0 /* Exit from interrupt or H/W trap */ +.globl _Kei386EoiHelper2ndEntry /* Exit from unexpected interrupt */ .globl _KiIdtDescriptor _KiIdtDescriptor: .short 0x800 .long _KiIdt -/* FUNCTIONS ****************************************************************/ +/* SOFTWARE INTERRUPT SERVICES ***********************************************/ _KiGetTickCount: _KiCallbackReturn: @@ -490,6 +489,7 @@ _Kei386EoiHelper@0: CHECK_FOR_APC_DELIVER 0 /* Exit and cleanup */ +_Kei386EoiHelper2ndEntry: TRAP_EPILOG NotFromSystemCall, DoNotRestorePreviousMode, DoRestoreSegments, DoRestoreVolatiles, DoNotRestoreEverything .endfunc @@ -670,6 +670,8 @@ Error: jmp _KiServiceExit .endfunc +/* EXCEPTION DISPATCHERS *****************************************************/ + .func CommonDispatchException _CommonDispatchException: @@ -747,6 +749,8 @@ _DispatchTwoParam: call _CommonDispatchException .endfunc +/* HARDWARE TRAP HANDLERS ****************************************************/ + .func KiTrap0 _KiTrap0: /* Push error code */ @@ -1291,4 +1295,54 @@ _KiSystemFatalException: ret .endfunc +/* INTERRUPT HANDLERS ********************************************************/ +.globl _KiStartUnexpected +_KiStartUnexpected: + +GENERATE_INT_HANDLERS + +_KiEndUnexpected: + jmp _KiUnexpectedInterruptTail + +.func KiUnexpectedInterruptTail +_KiUnexpectedInterruptTail: + + /* Enter interrupt trap */ + INT_PROLOG(kui) + + /* Increase interrupt count */ + inc dword ptr [fs:KPCR_PRCB_INTERRUPT_COUNT] + + /* Put vector in EBX and make space for KIRQL */ + mov ebx, [esp] + sub esp, 4 + + /* Begin interrupt */ + push esp + push ebx + push HIGH_LEVEL + call _HalBeginSystemInterrupt@12 + + /* Check if it was spurious or not */ + or eax, eax + jnz Handled + + /* Spurious, ignore it */ + add esp, 8 + jmp _Kei386EoiHelper2ndEntry + +Handled: + /* Unexpected, exit the interrupt */ + mov esi, $ + cli + call _HalEndSystemInterrupt@8 + jmp _Kei386EoiHelper@0 +.endfunc + +.globl _KiUnexpectedInterrupt +_KiUnexpectedInterrupt: + + /* Bugcheck with invalid interrupt code */ + push 0x12 + call _KeBugCheck@4 diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 7afaddae452..80aab1f1693 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -656,7 +656,7 @@ KeWaitForMutexObject@20=KeWaitForSingleObject@20 KeWaitForSingleObject@20 @KefAcquireSpinLockAtDpcLevel@4 @KefReleaseSpinLockFromDpcLevel@4 -;Kei386EoiHelper +Kei386EoiHelper@0 @KiAcquireSpinLock@4 ;KiBugCheckData DATA KiCoprocessorError@0 @@ -667,7 +667,7 @@ KiEnableTimerWatchdog KiInterruptDispatch2@8 KiIpiServiceRoutine@8 @KiReleaseSpinLock@4 -KiUnexpectedInterrupt@0 +KiUnexpectedInterrupt ;Kii386SpinOnSpinLock KiRawTicks DATA LdrAccessResource@16