[HAL]: Implement the profile and clock interrupt trap/handlers in C instead of ASM. This allows the kernel to remove the ugly hacks based on internal knowledge of how the assembly/stack of the HAL is supposed to look like. Everything is now done through a clean C interface.

[NTOS]: Remove said hacks and have a normal C implementation of KeUpdateSystemTime. It exits the interrupt through a soft interrupt exit.
[NTOS]: Implement 4 lines of support code needed to handle interrupts during V8086 mode, which were lacking since we weren't hitting this case yet.
Note that now the KeUpdateSystemTime interface is not "compatible" with Windows anymore. This does not matter, since the only possible caller of KeUpdateSystemTime is a very specific HAL routine that needs a very specific stack layout to actually work, so the chance of anyone calling this API is absolutely zero (no, not even some experimental driver. It's absolutely impossible).

svn path=/trunk/; revision=45276
This commit is contained in:
Sir Richard 2010-01-26 21:41:05 +00:00
parent 92df9a6434
commit 49ca1be9f3
8 changed files with 83 additions and 139 deletions

View file

@ -520,72 +520,3 @@ InvalidCount:
mov _HalpLastPerfCounterHigh, eax
jmp LoopPreInt
.endfunc
.globl _HalpClockInterrupt@0
.func HalpClockInterrupt@0
TRAP_FIXUPS hci_a, hci_t, DoFixupV86, DoFixupAbios
_HalpClockInterrupt@0:
/* Enter trap */
INT_PROLOG hci_a, hci_t, 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
/* Update the performance counter */
xor ebx, ebx
mov eax, _HalpCurrentRollOver
add _HalpPerfCounterLow, eax
adc _HalpPerfCounterHigh, ebx
/* Get the time increment and check if someone changed the clock rate */
mov eax, _HalpCurrentTimeIncrement
cmp _HalpClockSetMSRate, ebx
jz _KeUpdateSystemTime@0
/* FIXME: Someone did! */
int 3
Spurious:
/* Exit the interrupt */
add esp, 8
jmp _Kei386EoiHelper@0
.endfunc
.globl _HalpProfileInterrupt@0
.func HalpProfileInterrupt@0
TRAP_FIXUPS hpi_a, hpi_t, DoFixupV86, DoFixupAbios
_HalpProfileInterrupt@0:
/* Enter trap */
INT_PROLOG hpi_a, hpi_t, DoPushFakeErrorCode
/* Push vector and make stack for IRQL */
push 0x38
sub esp, 4
/* Begin the interrupt */
push esp
push 0x38
push PROFILE_LEVEL
call _HalBeginSystemInterrupt@12
/* Check if it's spurious */
or al, al
jz Spurious
/* FIXME: We should not be getting profile interrupts yet! */
int 3
.endfunc

View file

@ -109,6 +109,61 @@ HalpInitializeClock(VOID)
HalpCurrentRollOver = RollOver;
}
VOID
FASTCALL
HalpClockInterruptHandler(IN PKTRAP_FRAME TrapFrame)
{
KIRQL Irql;
/* Enter trap */
KiEnterInterruptTrap(TrapFrame);
/* Start the interrupt */
if (HalBeginSystemInterrupt(CLOCK2_LEVEL, PRIMARY_VECTOR_BASE, &Irql))
{
/* Update the performance counter */
HalpPerfCounter.QuadPart += HalpCurrentRollOver;
/* Check if someone changed the time rate */
if (HalpClockSetMSRate)
{
/* Not yet supported */
UNIMPLEMENTED;
while (TRUE);
}
/* Update the system time -- the kernel will exit this trap */
KeUpdateSystemTime(TrapFrame, HalpCurrentTimeIncrement, Irql);
}
/* Spurious, just end the interrupt */
KiEoiHelper(TrapFrame);
}
VOID
FASTCALL
HalpProfileInterruptHandler(IN PKTRAP_FRAME TrapFrame)
{
KIRQL Irql;
/* Enter trap */
KiEnterInterruptTrap(TrapFrame);
/* Start the interrupt */
if (HalBeginSystemInterrupt(PROFILE_LEVEL, PRIMARY_VECTOR_BASE + 8, &Irql))
{
/* Profiling isn't yet enabled */
UNIMPLEMENTED;
while (TRUE);
}
/* Spurious, just end the interrupt */
KiEoiHelper(TrapFrame);
}
KiTrap(HalpClockInterrupt, KI_PUSH_FAKE_ERROR_CODE);
KiTrap(HalpProfileInterrupt, KI_PUSH_FAKE_ERROR_CODE);
/* PUBLIC FUNCTIONS ***********************************************************/
/*

View file

@ -532,8 +532,10 @@ VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts);
VOID HalpApcInterrupt(VOID);
VOID HalpDispatchInterrupt(VOID);
/* udelay.c */
/* timer.c */
VOID NTAPI HalpInitializeClock(VOID);
VOID HalpClockInterrupt(VOID);
VOID HalpProfileInterrupt(VOID);
VOID
NTAPI
@ -548,8 +550,6 @@ VOID HalpInitDma (VOID);
/* Non-generic initialization */
VOID HalpInitPhase0 (PLOADER_PARAMETER_BLOCK LoaderBlock);
VOID HalpInitPhase1(VOID);
VOID NTAPI HalpClockInterrupt(VOID);
VOID NTAPI HalpProfileInterrupt(VOID);
VOID
NTAPI
@ -755,6 +755,14 @@ KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
#endif
VOID
FASTCALL
KeUpdateSystemTime(
IN PKTRAP_FRAME TrapFrame,
IN ULONG Increment,
IN KIRQL OldIrql
);
#ifdef _M_AMD64
#define KfLowerIrql KeLowerIrql
#ifndef CONFIG_SMP
@ -774,4 +782,6 @@ extern KSPIN_LOCK HalpSystemHardwareLock;
extern PADDRESS_USAGE HalpAddressUsageList;
extern LARGE_INTEGER HalpPerfCounter;
#endif /* __INTERNAL_HAL_HAL_H */

