From 380df53cc2f343da59bc2fbe382b8bb46a8a45a3 Mon Sep 17 00:00:00 2001 From: Stefan Ginsberg Date: Sat, 1 Nov 2008 12:01:58 +0000 Subject: [PATCH] - Implement most of SMP KeFlushEntireTb (currently unused though) - Update KiTbFlushTimeStamp on both UP and MP after flushing svn path=/trunk/; revision=37127 --- reactos/ntoskrnl/ke/i386/cpu.c | 53 +++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/reactos/ntoskrnl/ke/i386/cpu.c b/reactos/ntoskrnl/ke/i386/cpu.c index 819cec1cf25..e3e94e765a3 100644 --- a/reactos/ntoskrnl/ke/i386/cpu.c +++ b/reactos/ntoskrnl/ke/i386/cpu.c @@ -994,6 +994,20 @@ KeGetRecommendedSharedDataAlignment(VOID) return KeLargestCacheLine; } +VOID +NTAPI +KiFlushTargetEntireTb(IN PKIPI_CONTEXT PacketContext, + IN PVOID Ignored1, + IN PVOID Ignored2, + IN PVOID Ignored3) +{ + /* Signal this packet as done */ + KiIpiSignalPacketDone(PacketContext); + + /* Flush the TB for the Current CPU */ + KeFlushCurrentTb(); +} + /* * @implemented */ @@ -1003,19 +1017,50 @@ KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors) { KIRQL OldIrql; +#ifdef CONFIG_SMP + KAFFINITY TargetAffinity; + PKPRCB Prcb = KeGetCurrentPrcb(); +#endif /* Raise the IRQL for the TB Flush */ OldIrql = KeRaiseIrqlToSynchLevel(); #ifdef CONFIG_SMP - /* FIXME: Support IPI Flush */ -#error Not yet implemented! + /* FIXME: Use KiTbFlushTimeStamp to synchronize TB flush */ + + /* Get the current processor affinity, and exclude ourselves */ + TargetAffinity = KeActiveProcessors; + TargetAffinity &= ~KeGetCurrentPrcb()->SetMember; + + /* Make sure this is MP */ + if (TargetAffinity) + { + /* Send an IPI TB flush to the other processors */ + KiIpiSendPacket(TargetAffinity, + KiFlushTargetEntireTb, + NULL, + 0, + NULL); + } #endif - /* Flush the TB for the Current CPU */ + /* Flush the TB for the Current CPU, and update the flush stamp */ KeFlushCurrentTb(); - /* Return to Original IRQL */ +#ifdef CONFIG_SMP + /* If this is MP, wait for the other processors to finish */ + if (TargetAffinity) + { + /* Sanity check */ + ASSERT(Prcb == (volatile PKPRCB)KeGetCurrentPrcb()); + + /* FIXME: TODO */ + ASSERTMSG("Not yet implemented\n", FALSE); + } +#endif + + /* Update the flush stamp and return to original IRQL */ + InterlockedExchangeAdd(&KiTbFlushTimeStamp, 1); KeLowerIrql(OldIrql); }