Author: ion Date: Thu Aug 24 09:36:50 2006 New Revision: 23678
URL: http://svn.reactos.org/svn/reactos?rev=23678&view=rev Log: - Write a basic Clock Interrupt handler in the HAL (doesn't deal with changing increments yet, just like current ROS). It will call KeUpdateSystemTime once ready. - Implement KeDisconnectInterrupt with the new implementation. - Put Clock Interrupt initialization in the right place (might still be too late: must investigate more). - Added a debug print when unexpected interrupts are called, just noticed this happens on my checked machine, and it's a useful tracing tool.
Modified: trunk/reactos/hal/halx86/generic/halinit.c trunk/reactos/hal/halx86/generic/systimer.S trunk/reactos/hal/halx86/up/halinit_up.c trunk/reactos/ntoskrnl/ke/clock.c trunk/reactos/ntoskrnl/ke/i386/irq.c trunk/reactos/ntoskrnl/ke/i386/trap.s
Modified: trunk/reactos/hal/halx86/generic/halinit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/halinit.... ============================================================================== --- trunk/reactos/hal/halx86/generic/halinit.c (original) +++ trunk/reactos/hal/halx86/generic/halinit.c Thu Aug 24 09:36:50 2006 @@ -19,6 +19,7 @@
PVOID HalpZeroPageMapping = NULL; HALP_HOOKS HalpHooks; +VOID NTAPI HalpClockInterrupt(VOID);
/* FUNCTIONS ***************************************************************/
@@ -31,6 +32,10 @@ return STATUS_SUCCESS; }
+#define MAKEULONG(x, y) \ + (((((ULONG)(x))<<16) & 0xffff0000) | \ + ((ULONG)(y) & 0xffff)) + BOOLEAN STDCALL HalInitSystem (ULONG BootPhase, PLOADER_PARAMETER_BLOCK LoaderBlock) @@ -42,6 +47,14 @@ } else if (BootPhase == 1) { +#if 0 + /* Enable the clock interrupt */ + ((PKIPCR)KeGetPcr())->IDT[IRQ2VECTOR(0)].ExtendedOffset = + (USHORT)(((ULONG_PTR)HalpClockInterrupt >> 16) & 0xFFFF); + ((PKIPCR)KeGetPcr())->IDT[IRQ2VECTOR(0)].Offset = + (USHORT)HalpClockInterrupt; + HalEnableSystemInterrupt(IRQ2VECTOR(0), CLOCK2_LEVEL, Latched); +#endif /* Initialize display and make the screen black */ HalInitializeDisplay ((PROS_LOADER_PARAMETER_BLOCK)LoaderBlock); HalpInitBusHandlers();
Modified: trunk/reactos/hal/halx86/generic/systimer.S URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/systimer... ============================================================================== --- trunk/reactos/hal/halx86/generic/systimer.S (original) +++ trunk/reactos/hal/halx86/generic/systimer.S Thu Aug 24 09:36:50 2006 @@ -12,8 +12,7 @@ .intel_syntax noprefix
.extern _Kei386EoiHelper@0 - -/* GLOBALS *******************************************************************/ +.extern _KeUpdateSystemTime@0
/* FUNCTIONS *****************************************************************/
@@ -21,6 +20,31 @@ .func HalpClockInterrupt@0 _HalpClockInterrupt@0:
- jmp $ + /* Enter trap */ + INT_PROLOG Hci, DoPushFakeErrorCode + + /* Push vector and make stack for IRQL */ + push 0x30 + sub esp, 4 + + /* Begin the interrupt */ + push esp + push 0x30 + push CLOCK2_LEVEL + call _HalBeginSystemInterrupt@12 + + /* Check if it's spurious */ + or al, al + jz Spurious + + /* Do a tick */ + //jmp _KeUpdateSystemTime@0 + +Spurious: + + /* Exit the interrupt */ + add esp, 8 + mov esi, $ + jmp _Kei386EoiHelper@0 .endfunc
Modified: trunk/reactos/hal/halx86/up/halinit_up.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/up/halinit_up.c?... ============================================================================== --- trunk/reactos/hal/halx86/up/halinit_up.c (original) +++ trunk/reactos/hal/halx86/up/halinit_up.c Thu Aug 24 09:36:50 2006 @@ -15,8 +15,6 @@ #define NDEBUG #include <debug.h>
-VOID NTAPI HalpClockInterrupt(VOID); - /* FUNCTIONS ***************************************************************/
VOID @@ -24,15 +22,6 @@ { HalpInitPICs();
- /* Enable the clock interrupt */ -#if 0 - ((PKIPCR)KeGetPcr())->IDT[IRQ2VECTOR(0)].ExtendedOffset = - (USHORT)(((ULONG_PTR)HalpClockInterrupt >> 16) & 0xFFFF); - ((PKIPCR)KeGetPcr())->IDT[IRQ2VECTOR(0)].Offset = - (USHORT)HalpClockInterrupt; -#endif - HalEnableSystemInterrupt(IRQ2VECTOR(0), CLOCK2_LEVEL, Latched); - /* Setup busy waiting */ HalpCalibrateStallExecution(); }
Modified: trunk/reactos/ntoskrnl/ke/clock.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/clock.c?rev=236... ============================================================================== --- trunk/reactos/ntoskrnl/ke/clock.c (original) +++ trunk/reactos/ntoskrnl/ke/clock.c Thu Aug 24 09:36:50 2006 @@ -37,7 +37,7 @@
CHAR KiTimerSystemAuditing = 0; static KDPC KiExpireTimerDpc; -static BOOLEAN KiClockSetupComplete = FALSE; +BOOLEAN KiClockSetupComplete = FALSE;
extern ULONG KiMaximumDpcQueueDepth; extern ULONG KiMinimumDpcRate;
Modified: trunk/reactos/ntoskrnl/ke/i386/irq.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/irq.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/irq.c (original) +++ trunk/reactos/ntoskrnl/ke/i386/irq.c Thu Aug 24 09:36:50 2006 @@ -65,15 +65,10 @@ NTAPI KiChainedDispatch(VOID);
- -/* GLOBALS *****************************************************************/ +/* DEPRECATED FUNCTIONS ******************************************************/
void irq_handler_0(void); - extern IDT_DESCRIPTOR KiIdt[256]; - -/* FUNCTIONS ****************************************************************/ - #define PRESENT (0x8000) #define I486_INTERRUPT_GATE (0xe00)
@@ -168,6 +163,8 @@ HalEndSystemInterrupt (old_level, 0); }
+/* PRIVATE FUNCTIONS *********************************************************/ + VOID NTAPI KiGetVectorDispatch(IN ULONG Vector, @@ -274,6 +271,8 @@ ((PKIPCR)KeGetPcr())->IDT[Interrupt->Vector].Offset = (USHORT)PtrToUlong(Handler); } + +/* PUBLIC FUNCTIONS **********************************************************/
/* * @implemented @@ -430,65 +429,84 @@
/* * @implemented - * - * FUNCTION: Releases a drivers isr - * ARGUMENTS: - * InterruptObject = isr to release */ -BOOLEAN +BOOLEAN STDCALL -KeDisconnectInterrupt(PKINTERRUPT InterruptObject) -{ -#if 0 - KIRQL oldlvl,synch_oldlvl; - PISR_TABLE CurrentIsr; +KeDisconnectInterrupt(PKINTERRUPT Interrupt) +{ + KIRQL OldIrql, Irql; + ULONG Vector; + DISPATCH_INFO Dispatch; + PKINTERRUPT NextInterrupt; BOOLEAN State;
- DPRINT1("KeDisconnectInterrupt\n"); - ASSERT (InterruptObject->Number < KeNumberProcessors); - /* Set the affinity */ - KeSetSystemAffinityThread(1 << InterruptObject->Number); - - /* Get the ISR Tabe */ - CurrentIsr = &IsrTable[InterruptObject->Vector - IRQ_BASE] - [(ULONG)InterruptObject->Number]; - - /* Raise IRQL to required level and lock table */ - KeRaiseIrql(VECTOR2IRQL(InterruptObject->Vector),&oldlvl); - KiAcquireSpinLock(&CurrentIsr->Lock); + KeSetSystemAffinityThread(1 << Interrupt->Number); + + /* Lock the dispatcher */ + OldIrql = KeAcquireDispatcherDatabaseLock();
/* Check if it's actually connected */ - if ((State = InterruptObject->Connected)) - { - /* Lock the Interrupt */ - synch_oldlvl = KeAcquireInterruptSpinLock(InterruptObject); - - /* Remove this one, and check if all are gone */ - RemoveEntryList(&InterruptObject->InterruptListEntry); - if (IsListEmpty(&CurrentIsr->ListHead)) - { - /* Completely Disable the Interrupt */ - HalDisableSystemInterrupt(InterruptObject->Vector, InterruptObject->Irql); - } - + State = Interrupt->Connected; + if (State) + { + /* Get the vector and IRQL */ + Irql = Interrupt->Irql; + Vector = Interrupt->Vector; + + /* Get vector dispatch data */ + KiGetVectorDispatch(Vector, &Dispatch); + + /* Check if it was chained */ + if (Dispatch.Type == ChainConnect) + { + /* Check if the top-level interrupt is being removed */ + ASSERT(Irql <= SYNCH_LEVEL); + if (Interrupt == Dispatch.Interrupt) + { + /* Get the next one */ + Dispatch.Interrupt = CONTAINING_RECORD(Dispatch.Interrupt-> + InterruptListEntry.Flink, + KINTERRUPT, + InterruptListEntry); + + /* Reconnect it */ + KiConnectVectorToInterrupt(Dispatch.Interrupt, ChainConnect); + } + + /* Remove it */ + RemoveEntryList(&Interrupt->InterruptListEntry); + + /* Get the next one */ + NextInterrupt = CONTAINING_RECORD(Dispatch.Interrupt-> + InterruptListEntry.Flink, + KINTERRUPT, + InterruptListEntry); + + /* Check if this is the only one left */ + if (Dispatch.Interrupt == NextInterrupt) + { + /* Connect it in non-chained mode */ + KiConnectVectorToInterrupt(Dispatch.Interrupt, NormalConnect); + } + } + else + { + /* Only one left, disable and remove it */ + HalDisableSystemInterrupt(Interrupt->Vector, Irql); + KiConnectVectorToInterrupt(Interrupt, NoConnect); + } + /* Disconnect it */ - InterruptObject->Connected = FALSE; - - /* Release the interrupt lock */ - KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl); - } - /* Release the table spinlock */ - KiReleaseSpinLock(&CurrentIsr->Lock); - KeLowerIrql(oldlvl); - - /* Go back to default affinity */ + Interrupt->Connected = FALSE; + } + + /* Unlock the dispatcher and revert affinity */ + KeReleaseDispatcherDatabaseLock(OldIrql); KeRevertToUserAffinityThread(); - - /* Return Old Interrupt State */ + + /* Return to caller */ return State; -#endif - return 0; }
/* EOF */
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?rev... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/trap.s (original) +++ trunk/reactos/ntoskrnl/ke/i386/trap.s Thu Aug 24 09:36:50 2006 @@ -81,6 +81,9 @@ _KiUnexpectedEntrySize: .long _KiUnexpectedInterrupt1 - _KiUnexpectedInterrupt0
+_UnexpectedMsg: + .asciz "\n\x7\x7!!! Unexpected Interrupt %02lx !!!\n" + /* SOFTWARE INTERRUPT SERVICES ***********************************************/
_KiGetTickCount: @@ -1348,76 +1351,13 @@ 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 - -/* INTERRUPT HANDLERS ********************************************************/ - -.func KiInterruptTemplate -_KiInterruptTemplate: - - /* Enter interrupt trap */ - INT_PROLOG kit, DoPushFakeErrorCode -.endfunc - -_KiInterruptTemplate2ndDispatch: - /* Dummy code, will be replaced by the address of the KINTERRUPT */ - mov edi, 0 - -_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 + /* Unexpected interrupt, print a message on debug builds */ +#if DBG + push [esp+4] + push offset _UnexpectedMsg + call _DbgPrint + add esp, 8 +#endif
/* Exit the interrupt */ mov esi, $ @@ -1426,6 +1366,77 @@ jmp _Kei386EoiHelper@0 .endfunc
+.globl _KiUnexpectedInterrupt +_KiUnexpectedInterrupt: + + /* Bugcheck with invalid interrupt code */ + push 0x12 + call _KeBugCheck@4 + +/* INTERRUPT HANDLERS ********************************************************/ + +.func KiInterruptTemplate +_KiInterruptTemplate: + + /* Enter interrupt trap */ + INT_PROLOG kit, DoPushFakeErrorCode +.endfunc + +_KiInterruptTemplate2ndDispatch: + /* Dummy code, will be replaced by the address of the KINTERRUPT */ + mov edi, 0 + +_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: