From c8c71fcd5c5d20ab522c1f81b9e48bcaa3d104c7 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 24 Aug 2006 01:53:54 +0000 Subject: [PATCH] - Implement Chained and Normal generic interrupt handlers. - Make generated handlers have a proper .func symbol for symbol data. - Make IDT writable, the page shouldn't be read-only. - Change some symbol names. svn path=/trunk/; revision=23676 --- reactos/hal/halx86/generic/systimer.S | 1 + reactos/include/ndk/asm.h | 10 ++ .../ntoskrnl/include/internal/i386/asmmacro.S | 4 +- reactos/ntoskrnl/ke/i386/kernel.c | 5 + reactos/ntoskrnl/ke/i386/trap.s | 127 +++++++++++++++++- 5 files changed, 143 insertions(+), 4 deletions(-) diff --git a/reactos/hal/halx86/generic/systimer.S b/reactos/hal/halx86/generic/systimer.S index e7c14bc352e..019f909f8df 100644 --- a/reactos/hal/halx86/generic/systimer.S +++ b/reactos/hal/halx86/generic/systimer.S @@ -23,3 +23,4 @@ _HalpClockInterrupt@0: jmp $ .endfunc + diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index 58161d45ff7..eea6d7d4525 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -155,6 +155,16 @@ Author: #define KPCR_SYSTEM_CALLS 0x6B8 #define KPCR_PRCB_DPC_ROUTINE_ACTIVE 0x994 +// +// KINTERRUPT Offsets +// +#define KINTERRUPT_SERVICE_ROUTINE 0x0C +#define KINTERRUPT_SERVICE_CONTEXT 0x10 +#define KINTERRUPT_ACTUAL_LOCK 0x1C +#define KINTERRUPT_IRQL 0x20 +#define KINTERRUPT_VECTOR 0x24 +#define KINTERRUPT_SYNCHRONIZE_IRQL 0x29 + // // KGDTENTRY Offsets // diff --git a/reactos/ntoskrnl/include/internal/i386/asmmacro.S b/reactos/ntoskrnl/include/internal/i386/asmmacro.S index e755477546e..9f1a25ba560 100644 --- a/reactos/ntoskrnl/include/internal/i386/asmmacro.S +++ b/reactos/ntoskrnl/include/internal/i386/asmmacro.S @@ -125,9 +125,11 @@ idt _KiUnexpectedInterrupt&Number, INT_32_DPL0 // @remark None. // .macro GENERATE_INT_HANDLER Number +.func KiUnexpectedInterrupt&Number _KiUnexpectedInterrupt&Number: push PRIMARY_VECTOR_BASE + Number - jmp _KiEndUnexpected + jmp _KiEndUnexpectedRange@0 +.endfunc .endm // diff --git a/reactos/ntoskrnl/ke/i386/kernel.c b/reactos/ntoskrnl/ke/i386/kernel.c index 3cbba0cfd2e..e8876a3a872 100644 --- a/reactos/ntoskrnl/ke/i386/kernel.c +++ b/reactos/ntoskrnl/ke/i386/kernel.c @@ -489,6 +489,7 @@ INIT_FUNCTION NTAPI KeInit2(VOID) { + ULONG Protect; PKIPCR Pcr = (PKIPCR)KeGetCurrentKPCR(); KiInitializeBugCheck(); @@ -548,6 +549,10 @@ KeInit2(VOID) { DPRINT("Ke386L2CacheSize: %dkB\n", Pcr->SecondLevelCacheSize); } + + /* Set IDT to writable */ + Protect = MmGetPageProtect(NULL, (PVOID)KiIdt); + MmSetPageProtect(NULL, (PVOID)KiIdt, Protect | PAGE_IS_WRITABLE); } VOID INIT_FUNCTION diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index bc62f7a8a73..662cc3bd520 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -59,6 +59,12 @@ GENERATE_IDT_STUBS /* INT 30-FF: UNEXPECTED INTERRUPTS */ /* Interrupt template entrypoints */ .globl _KiInterruptTemplate .globl _KiInterruptTemplateObject +.globl _KiInterruptTemplateDispatch + +/* Chained and Normal generic interrupt handlers for 1st and 2nd level entry*/ +.globl _KiChainedDispatch2ndLvl@0 +.globl _KiInterruptDispatch3@0 +.globl _KiChainedDispatch@0 /* We implement the following trap exit points: */ .globl _KiServiceExit /* Exit from syscall */ @@ -71,6 +77,10 @@ _KiIdtDescriptor: .short 0x800 .long _KiIdt +.globl _KiUnexpectedEntrySize +_KiUnexpectedEntrySize: + .long _KiUnexpectedInterrupt1 - _KiUnexpectedInterrupt0 + /* SOFTWARE INTERRUPT SERVICES ***********************************************/ _KiGetTickCount: @@ -1301,12 +1311,13 @@ _KiSystemFatalException: /* UNEXPECTED INTERRUPT HANDLERS **********************************************/ -.globl _KiStartUnexpected -_KiStartUnexpected: +.globl _KiStartUnexpectedRange@0 +_KiStartUnexpectedRange@0: GENERATE_INT_HANDLERS -_KiEndUnexpected: +.globl _KiEndUnexpectedRange@0 +_KiEndUnexpectedRange@0: jmp _KiUnexpectedInterruptTail .func KiUnexpectedInterruptTail @@ -1367,3 +1378,113 @@ _KiInterruptTemplate2ndDispatch: _KiInterruptTemplateObject: /* Dummy jump, will be replaced by the actual jump */ jmp _KeSynchronizeExecution@12 + +_KiInterruptTemplateDispatch: + /* Marks the end of the template so that the jump above can be edited */ + +.func KiChainedDispatch2ndLvl@0 +_KiChainedDispatch2ndLvl@0: + + /* Not yet supported */ + int 3 +.endfunc + +.func KiChainedDispatch@0 +_KiChainedDispatch@0: + + /* Increase interrupt count */ + inc dword ptr [fs:KPCR_PRCB_INTERRUPT_COUNT] + + /* Save trap frame */ + mov ebp, esp + + /* Save vector and IRQL */ + mov eax, [edi+KINTERRUPT_VECTOR] + mov ecx, [edi+KINTERRUPT_IRQL] + + /* Save old irql */ + push eax + sub esp, 4 + + /* Begin interrupt */ + push eax + push ecx + call _HalBeginSystemInterrupt@12 + + /* Check if it was handled */ + or eax, eax + jz SpuriousInt + sub esp, 12 + + /* Call the 2nd-level handler */ + call _KiChainedDispatch2ndLvl@0 + + /* Exit the interrupt */ + mov esi, $ + cli + call _HalEndSystemInterrupt@8 + jmp _Kei386EoiHelper@0 +.endfunc + +.func KiInterruptDispatch3@0 +_KiInterruptDispatch3@0: + + /* Increase interrupt count */ + inc dword ptr [fs:KPCR_PRCB_INTERRUPT_COUNT] + + /* Save trap frame */ + mov ebp, esp + + /* Save vector and IRQL */ + mov eax, [edi+KINTERRUPT_VECTOR] + mov ecx, [edi+KINTERRUPT_SYNCHRONIZE_IRQL] + + /* Save old irql */ + push eax + sub esp, 4 + push esp + + /* Begin interrupt */ + push eax + push ecx + call _HalBeginSystemInterrupt@12 + + /* Check if it was handled */ + or eax, eax + jz SpuriousInt + sub esp, 12 + + /* Acquire the lock */ +GetIntLock: + mov esi, [edi+KINTERRUPT_ACTUAL_LOCK] + ACQUIRE_SPINLOCK(esi, IntSpin) + + /* Call the ISR */ + mov eax, [edi+KINTERRUPT_SERVICE_CONTEXT] + push eax + push edi + call [edi+KINTERRUPT_SERVICE_ROUTINE] + + /* Release the lock */ + RELEASE_SPINLOCK(esi) + + /* Clean up the stack */ + add esp, 12 + + /* Exit the interrupt */ + mov esi, $ + cli + call _HalEndSystemInterrupt@8 + jmp _Kei386EoiHelper@0 + +SpuriousInt: + /* Exit the interrupt */ + add esp, 8 + mov esi, $ + jmp _Kei386EoiHelper@0 + +#ifdef CONFIG_SMP +IntSpin: + SPIN_ON_LOCK esi, GetIntLock +#endif +.endfunc