Commit in reactos/ntoskrnl on MAIN
ke/ipi.c+162-81.2 -> 1.3
include/internal/ke.h+4-51.64 -> 1.65
+166-13
2 modified files
- Started the implementation of the ipi calls.

reactos/ntoskrnl/ke
ipi.c 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- ipi.c	15 Aug 2004 16:39:05 -0000	1.2
+++ ipi.c	14 Nov 2004 20:00:06 -0000	1.3
@@ -1,10 +1,11 @@
-/* $Id: ipi.c,v 1.2 2004/08/15 16:39:05 chorns Exp $
+/* $Id: ipi.c,v 1.3 2004/11/14 20:00:06 hbirr Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/ipi.c
  * PURPOSE:         IPI Routines (Inter-Processor Interrupts). NT5+
  * PROGRAMMER:      Alex Ionescu (alex@relsoft.net)
+ *                  Hartmut Birr    
  * UPDATE HISTORY:
  *                  Created 11/08/2004
  */
@@ -15,20 +16,173 @@
 #define NDEBUG
 #include <internal/debug.h>
 
+/* GLOBALS *******************************************************************/
+
+KSPIN_LOCK KiIpiLock;
+
+struct
+{
+   VOID STDCALL (*Function)(PVOID);
+   PVOID Argument;
+   BOOLEAN Synchronize;
+   ULONG StartCount;
+   ULONG EndCount;
+} KiIpiInfo;
+
 /* FUNCTIONS *****************************************************************/
 
 /*
  * @unimplemented
  */
-STDCALL
 BOOLEAN
