- 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.

svn path=/trunk/; revision=23678
This commit is contained in:
Alex Ionescu 2006-08-24 05:36:50 +00:00
parent 15899302f6
commit 8b82c0d641
6 changed files with 121 additions and 66 deletions

View file

@ -19,6 +19,7 @@
PVOID HalpZeroPageMapping = NULL;
HALP_HOOKS HalpHooks;
VOID NTAPI HalpClockInterrupt(VOID);
/* FUNCTIONS ***************************************************************/
@ -31,6 +32,10 @@ DriverEntry(
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 @@ HalInitSystem (ULONG BootPhase,
}
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();

View file

@ -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

View file

@ -15,8 +15,6 @@
#define NDEBUG
#include <debug.h>
VOID NTAPI HalpClockInterrupt(VOID);
/* FUNCTIONS ***************************************************************/
VOID
@ -24,15 +22,6 @@ HalpInitPhase0(PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
{
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();
}

View file

@ -37,7 +37,7 @@ LARGE_INTEGER SystemBootTime = { 0 };
CHAR KiTimerSystemAuditing = 0;
static KDPC KiExpireTimerDpc;
static BOOLEAN KiClockSetupComplete = FALSE;
BOOLEAN KiClockSetupComplete = FALSE;
extern ULONG KiMaximumDpcQueueDepth;
extern ULONG KiMinimumDpcRate;

View file

@ -65,15 +65,10 @@ VOID
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 @@ KiInterruptDispatch (ULONG vector, PKIRQ_TRAPFRAME Trapframe)
HalEndSystemInterrupt (old_level, 0);
}
/* PRIVATE FUNCTIONS *********************************************************/
VOID
NTAPI
KiGetVectorDispatch(IN ULONG Vector,
@ -275,6 +272,8 @@ KiConnectVectorToInterrupt(IN PKINTERRUPT Interrupt,
(USHORT)PtrToUlong(Handler);
}
/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
*/
@ -430,65 +429,84 @@ KeConnectInterrupt(IN PKINTERRUPT Interrupt)
/*
* @implemented
*
* FUNCTION: Releases a drivers isr
* ARGUMENTS:
* InterruptObject = isr to release
*/
BOOLEAN
BOOLEAN
STDCALL
KeDisconnectInterrupt(PKINTERRUPT InterruptObject)
KeDisconnectInterrupt(PKINTERRUPT Interrupt)
{
#if 0
KIRQL oldlvl,synch_oldlvl;
PISR_TABLE CurrentIsr;
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);
KeSetSystemAffinityThread(1 << Interrupt->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);
/* Lock the dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Check if it's actually connected */
if ((State = InterruptObject->Connected))
State = Interrupt->Connected;
if (State)
{
/* Lock the Interrupt */
synch_oldlvl = KeAcquireInterruptSpinLock(InterruptObject);
/* Get the vector and IRQL */
Irql = Interrupt->Irql;
Vector = Interrupt->Vector;
/* Remove this one, and check if all are gone */
RemoveEntryList(&InterruptObject->InterruptListEntry);
if (IsListEmpty(&CurrentIsr->ListHead))
/* Get vector dispatch data */
KiGetVectorDispatch(Vector, &Dispatch);
/* Check if it was chained */
if (Dispatch.Type == ChainConnect)
{
/* Completely Disable the Interrupt */
HalDisableSystemInterrupt(InterruptObject->Vector, InterruptObject->Irql);
}
/* Disconnect it */
InterruptObject->Connected = FALSE;
/* Release the interrupt lock */
KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl);
}
/* Release the table spinlock */
KiReleaseSpinLock(&CurrentIsr->Lock);
KeLowerIrql(oldlvl);
/* 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);
/* Go back to default affinity */
/* 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 */
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 */

View file

@ -81,6 +81,9 @@ _KiIdtDescriptor:
_KiUnexpectedEntrySize:
.long _KiUnexpectedInterrupt1 - _KiUnexpectedInterrupt0
_UnexpectedMsg:
.asciz "\n\x7\x7!!! Unexpected Interrupt %02lx !!!\n"
/* SOFTWARE INTERRUPT SERVICES ***********************************************/
_KiGetTickCount:
@ -1348,7 +1351,15 @@ _KiUnexpectedInterruptTail:
jmp _Kei386EoiHelper2ndEntry
Handled:
/* Unexpected, exit the interrupt */
/* 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, $
cli
call _HalEndSystemInterrupt@8