//////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: Processor.cs // // Note: // namespace Microsoft.Singularity { using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Threading; using Microsoft.Singularity.X86; using Microsoft.Singularity.V1.Services; [CLSCompliant(false)] [NoCCtor] public class Processor { public static long CyclesPerSecond { [NoHeapAllocation] get { return ProcessService.GetCyclesPerSecond(); } } public static ulong CycleCount { [NoHeapAllocation] get { return GetCycleCount(); } } //////////////////////////////////////////////////// External Methods. // [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [StackBound(32)] [NoHeapAllocation] public static extern ulong GetCycleCount(); [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [StackBound(32)] [NoHeapAllocation] internal static unsafe extern UIntPtr GetFrameEip(UIntPtr ebp); [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [StackBound(32)] [NoHeapAllocation] internal static unsafe extern UIntPtr GetFrameEbp(UIntPtr ebp); [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [GCAnnotation(GCOption.NOGC)] [StackBound(32)] [NoHeapAllocation] internal static extern UIntPtr GetStackPointer(); [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [GCAnnotation(GCOption.NOGC)] [StackBound(32)] [NoHeapAllocation] internal static extern UIntPtr GetFramePointer(); [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [GCAnnotation(GCOption.NOGC)] [StackBound(32)] [NoHeapAllocation] internal static unsafe extern ThreadContext * GetCurrentThreadContext(); [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [GCAnnotation(GCOption.NOGC)] [StackBound(32)] [NoHeapAllocation] internal static unsafe extern ProcessorContext * GetCurrentProcessorContext(); [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [GCAnnotation(GCOption.NOGC)] [StackBound(32)] [NoHeapAllocation] internal static extern Thread GetCurrentThread(); ////////////////////////////////////////////////////////////////////////////// // [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [GCAnnotation(GCOption.NOGC)] [StackBound(16)] [NoHeapAllocation] public static extern void WriteMsr(uint offset, ulong value); [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [GCAnnotation(GCOption.NOGC)] [StackBound(16)] [NoHeapAllocation] public static extern ulong ReadMsr(uint offset); [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [GCAnnotation(GCOption.NOGC)] [StackBound(64)] [NoHeapAllocation] public static extern void ReadCpuid(uint feature, out uint v0, out uint v1, out uint v2, out uint v3); [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [GCAnnotation(GCOption.NOGC)] [StackBound(16)] [NoHeapAllocation] public static extern ulong ReadPmc(uint offset); [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [GCAnnotation(GCOption.NOGC)] [StackBound(32)] [NoHeapAllocation] internal static extern void EnterRing3(); [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [GCAnnotation(GCOption.NOGC)] [StackBound(32)] [NoHeapAllocation] public static extern bool AtKernelPrivilege(); ////////////////////////////////////////////////////////////////////// // // // These methods are currently marked external because they are used // by device drivers. We need a tool to verify that device drivers // are in fact using them correctly! // [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [GCAnnotation(GCOption.NOGC)] [StackBound(16)] [NoHeapAllocation] public static extern bool DisableInterrupts(); [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [GCAnnotation(GCOption.NOGC)] [StackBound(16)] [NoHeapAllocation] public static extern void RestoreInterrupts(bool enabled); // Use this method for assertions only! [AccessedByRuntime("output to header : defined in Processor.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [GCAnnotation(GCOption.NOGC)] [StackBound(16)] [NoHeapAllocation] public static extern bool InterruptsDisabled(); ////////////////////////////////////////////////////////////////////// // // // These methods are public and safe to use from any where provided // there's at least 2 call frame on the stack. // [NoHeapAllocation] public static UIntPtr GetCallerEip() { UIntPtr currentFrame = GetFramePointer(); UIntPtr callerFrame = GetFrameEbp(currentFrame); if (callerFrame == UIntPtr.Zero) { return UIntPtr.Zero; } UIntPtr callersCaller = GetFrameEip(callerFrame); return callersCaller; } /// /// Provides a mini stack trace starting from the caller of the caller /// of this method. /// [NoHeapAllocation] public static void GetStackEips(out UIntPtr pc1, out UIntPtr pc2, out UIntPtr pc3) { pc1 = UIntPtr.Zero; pc2 = UIntPtr.Zero; pc3 = UIntPtr.Zero; UIntPtr currentFrame = GetFramePointer(); UIntPtr callerFrame = GetFrameEbp(currentFrame); if (callerFrame == UIntPtr.Zero) { return; } pc1 = GetFrameEip(callerFrame); callerFrame = GetFrameEbp(callerFrame); if (callerFrame == UIntPtr.Zero) { return; } pc2 = GetFrameEip(callerFrame); callerFrame = GetFrameEbp(callerFrame); if (callerFrame == UIntPtr.Zero) { return; } pc3 = GetFrameEip(callerFrame); } /// /// Provides the full stack trace starting from the caller of the caller /// of this method. /// /// Eip values in stack array from top to bottom [NoHeapAllocation] public static void GetStackEips(UIntPtr[] stack) { if (stack == null) { return; } UIntPtr currentFrame = GetFramePointer(); UIntPtr callerFrame = GetFrameEbp(currentFrame); for (int index = 0; callerFrame != UIntPtr.Zero && index < stack.Length; index++) { stack[index] = GetFrameEip(callerFrame); callerFrame = GetFrameEbp(callerFrame); } } } }