-KiIpiServiceRoutine(
-	IN PKTRAP_FRAME   		TrapFrame,
-	IN PKEXCEPTION_FRAME  	ExceptionFrame
-)
+STDCALL
+KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame,
+                    IN PKEXCEPTION_FRAME ExceptionFrame)
+{
+    LARGE_INTEGER StartTime, CurrentTime, Frequency;
+
+    ASSERT(KeGetCurrentIrql() == IPI_LEVEL);
+
+    DPRINT("KiIpiServiceRoutine\n");
+
+
+    if (KiIpiInfo.Synchronize)
+    {
+       InterlockedDecrement(&KiIpiInfo.StartCount);
+       StartTime = KeQueryPerformanceCounter(&Frequency);
+       while (0 != InterlockedCompareExchange(&KiIpiInfo.StartCount, 0, 0))
+       {
+          CurrentTime = KeQueryPerformanceCounter(NULL);
+	  if (CurrentTime.QuadPart > StartTime.QuadPart + Frequency.QuadPart)
+	  {
+	     DPRINT1("Waiting longer than 1 seconds to start the ipi routine\n");
+	     KEBUGCHECK(0);
+	  }
+       }
+    }
+    KiIpiInfo.Function(KiIpiInfo.Argument);
+    if (KiIpiInfo.Synchronize)
+    {
+       InterlockedDecrement(&KiIpiInfo.EndCount);
+       StartTime = KeQueryPerformanceCounter(&Frequency);
+       while (0 != InterlockedCompareExchange(&KiIpiInfo.EndCount, 0, 0))
+       {
+          CurrentTime = KeQueryPerformanceCounter(NULL);
+	  if (CurrentTime.QuadPart > StartTime.QuadPart + Frequency.QuadPart)
+	  {
+	     DPRINT1("Waiting longer than 1 seconds after executing the ipi routine\n");
+	     KEBUGCHECK(0);
+	  }
+       }
+    }
+    return TRUE;
+}
+
+VOID
+STDCALL
+KiIpiSendPacket(ULONG Processors, VOID STDCALL (*Function)(PVOID), PVOID Argument, ULONG Count, BOOLEAN Synchronize)
+{
+    ULONG i;
+
+    ASSERT(KeGetCurrentIrql() == SYNCH_LEVEL);
+
+    /* 
+     * FIXME
+     *   M$ puts the ipi information anywhere into the KPCR of the requestor.
+     *   The KPCR of the target contains a pointer of the KPCR of the requestor.
+     */
+
+    KiIpiInfo.Function = Function;
+    KiIpiInfo.Argument = Argument;
+    if (Synchronize)
+    {
+       KiIpiInfo.StartCount = Count;
+       KiIpiInfo.EndCount = Count;
+    }
+    KiIpiInfo.Synchronize = Synchronize;
+
+    for (i = 0; i < KeNumberProcessors; i++)
+    {
+       if (Processors & (1 << i))
+       {
+	  HalRequestIpi(i);
+       }
+    }
+}
+
+VOID
+STDCALL
+KeIpiGenericCall(VOID STDCALL (*Function)(PVOID), PVOID Argument)
+{
+   KIRQL oldIrql, oldIrql2;
+   ULONG Count, i;
+   ULONG Processors = 0;
+
+   DPRINT("KeIpiGenericCall on CPU%d\n", KeGetCurrentProcessorNumber());
+
+   KeRaiseIrql(SYNCH_LEVEL, &oldIrql);
+
+   Count = KeNumberProcessors;
+   for (i = 0; i < KeNumberProcessors; i++)
+   {
+      if (KeGetCurrentProcessorNumber() != i)
+      {
+         Processors |= (1 << i);
+      }
+   }
+
+   KiAcquireSpinLock(&KiIpiLock);
+
+   KiIpiSendPacket(Processors, Function, Argument, Count, TRUE);
+   
+   KeRaiseIrql(IPI_LEVEL, &oldIrql2);
+   
+   KiIpiServiceRoutine(NULL, NULL);
+   
+   KeLowerIrql(oldIrql2);
+
+   KiReleaseSpinLock(&KiIpiLock);
+   
+   KeLowerIrql(oldIrql);
+   
+   DPRINT("KeIpiGenericCall on CPU%d done\n", KeGetCurrentProcessorNumber());
+}
+
+VOID
+STDCALL
+KeIpiCallForBootProcessor(VOID STDCALL (*Function)(PVOID), PVOID Argument)
 {
-	UNIMPLEMENTED;
-	return FALSE;
+   KIRQL oldIrql, oldIrql2;
+   LARGE_INTEGER StartCount, CurrentCount;
+   LARGE_INTEGER Frequency;
+
+   KeRaiseIrql(SYNCH_LEVEL, &oldIrql);
+
+   ASSERT (KeGetCurrentProcessorNumber() != 0);
+
+   KiAcquireSpinLock(&KiIpiLock);
+
+   KiIpiSendPacket(1, Function, Argument, 1, TRUE);
+   
+   KeRaiseIrql(IPI_LEVEL, &oldIrql2);
+
+   StartCount = KeQueryPerformanceCounter(&Frequency);
+   while (0 != InterlockedCompareExchange(&KiIpiInfo.EndCount, 0, 0))
+   {
+      CurrentCount = KeQueryPerformanceCounter(NULL);
+      if (CurrentCount.QuadPart > StartCount.QuadPart + Frequency.QuadPart)
+      {
+         DPRINT1("Waiting longer than 1 second after sending the ipi to the boot processor\n");
+	 KEBUGCHECK(0);
+      }
+   }
+
+   KeLowerIrql(oldIrql2);
+
+   KiReleaseSpinLock(&KiIpiLock);
+   
+   KeLowerIrql(oldIrql);
+
 }
 
 /* EOF */

reactos/ntoskrnl/include/internal
ke.h 1.64 -> 1.65
diff -u -r1.64 -r1.65
--- ke.h	11 Nov 2004 22:23:52 -0000	1.64
+++ ke.h	14 Nov 2004 20:00:06 -0000	1.65
@@ -41,6 +41,7 @@
 struct _KTHREAD;
 struct _KIRQ_TRAPFRAME;
 struct _KPCR;
+struct _KEXCEPTION_FRAME;
 
 VOID STDCALL 
 DbgBreakPointNoBugCheck(VOID);
@@ -58,12 +59,10 @@
 	IN KPROFILE_SOURCE		Source
 );
 
-/*BOOLEAN
+BOOLEAN
 STDCALL
-KiIpiServiceRoutine(
-	IN PKTRAP_FRAME   		TrapFrame,
-	IN PKEXCEPTION_FRAME  	ExceptionFrame
-);*/
+KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame,
+	            IN struct _KEXCEPTION_FRAME* ExceptionFrame);
 
 VOID STDCALL KeUpdateSystemTime(PKTRAP_FRAME TrapFrame, KIRQL Irql);
 VOID STDCALL KeUpdateRunTime(PKTRAP_FRAME TrapFrame, KIRQL Irql);
CVSspam 0.2.8