View file

@ -235,21 +235,6 @@ KeFlushEntireTb(
IN BOOLEAN AllProcessors
);
VOID
NTAPI
KeUpdateSystemTime(
PKTRAP_FRAME TrapFrame,
KIRQL Irql,
ULONG Increment
);
VOID
NTAPI
KeUpdateRunTime(
PKTRAP_FRAME TrapFrame,
KIRQL Irql
);
VOID
NTAPI
KeSetDmaIoCoherency(

View file

@ -629,8 +629,11 @@ KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
/* Check for V86 mode */
if (__builtin_expect(TrapFrame->EFlags & EFLAGS_V86_MASK, 0))
{
DbgPrint("Need V8086 Interrupt Support!\n");
while (TRUE);
/* Restore V8086 segments into Protected Mode segments */
TrapFrame->SegFs = TrapFrame->V86Fs;
TrapFrame->SegGs = TrapFrame->V86Gs;
TrapFrame->SegDs = TrapFrame->V86Ds;
TrapFrame->SegEs = TrapFrame->V86Es;
}
/* Check if this wasn't kernel code */

View file

@ -205,41 +205,6 @@ _KiUnexpectedInterrupt:
/* INTERRUPT HANDLERS ********************************************************/
.globl _KeUpdateSystemTime@0
.func KeUpdateSystemTime@0
_KeUpdateSystemTime@0:
/*
* When we enter here, the ASM HAL has:
* - Entered here with a JMP, not a CALL
* - Put increment in EAX
* - Pushed OldIRQL on the stack earlier [ESP]
* - Pushed Vector on the stack earlier [ESP + 4]
* - The trap frame at ESP + 8
*
* When the HAL moves to C, this shit needs to die!!!
*
*/
/* Call the regparm with Increment, OldIrql, TrapFrame */
mov edx, [esp]
mov ecx, ebp
call _KeUpdateSystemTimeHandler
/*
* The code below cannot be done in C because HalEndSystemInterrupt will
* fuck with your stack sideways when it decides to handle a pending APC or
* DPC!
*/
/* Stack is back where it was, HalEndSystemInterrupt will clean it up */
cli
call _HalEndSystemInterrupt@8
/* Now the stack has become the trap frame */
jmp _Kei386EoiHelper@0
.endfunc
.func KiDispatchInterrupt@0
_KiDispatchInterrupt@0:

View file

@ -19,19 +19,11 @@ ULONG KeTimeAdjustment;
/* FUNCTIONS ******************************************************************/
#ifndef _M_ARM
VOID
__attribute__((regparm(3)))
KeUpdateSystemTimeHandler(IN ULONG Increment,
IN KIRQL Irql,
IN PKTRAP_FRAME TrapFrame)
#else
VOID
NTAPI
FASTCALL
KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
IN ULONG Increment,
IN KIRQL Irql)
#endif
{
PKPRCB Prcb = KeGetCurrentPrcb();
ULARGE_INTEGER CurrentTime, InterruptTime;
@ -119,6 +111,13 @@ KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
/* Increase interrupt count and exit */
Prcb->InterruptCount++;
}
/* Disable interrupts and end the interrupt */
_disable();
HalEndSystemInterrupt(Irql, CLOCK2_LEVEL);
/* Exit the interrupt */
KiEoiHelper(TrapFrame);
}
VOID

View file

@ -688,11 +688,7 @@
@ fastcall KeTryToAcquireSpinLockAtDpcLevel(ptr)
@ stdcall KeUnstackDetachProcess(ptr)
@ stdcall KeUpdateRunTime(ptr long)
#ifdef _M_IX86
@ stdcall KeUpdateSystemTime()
#else
@ stdcall KeUpdateSystemTime(ptr long long)
#endif
@ fastcall KeUpdateSystemTime(ptr long long)
@ stdcall KeUserModeCallback(long ptr long ptr ptr)
@ stdcall KeWaitForMultipleObjects(long ptr long long long long ptr ptr)
@ stdcall KeWaitForMutexObject(ptr long long long ptr) KeWaitForSingleObject