/////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: MpBootInfo.cs // // Note: // This structure holds values needed to bring the application processors // into protected mode. // using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Microsoft.Singularity.Hal; using Microsoft.Singularity.Memory; namespace Microsoft.Singularity { [StructLayout(LayoutKind.Sequential, Pack=4)] [CLSCompliant(false)] [AccessedByRuntime("referenced in c++")] public struct MpBootInfo { #if SINGULARITY_MP [AccessedByRuntime("referenced in c++")] public const uint MAX_CPU = # if MAX_CPU4 4; # elif MAX_CPU3 3; # elif MAX_CPU2 2; # else 15; # endif // MAX_CPUX #else [AccessedByRuntime("referenced in c++")] public const uint MAX_CPU = 1; #endif // SINGULARITY_MP [AccessedByRuntime("referenced in c++")] public const uint Signature = 0x4d504249; // "MPBI" // Settings for next processor to enter protected mode [AccessedByRuntime("referenced in c++")] public uint signature; [AccessedByRuntime("referenced in c++")] public UIntPtr KernelStackBegin; [AccessedByRuntime("referenced in c++")] public UIntPtr KernelStack; [AccessedByRuntime("referenced in c++")] public UIntPtr KernelStackLimit; [AccessedByRuntime("referenced in c++")] public volatile int TargetCpu; [AccessedByRuntime("defined in MpBootInfo.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [StackBound(256)] internal static unsafe extern MpBootInfo * HalGetMpBootInfo(); [AccessedByRuntime("defined in MpBootInfo.cpp")] [MethodImpl(MethodImplOptions.InternalCall)] [StackBound(256)] internal static unsafe extern void HalReleaseMpStartupLock(); public unsafe void ReleaseMpStartupLock() { HalReleaseMpStartupLock(); } public unsafe bool PrepareForCpuStart(int targetCpu) { UIntPtr size = MemoryManager.PagePad( Platform.BootCpu.KernelStackBegin - Platform.BootCpu.KernelStackLimit); UIntPtr stack = MemoryManager.KernelAllocate( MemoryManager.PagesFromBytes(size), null, 0, System.GCs.PageType.Stack); if (stack == UIntPtr.Zero) { return false; } KernelStackLimit = stack; KernelStackBegin = stack + size; signature = Signature; TargetCpu = targetCpu; HalReleaseMpStartupLock(); return true; } } }