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/systime…
==============================================================================
--- 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=23…
==============================================================================
--- 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?re…
==============================================================================
--- 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: