Author: sir_richard
Date: Fri Jan 29 09:14:51 2010
New Revision: 45316
URL: http://svn.reactos.org/svn/reactos?rev=45316&view=rev
Log:
[HAL]: Mark ECX as clobbered in HalpNestedTrap, otherwise if the compiler decides to store IRQL in ECX, it will then be overriden with our ECX parameter. With this clobber, the compiler will use another register, such as EAX, to hold the IRQL.
Modified:
trunk/reactos/hal/halx86/include/halp.h
Modified: trunk/reactos/hal/halx86/include/halp.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/include/halp.h?…
==============================================================================
--- trunk/reactos/hal/halx86/include/halp.h [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/include/halp.h [iso-8859-1] Fri Jan 29 09:14:51 2010
@@ -128,7 +128,7 @@
:
: "im"(SWInterruptHandlerTable2[PendingIrql]),
[t] "i"(&PCR->VdmAlert)
- : "%esp"
+ : "%esp","%ecx"
);
UNREACHABLE;
}
@@ -560,6 +560,7 @@
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts);
VOID HalpApcInterrupt(VOID);
VOID HalpDispatchInterrupt(VOID);
+VOID HalpDispatchInterrupt2(VOID);
VOID FASTCALL HalpApcInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame);
VOID FASTCALL HalpDispatchInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame);
Author: sir_richard
Date: Fri Jan 29 03:25:30 2010
New Revision: 45312
URL: http://svn.reactos.org/svn/reactos?rev=45312&view=rev
Log:
[NTOS]: Another try at the chained interrupt dispatch problem...
Modified:
trunk/reactos/ntoskrnl/ke/i386/irqobj.c
Modified: trunk/reactos/ntoskrnl/ke/i386/irqobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/irqobj.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/irqobj.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/irqobj.c [iso-8859-1] Fri Jan 29 03:25:30 2010
@@ -274,27 +274,24 @@
KfLowerIrql(OldIrql);
}
- /* Check if the interrupt got handled */
- if (Handled)
+ /* Check if the interrupt got handled and it's level */
+ if ((Handled) && (Interrupt->Mode == LevelSensitive)) break;
+
+ /* What's next? */
+ NextEntry = NextEntry->Flink;
+
+ /* Is this the last one? */
+ if (NextEntry == ListHead)
{
- /* Edge shared interrupts are not handled (they never were) */
- ASSERT(Interrupt->Mode == LevelSensitive);
- break;
+ /* Level should not have gotten here */
+ if (Interrupt->Mode == LevelSensitive) break;
+
+ /* As for edge, we can only exit once nobody can handle the interrupt */
+ if (!Handled) break;
}
- else
- {
- /* This code path was never tested, and shouldn't be reached */
- DPRINT1("Edge shared interrupt. ReactOS cannot handle these\n");
-
- /* What's next? */
- NextEntry = NextEntry->Flink;
-
- /* Is this the last one? */
- if (NextEntry == ListHead) break;
-
- /* Get the actual interrupt object */
- Interrupt = CONTAINING_RECORD(NextEntry, KINTERRUPT, InterruptListEntry);
- }
+
+ /* Get the interrupt object for the next pass */
+ Interrupt = CONTAINING_RECORD(NextEntry, KINTERRUPT, InterruptListEntry);
}
/* Now call the epilogue code */
@@ -431,6 +428,7 @@
if (!Interrupt->Connected)
{
/* Get vector dispatching information */
+ DPRINT1("Interrupt Connect: %lx %lx %d %d\n", Vector, Irql, Interrupt->ShareVector, Interrupt->Mode);
KiGetVectorDispatch(Vector, &Dispatch);
/* Check if the vector is already connected */
@@ -469,6 +467,7 @@
}
/* Insert into the interrupt list */
+ DPRINT1("Inserting shared interrupt %p into %p with mode: %lx\n", Interrupt, &Dispatch.Interrupt, Interrupt->Mode);
InsertTailList(&Dispatch.Interrupt->InterruptListEntry,
&Interrupt->InterruptListEntry);
}
@@ -487,6 +486,7 @@
}
/* Return to caller */
+ DPRINT1("Interrupt was registered: %lx\n", Connected);
return Connected;
}
Author: sir_richard
Date: Fri Jan 29 02:37:25 2010
New Revision: 45310
URL: http://svn.reactos.org/svn/reactos?rev=45310&view=rev
Log:
[NTOS]: Implement chained interrupt dispatch. For level interrupts, the first interrupt handler should process the interrupt and no other handlers are called. Edge interrupts are another matter, but since they aren't yet supported, I haven't implemented that code path (it wasn't implemented previously). I seriously hope we don't have edge/chained interrupts because the HAL/NTOS could never handle this!
Modified:
trunk/reactos/ntoskrnl/ke/i386/irqobj.c
Modified: trunk/reactos/ntoskrnl/ke/i386/irqobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/irqobj.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/irqobj.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/irqobj.c [iso-8859-1] Fri Jan 29 02:37:25 2010
@@ -233,11 +233,79 @@
KiChainedDispatch(IN PKTRAP_FRAME TrapFrame,
IN PKINTERRUPT Interrupt)
{
+ KIRQL OldIrql;
+ BOOLEAN Handled;
+ PLIST_ENTRY NextEntry, ListHead;
+
/* Increase interrupt count */
KeGetCurrentPrcb()->InterruptCount++;
- UNIMPLEMENTED;
- while (TRUE);
-}
+
+ /* Begin the interrupt, making sure it's not spurious */
+ if (HalBeginSystemInterrupt(Interrupt->Irql,
+ Interrupt->Vector,
+ &OldIrql))
+ {
+ /* Get list pointers */
+ ListHead = &Interrupt->InterruptListEntry;
+ NextEntry = ListHead; /* The head is an entry! */
+ while (TRUE)
+ {
+ /* Check if this interrupt's IRQL is higher than the current one */
+ if (Interrupt->SynchronizeIrql > Interrupt->Irql)
+ {
+ /* Raise to higher IRQL */
+ OldIrql = KfRaiseIrql(Interrupt->Irql);
+ }
+
+ /* Acquire interrupt lock */
+ KxAcquireSpinLock(Interrupt->ActualLock);
+
+ /* Call the ISR */
+ Handled = Interrupt->ServiceRoutine(Interrupt,
+ Interrupt->ServiceContext);
+
+ /* Release interrupt lock */
+ KxReleaseSpinLock(Interrupt->ActualLock);
+
+ /* Check if this interrupt's IRQL is higher than the current one */
+ if (Interrupt->SynchronizeIrql > Interrupt->Irql)
+ {
+ /* Lower the IRQL back */
+ KfLowerIrql(OldIrql);
+ }
+
+ /* Check if the interrupt got handled */
+ if (Handled)
+ {
+ /* Edge shared interrupts are not handled (they never were) */
+ ASSERT(Interrupt->Mode == LevelSensitive);
+ break;
+ }
+ else
+ {
+ /* This code path was never tested, and shouldn't be reached */
+ DPRINT1("Edge shared interrupt. ReactOS cannot handle these\n");
+
+ /* What's next? */
+ NextEntry = NextEntry->Flink;
+
+ /* Is this the last one? */
+ if (NextEntry == ListHead) break;
+
+ /* Get the actual interrupt object */
+ Interrupt = CONTAINING_RECORD(NextEntry, KINTERRUPT, InterruptListEntry);
+ }
+ }
+
+ /* Now call the epilogue code */
+ KiExitInterrupt(TrapFrame, OldIrql, FALSE);
+ }
+ else
+ {
+ /* Now call the epilogue code */
+ KiExitInterrupt(TrapFrame, OldIrql, TRUE);
+ }
+ }
VOID
FASTCALL