mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[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:
parent
92df9a6434
commit
49ca1be9f3
8 changed files with 83 additions and 139 deletions
|
@ -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
|
||||
|
|
|
@ -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 ***********************************************************/
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
IN KIRQL Irql)
|
||||
{
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue