]> xenbits.xensource.com Git - people/pauldu/xenbus.git/commitdiff
Add per-cpu information to the set gathered by the system
authorPaul Durrant <paul.durrant@citrix.com>
Tue, 29 Oct 2013 13:01:15 +0000 (14:01 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Tue, 29 Oct 2013 13:01:15 +0000 (14:01 +0100)
module.
We should really add calls to make this information more
available.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
src/xen/hypercall.c
src/xen/system.c

index a35b461420e52e61832552c657da8a6966eee15c..799d8912634cbb572c26063f2fa8f9ef0afdb37e 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <ntddk.h>
 #include <xen.h>
+#include <util.h>
 
 #include "hypercall.h"
 #include "dbg_print.h"
@@ -55,32 +56,6 @@ typedef HYPERCALL_GATE  *PHYPERCALL_GATE;
 
 PHYPERCALL_GATE     Hypercall;
 
-static FORCEINLINE VOID
-__CpuId(
-    IN  ULONG   Leaf,
-    OUT PULONG  EAX OPTIONAL,
-    OUT PULONG  EBX OPTIONAL,
-    OUT PULONG  ECX OPTIONAL,
-    OUT PULONG  EDX OPTIONAL
-    )
-{
-    ULONG       Value[4] = {0};
-
-    __cpuid(Value, Leaf);
-
-    if (EAX)
-        *EAX = Value[0];
-
-    if (EBX)
-        *EBX = Value[1];
-
-    if (ECX)
-        *ECX = Value[2];
-
-    if (EDX)
-        *EDX = Value[3];
-}
-
 NTSTATUS
 HypercallInitialize(
     VOID
index ed14bed4463a5043b5b0e20b5dd5737f33c9a430..d3cae469571aa7ec0faef340a2244c278f01c499 100644 (file)
 #include "dbg_print.h"
 #include "assert.h"
 
+typedef struct _SYSTEM_CPU {
+    CHAR    Manufacturer[13];
+    UCHAR   ApicID;
+} SYSTEM_CPU, *PSYSTEM_CPU;
+
+static SYSTEM_CPU   SystemCpu[MAXIMUM_PROCESSORS];
+
 static FORCEINLINE const CHAR *
 __PlatformIdName(
     IN  ULONG   PlatformId
@@ -192,6 +199,97 @@ __SystemGetMemoryInformation(
     }
 }
 
+KDEFERRED_ROUTINE   SystemCpuInformation;
+
+VOID
+SystemCpuInformation(
+    IN  PKDPC   Dpc,
+    IN  PVOID   Context,
+    IN  PVOID   Argument1,
+    IN  PVOID   Argument2
+    )
+{
+    PKSPIN_LOCK     Lock = Argument1;
+    PKEVENT         Event = Argument2;
+    ULONG           Index;
+    PSYSTEM_CPU     Cpu;
+    ULONG           EBX;
+    ULONG           ECX;
+    ULONG           EDX;
+
+    UNREFERENCED_PARAMETER(Dpc);
+    UNREFERENCED_PARAMETER(Context);
+    UNREFERENCED_PARAMETER(Argument2);
+
+    ASSERT(Lock != NULL);
+    ASSERT(Event != NULL);
+
+    KeAcquireSpinLockAtDpcLevel(Lock);
+
+    Index = KeGetCurrentProcessorNumber();
+
+    Info("====> (%u)\n", Index);
+
+    Cpu = &SystemCpu[Index];
+
+    __CpuId(0, NULL, &EBX, &ECX, &EDX);
+
+    RtlCopyMemory(&Cpu->Manufacturer[0], &EBX, sizeof (ULONG));
+    RtlCopyMemory(&Cpu->Manufacturer[4], &EDX, sizeof (ULONG));
+    RtlCopyMemory(&Cpu->Manufacturer[8], &ECX, sizeof (ULONG));
+
+    Info("Manufacturer: %s\n", Cpu->Manufacturer);
+
+    __CpuId(1, NULL, &EBX, NULL, NULL);
+
+    Cpu->ApicID = EBX >> 24;
+
+    Info("Local APIC ID: %02X\n", Cpu->ApicID);
+
+    Info("<==== (%u)\n", Index);
+
+    KeReleaseSpinLockFromDpcLevel(Lock);
+    KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+}
+
+static FORCEINLINE VOID
+__SystemGetCpuInformation(
+    VOID
+    )
+{
+    KSPIN_LOCK      Lock;
+    KDPC            Dpc[MAXIMUM_PROCESSORS];
+    KEVENT          Event[MAXIMUM_PROCESSORS];
+    PKEVENT         Object[MAXIMUM_PROCESSORS];
+    LONG            Index;
+
+    Info("====>\n");
+
+    KeInitializeSpinLock(&Lock);
+
+    for (Index = 0; Index < KeNumberProcessors; Index++) {
+        KeInitializeDpc(&Dpc[Index], SystemCpuInformation, NULL);
+        KeSetTargetProcessorDpc(&Dpc[Index], (CCHAR)Index);
+        KeSetImportanceDpc(&Dpc[Index], HighImportance);
+
+        KeInitializeEvent(&Event[Index], NotificationEvent, FALSE);
+        Object[Index] = &Event[Index];
+
+        KeInsertQueueDpc(&Dpc[Index], &Lock, &Event[Index]);
+    }
+
+    (VOID) KeWaitForMultipleObjects(KeNumberProcessors,
+                                    Object,
+                                    WaitAll,
+                                    Executive,
+                                    KernelMode,
+                                    FALSE,
+                                    NULL,
+                                    NULL);
+
+    Info("<====\n");
+}
+
 extern VOID
 SystemGetInformation(
     VOID
@@ -199,4 +297,5 @@ SystemGetInformation(
 {
     __SystemGetVersionInformation();
     __SystemGetMemoryInformation();
+    __SystemGetCpuInformation();
 }