You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
3.7 KiB
208 lines
3.7 KiB
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
flush.c
|
|
|
|
Abstract:
|
|
|
|
This module implements i386 machine dependent kernel functions to flush
|
|
the data and instruction caches and to stall processor execution.
|
|
|
|
Author:
|
|
|
|
David N. Cutler (davec) 26-Apr-1990
|
|
|
|
Environment:
|
|
|
|
Kernel mode only.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "ki.h"
|
|
|
|
//
|
|
// Prototypes
|
|
//
|
|
|
|
VOID
|
|
KiInvalidateAllCachesTarget (
|
|
IN PKIPI_CONTEXT SignalDone,
|
|
IN PVOID Parameter1,
|
|
IN PVOID Parameter2,
|
|
IN PVOID Parameter3
|
|
);
|
|
|
|
extern ULONG KeI386CpuType;
|
|
|
|
BOOLEAN
|
|
KeInvalidateAllCaches (
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function writes back and invalidates the cache on all processors
|
|
in the host configuration.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
TRUE if the invalidation was done, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
#ifndef NT_UP
|
|
|
|
KIRQL OldIrql;
|
|
PKPRCB Prcb;
|
|
KAFFINITY TargetProcessors;
|
|
|
|
#endif
|
|
|
|
//
|
|
// Support for wbinvd on Pentium based platforms is vendor dependent.
|
|
// Check for family first and support on Pentium Pro based platforms
|
|
// onward.
|
|
//
|
|
|
|
if (KeI386CpuType < 6 ) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Raise IRQL and compute target set of processors.
|
|
//
|
|
|
|
|
|
#ifndef NT_UP
|
|
|
|
//
|
|
// Synchronize with other IPI functions which may stall
|
|
//
|
|
|
|
OldIrql = KeRaiseIrqlToSynchLevel();
|
|
KeAcquireSpinLockAtDpcLevel (&KiReverseStallIpiLock);
|
|
|
|
Prcb = KeGetCurrentPrcb();
|
|
TargetProcessors = KeActiveProcessors & ~Prcb->SetMember;
|
|
|
|
//
|
|
// If any target processors are specified, then send writeback
|
|
// invalidate packet to the target set of processors.
|
|
//
|
|
|
|
if (TargetProcessors != 0) {
|
|
KiIpiSendSynchronousPacket(Prcb,
|
|
TargetProcessors,
|
|
KiInvalidateAllCachesTarget,
|
|
(PVOID)&Prcb->ReverseStall,
|
|
NULL,
|
|
NULL);
|
|
|
|
KiIpiStallOnPacketTargets(TargetProcessors);
|
|
}
|
|
|
|
#endif
|
|
|
|
//
|
|
// All target processors have written back and invalidated caches and
|
|
// are waiting to proceed. Write back invalidate current cache and
|
|
// then continue the execution of target processors.
|
|
//
|
|
|
|
_asm {
|
|
;
|
|
; wbinvd
|
|
;
|
|
|
|
_emit 0Fh
|
|
_emit 09h
|
|
}
|
|
|
|
//
|
|
// Wait until all target processors have finished and completed packet.
|
|
//
|
|
|
|
#ifndef NT_UP
|
|
|
|
if (TargetProcessors != 0) {
|
|
Prcb->ReverseStall += 1;
|
|
}
|
|
|
|
//
|
|
// Drop reverse IPI lock and Lower IRQL to its previous value.
|
|
//
|
|
|
|
KeReleaseSpinLockFromDpcLevel (&KiReverseStallIpiLock);
|
|
|
|
KeLowerIrql(OldIrql);
|
|
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#if !defined(NT_UP)
|
|
|
|
VOID
|
|
KiInvalidateAllCachesTarget (
|
|
IN PKIPI_CONTEXT SignalDone,
|
|
IN PVOID Proceed,
|
|
IN PVOID Parameter2,
|
|
IN PVOID Parameter3
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is the target function for writing back and invalidating the cache.
|
|
|
|
Arguments:
|
|
|
|
SignalDone - Supplies a pointer to a variable that is cleared when the
|
|
requested operation has been performed.
|
|
|
|
Proceed - pointer to flag to syncronize with
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER (Parameter2);
|
|
UNREFERENCED_PARAMETER (Parameter3);
|
|
|
|
//
|
|
// Write back invalidate current cache
|
|
//
|
|
|
|
_asm {
|
|
;
|
|
; wbinvd
|
|
;
|
|
|
|
_emit 0Fh
|
|
_emit 09h
|
|
|
|
}
|
|
|
|
KiIpiSignalPacketDoneAndStall (SignalDone, Proceed);
|
|
}
|
|
|
|
#endif
|