Exemplo n.º 1
0
        private void InitializeMemoryManager(AddressSpaceType addrSpaceType, MemoryRegion memRegion)
        {
            int addrSpaceBits;

            switch (addrSpaceType)
            {
            case AddressSpaceType.Addr32Bits:      addrSpaceBits = 32; break;

            case AddressSpaceType.Addr36Bits:      addrSpaceBits = 36; break;

            case AddressSpaceType.Addr32BitsNoMap: addrSpaceBits = 32; break;

            case AddressSpaceType.Addr39Bits:      addrSpaceBits = 39; break;

            default: throw new ArgumentException(nameof(addrSpaceType));
            }

            bool useFlatPageTable = memRegion == MemoryRegion.Application;

            CpuMemory = new MemoryManager(_system.Device.Memory.RamPointer, addrSpaceBits, useFlatPageTable);

            MemoryManager = new KMemoryManager(_system, CpuMemory);

            Translator = new Translator(CpuMemory);

            Translator.CpuTrace += CpuTraceHandler;
        }
Exemplo n.º 2
0
        private void InitializeMemoryManager(AddressSpaceType addrSpaceType, MemoryRegion memRegion)
        {
            int addrSpaceBits;

            switch (addrSpaceType)
            {
            case AddressSpaceType.Addr32Bits:      addrSpaceBits = 32; break;

            case AddressSpaceType.Addr36Bits:      addrSpaceBits = 36; break;

            case AddressSpaceType.Addr32BitsNoMap: addrSpaceBits = 32; break;

            case AddressSpaceType.Addr39Bits:      addrSpaceBits = 39; break;

            default: throw new ArgumentException(nameof(addrSpaceType));
            }

            bool useFlatPageTable = memRegion == MemoryRegion.Application;

            if (_system.UseLegacyJit)
            {
                CpuMemory = new ChocolArm64.Memory.MemoryManager(_system.Device.Memory.RamPointer, addrSpaceBits, useFlatPageTable);

                Translator = new ChocolArm64.Translation.Translator((ChocolArm64.Memory.MemoryManager)CpuMemory);
            }
            else
            {
                CpuMemory = new MemoryManager(_system.Device.Memory.RamPointer, addrSpaceBits, useFlatPageTable);

                Translator = new Translator((MemoryManager)CpuMemory);
            }

            MemoryManager = new KMemoryManager(_system, CpuMemory);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Creates a set of instructions to realize a generic lea operation.
        /// </summary>
        /// <param name="sourceType">The source address type (pointer or view).</param>
        /// <param name="elementIndex">The current element index (the offset).</param>
        /// <param name="targetAddressRegister">The allocated target pointer register to write to.</param>
        /// <param name="address">The source address.</param>
        private void MakeLoadElementAddress(
            AddressSpaceType sourceType,
            PrimitiveRegister elementIndex,
            PrimitiveRegister targetAddressRegister,
            PrimitiveRegister address)
        {
            var elementSize    = ABI.GetSizeOf(sourceType.ElementType);
            var offsetRegister = AllocatePlatformRegister(out RegisterDescription _);

            using (var command = BeginCommand(
                       PTXInstructions.GetLEAMulOperation(ABI.PointerArithmeticType)))
            {
                command.AppendArgument(offsetRegister);
                command.AppendArgument(elementIndex);
                command.AppendConstant(elementSize);
            }

            using (var command = BeginCommand(
                       PTXInstructions.GetArithmeticOperation(
                           BinaryArithmeticKind.Add,
                           ABI.PointerArithmeticType,
                           false)))
            {
                command.AppendArgument(targetAddressRegister);
                command.AppendArgument(address);
                command.AppendArgument(offsetRegister);
            }

            FreeRegister(offsetRegister);
        }
Exemplo n.º 4
0
 /// <summary>
 /// Constructs a new cast value.
 /// </summary>
 /// <param name="basicBlock">The parent basic block.</param>
 /// <param name="value">The value to convert.</param>
 /// <param name="targetType">The target type to convert the value to.</param>
 internal BaseAddressSpaceCast(
     BasicBlock basicBlock,
     ValueReference value,
     AddressSpaceType targetType)
     : base(basicBlock, value, targetType)
 {
 }
Exemplo n.º 5
0
        private void InitializeMemoryManager(AddressSpaceType addrSpaceType, MemoryRegion memRegion)
        {
            int addrSpaceBits;

            switch (addrSpaceType)
            {
            case AddressSpaceType.Addr32Bits:      addrSpaceBits = 32; break;

            case AddressSpaceType.Addr36Bits:      addrSpaceBits = 36; break;

            case AddressSpaceType.Addr32BitsNoMap: addrSpaceBits = 32; break;

            case AddressSpaceType.Addr39Bits:      addrSpaceBits = 39; break;

            default: throw new ArgumentException(nameof(addrSpaceType));
            }

            bool useFlatPageTable = memRegion == MemoryRegion.Application;

            CpuMemory = new MemoryManager(_system.Device.Memory.RamPointer, addrSpaceBits, useFlatPageTable);

            Translator = new Translator(CpuMemory);

            // TODO: This should eventually be removed.
            // The GPU shouldn't depend on the CPU memory manager at all.
            _system.Device.Gpu.SetVmm(CpuMemory);

            MemoryManager = new KMemoryManager(_system, CpuMemory);
        }
Exemplo n.º 6
0
        private void InitializeMemoryManager(AddressSpaceType addrSpaceType, MemoryRegion memRegion)
        {
            int addrSpaceBits = addrSpaceType switch
            {
                AddressSpaceType.Addr32Bits => 32,
                AddressSpaceType.Addr36Bits => 36,
                AddressSpaceType.Addr32BitsNoMap => 32,
                AddressSpaceType.Addr39Bits => 39,
                _ => throw new ArgumentException(nameof(addrSpaceType))
            };

            CpuMemory  = new MemoryManager(KernelContext.Memory, 1UL << addrSpaceBits, InvalidAccessHandler);
            CpuContext = new CpuContext(CpuMemory);

            // TODO: This should eventually be removed.
            // The GPU shouldn't depend on the CPU memory manager at all.
            KernelContext.Device.Gpu.SetVmm(CpuMemory);

            MemoryManager = new KMemoryManager(KernelContext, CpuMemory);
        }
Exemplo n.º 7
0
 /// <summary>
 /// Specializes the address space of the given <see cref="AddressSpaceType"/>.
 /// </summary>
 /// <param name="addressSpaceType">The source type.</param>
 /// <param name="addressSpace">The new address space.</param>
 /// <returns>The created specialzized <see cref="AddressSpaceType"/>.</returns>
 public AddressSpaceType SpecializeAddressSpaceType(
     AddressSpaceType addressSpaceType,
     MemoryAddressSpace addressSpace) =>
 TypeContext.SpecializeAddressSpaceType(addressSpaceType, addressSpace);
Exemplo n.º 8
0
        public KernelResult Initialize(
            ProcessCreationInfo creationInfo,
            int[]               caps,
            KResourceLimit resourceLimit,
            MemoryRegion memRegion)
        {
            ResourceLimit = resourceLimit;
            _memRegion    = memRegion;

            ulong personalMmHeapSize = GetPersonalMmHeapSize((ulong)creationInfo.PersonalMmHeapPagesCount, memRegion);

            ulong codePagesCount = (ulong)creationInfo.CodePagesCount;

            ulong neededSizeForProcess = personalMmHeapSize + codePagesCount * KMemoryManager.PageSize;

            if (neededSizeForProcess != 0 && resourceLimit != null)
            {
                if (!resourceLimit.Reserve(LimitableResource.Memory, neededSizeForProcess))
                {
                    return(KernelResult.ResLimitExceeded);
                }
            }

            void CleanUpForError()
            {
                if (neededSizeForProcess != 0 && resourceLimit != null)
                {
                    resourceLimit.Release(LimitableResource.Memory, neededSizeForProcess);
                }
            }

            PersonalMmHeapPagesCount = (ulong)creationInfo.PersonalMmHeapPagesCount;

            KMemoryBlockAllocator memoryBlockAllocator;

            if (PersonalMmHeapPagesCount != 0)
            {
                memoryBlockAllocator = new KMemoryBlockAllocator(PersonalMmHeapPagesCount * KMemoryManager.PageSize);
            }
            else
            {
                memoryBlockAllocator = (MmuFlags & 0x40) != 0
                    ? System.LargeMemoryBlockAllocator
                    : System.SmallMemoryBlockAllocator;
            }

            AddressSpaceType addrSpaceType = (AddressSpaceType)((creationInfo.MmuFlags >> 1) & 7);

            InitializeMemoryManager(addrSpaceType, memRegion);

            bool aslrEnabled = ((creationInfo.MmuFlags >> 5) & 1) != 0;

            ulong codeAddress = creationInfo.CodeAddress;

            ulong codeSize = codePagesCount * KMemoryManager.PageSize;

            KernelResult result = MemoryManager.InitializeForProcess(
                addrSpaceType,
                aslrEnabled,
                !aslrEnabled,
                memRegion,
                codeAddress,
                codeSize,
                memoryBlockAllocator);

            if (result != KernelResult.Success)
            {
                CleanUpForError();

                return(result);
            }

            if (!ValidateCodeAddressAndSize(codeAddress, codeSize))
            {
                CleanUpForError();

                return(KernelResult.InvalidMemRange);
            }

            result = MemoryManager.MapNewProcessCode(
                codeAddress,
                codePagesCount,
                MemoryState.CodeStatic,
                MemoryPermission.None);

            if (result != KernelResult.Success)
            {
                CleanUpForError();

                return(result);
            }

            result = Capabilities.InitializeForUser(caps, MemoryManager);

            if (result != KernelResult.Success)
            {
                CleanUpForError();

                return(result);
            }

            Pid = System.GetProcessId();

            if (Pid == -1 || (ulong)Pid < Horizon.InitialProcessId)
            {
                throw new InvalidOperationException($"Invalid Process Id {Pid}.");
            }

            result = ParseProcessInfo(creationInfo);

            if (result != KernelResult.Success)
            {
                CleanUpForError();
            }

            return(result);
        }
Exemplo n.º 9
0
        public KernelResult InitializeKip(
            ProcessCreationInfo creationInfo,
            int[]               caps,
            KPageList pageList,
            KResourceLimit resourceLimit,
            MemoryRegion memRegion)
        {
            ResourceLimit = resourceLimit;
            _memRegion    = memRegion;

            AddressSpaceType addrSpaceType = (AddressSpaceType)((creationInfo.MmuFlags >> 1) & 7);

            InitializeMemoryManager(addrSpaceType, memRegion);

            bool aslrEnabled = ((creationInfo.MmuFlags >> 5) & 1) != 0;

            ulong codeAddress = creationInfo.CodeAddress;

            ulong codeSize = (ulong)creationInfo.CodePagesCount * KMemoryManager.PageSize;

            KMemoryBlockAllocator memoryBlockAllocator = (MmuFlags & 0x40) != 0
                ? System.LargeMemoryBlockAllocator
                : System.SmallMemoryBlockAllocator;

            KernelResult result = MemoryManager.InitializeForProcess(
                addrSpaceType,
                aslrEnabled,
                !aslrEnabled,
                memRegion,
                codeAddress,
                codeSize,
                memoryBlockAllocator);

            if (result != KernelResult.Success)
            {
                return(result);
            }

            if (!ValidateCodeAddressAndSize(codeAddress, codeSize))
            {
                return(KernelResult.InvalidMemRange);
            }

            result = MemoryManager.MapPages(
                codeAddress,
                pageList,
                MemoryState.CodeStatic,
                MemoryPermission.None);

            if (result != KernelResult.Success)
            {
                return(result);
            }

            result = Capabilities.InitializeForKernel(caps, MemoryManager);

            if (result != KernelResult.Success)
            {
                return(result);
            }

            Pid = System.GetKipId();

            if (Pid == 0 || (ulong)Pid >= Horizon.InitialProcessId)
            {
                throw new InvalidOperationException($"Invalid KIP Id {Pid}.");
            }

            result = ParseProcessInfo(creationInfo);

            return(result);
        }
Exemplo n.º 10
0
        public KernelResult Initialize(
            ProcessCreationInfo creationInfo,
            ReadOnlySpan <int> capabilities,
            KResourceLimit resourceLimit,
            MemoryRegion memRegion,
            IProcessContextFactory contextFactory,
            ThreadStart customThreadStart = null)
        {
            ResourceLimit      = resourceLimit;
            _memRegion         = memRegion;
            _contextFactory    = contextFactory ?? new ProcessContextFactory();
            _customThreadStart = customThreadStart;

            ulong personalMmHeapSize = GetPersonalMmHeapSize((ulong)creationInfo.SystemResourcePagesCount, memRegion);

            ulong codePagesCount = (ulong)creationInfo.CodePagesCount;

            ulong neededSizeForProcess = personalMmHeapSize + codePagesCount * KMemoryManager.PageSize;

            if (neededSizeForProcess != 0 && resourceLimit != null)
            {
                if (!resourceLimit.Reserve(LimitableResource.Memory, neededSizeForProcess))
                {
                    return(KernelResult.ResLimitExceeded);
                }
            }

            void CleanUpForError()
            {
                if (neededSizeForProcess != 0 && resourceLimit != null)
                {
                    resourceLimit.Release(LimitableResource.Memory, neededSizeForProcess);
                }
            }

            PersonalMmHeapPagesCount = (ulong)creationInfo.SystemResourcePagesCount;

            KMemoryBlockAllocator memoryBlockAllocator;

            if (PersonalMmHeapPagesCount != 0)
            {
                memoryBlockAllocator = new KMemoryBlockAllocator(PersonalMmHeapPagesCount * KMemoryManager.PageSize);
            }
            else
            {
                memoryBlockAllocator = creationInfo.Flags.HasFlag(ProcessCreationFlags.IsApplication)
                    ? KernelContext.LargeMemoryBlockAllocator
                    : KernelContext.SmallMemoryBlockAllocator;
            }

            AddressSpaceType addrSpaceType = (AddressSpaceType)((int)(creationInfo.Flags & ProcessCreationFlags.AddressSpaceMask) >> (int)ProcessCreationFlags.AddressSpaceShift);

            InitializeMemoryManager(creationInfo.Flags);

            bool aslrEnabled = creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr);

            ulong codeAddress = creationInfo.CodeAddress;

            ulong codeSize = codePagesCount * KMemoryManager.PageSize;

            KernelResult result = MemoryManager.InitializeForProcess(
                addrSpaceType,
                aslrEnabled,
                !aslrEnabled,
                memRegion,
                codeAddress,
                codeSize,
                memoryBlockAllocator);

            if (result != KernelResult.Success)
            {
                CleanUpForError();

                return(result);
            }

            if (!MemoryManager.CanContain(codeAddress, codeSize, MemoryState.CodeStatic))
            {
                CleanUpForError();

                return(KernelResult.InvalidMemRange);
            }

            result = MemoryManager.MapNewProcessCode(
                codeAddress,
                codePagesCount,
                MemoryState.CodeStatic,
                KMemoryPermission.None);

            if (result != KernelResult.Success)
            {
                CleanUpForError();

                return(result);
            }

            result = Capabilities.InitializeForUser(capabilities, MemoryManager);

            if (result != KernelResult.Success)
            {
                CleanUpForError();

                return(result);
            }

            Pid = KernelContext.NewProcessId();

            if (Pid == -1 || (ulong)Pid < KernelConstants.InitialProcessId)
            {
                throw new InvalidOperationException($"Invalid Process Id {Pid}.");
            }

            result = ParseProcessInfo(creationInfo);

            if (result != KernelResult.Success)
            {
                CleanUpForError();
            }

            return(result);
        }
Exemplo n.º 11
0
        public KernelResult InitializeKip(
            ProcessCreationInfo creationInfo,
            ReadOnlySpan <int> capabilities,
            KPageList pageList,
            KResourceLimit resourceLimit,
            MemoryRegion memRegion,
            IProcessContextFactory contextFactory,
            ThreadStart customThreadStart = null)
        {
            ResourceLimit      = resourceLimit;
            _memRegion         = memRegion;
            _contextFactory    = contextFactory ?? new ProcessContextFactory();
            _customThreadStart = customThreadStart;

            AddressSpaceType addrSpaceType = (AddressSpaceType)((int)(creationInfo.Flags & ProcessCreationFlags.AddressSpaceMask) >> (int)ProcessCreationFlags.AddressSpaceShift);

            InitializeMemoryManager(creationInfo.Flags);

            bool aslrEnabled = creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr);

            ulong codeAddress = creationInfo.CodeAddress;

            ulong codeSize = (ulong)creationInfo.CodePagesCount * KMemoryManager.PageSize;

            KMemoryBlockAllocator memoryBlockAllocator = creationInfo.Flags.HasFlag(ProcessCreationFlags.IsApplication)
                ? KernelContext.LargeMemoryBlockAllocator
                : KernelContext.SmallMemoryBlockAllocator;

            KernelResult result = MemoryManager.InitializeForProcess(
                addrSpaceType,
                aslrEnabled,
                !aslrEnabled,
                memRegion,
                codeAddress,
                codeSize,
                memoryBlockAllocator);

            if (result != KernelResult.Success)
            {
                return(result);
            }

            if (!MemoryManager.CanContain(codeAddress, codeSize, MemoryState.CodeStatic))
            {
                return(KernelResult.InvalidMemRange);
            }

            result = MemoryManager.MapPages(
                codeAddress,
                pageList,
                MemoryState.CodeStatic,
                KMemoryPermission.None);

            if (result != KernelResult.Success)
            {
                return(result);
            }

            result = Capabilities.InitializeForKernel(capabilities, MemoryManager);

            if (result != KernelResult.Success)
            {
                return(result);
            }

            Pid = KernelContext.NewKipId();

            if (Pid == 0 || (ulong)Pid >= KernelConstants.InitialProcessId)
            {
                throw new InvalidOperationException($"Invalid KIP Id {Pid}.");
            }

            return(ParseProcessInfo(creationInfo));
        }
Exemplo n.º 12
0
        public KMemoryManager(Process Process)
        {
            CpuMemory = Process.Memory;
            Allocator = Process.Device.Memory.Allocator;

            long CodeRegionSize;
            long MapRegionSize;
            long HeapRegionSize;
            long NewMapRegionSize;
            long TlsIoRegionSize;
            int  AddrSpaceWidth;

            AddressSpaceType AddrType = AddressSpaceType.Addr39Bits;

            if (Process.MetaData != null)
            {
                AddrType = (AddressSpaceType)Process.MetaData.AddressSpaceWidth;
            }

            switch (AddrType)
            {
            case AddressSpaceType.Addr32Bits:
                CodeRegionStart  = 0x200000;
                CodeRegionSize   = 0x3fe00000;
                MapRegionSize    = 0x40000000;
                HeapRegionSize   = 0x40000000;
                NewMapRegionSize = 0;
                TlsIoRegionSize  = 0;
                AddrSpaceWidth   = 32;
                break;

            case AddressSpaceType.Addr36Bits:
                CodeRegionStart  = 0x8000000;
                CodeRegionSize   = 0x78000000;
                MapRegionSize    = 0x180000000;
                HeapRegionSize   = 0x180000000;
                NewMapRegionSize = 0;
                TlsIoRegionSize  = 0;
                AddrSpaceWidth   = 36;
                break;

            case AddressSpaceType.Addr36BitsNoMap:
                CodeRegionStart  = 0x200000;
                CodeRegionSize   = 0x3fe00000;
                MapRegionSize    = 0;
                HeapRegionSize   = 0x80000000;
                NewMapRegionSize = 0;
                TlsIoRegionSize  = 0;
                AddrSpaceWidth   = 36;
                break;

            case AddressSpaceType.Addr39Bits:
                CodeRegionStart  = 0x8000000;
                CodeRegionSize   = 0x80000000;
                MapRegionSize    = 0x1000000000;
                HeapRegionSize   = 0x180000000;
                NewMapRegionSize = 0x80000000;
                TlsIoRegionSize  = 0x1000000000;
                AddrSpaceWidth   = 39;
                break;

            default: throw new InvalidOperationException();
            }

            AddrSpaceStart = 0;
            AddrSpaceEnd   = 1L << AddrSpaceWidth;

            CodeRegionEnd     = CodeRegionStart + CodeRegionSize;
            MapRegionStart    = CodeRegionEnd;
            MapRegionEnd      = CodeRegionEnd + MapRegionSize;
            HeapRegionStart   = MapRegionEnd;
            HeapRegionEnd     = MapRegionEnd + HeapRegionSize;
            NewMapRegionStart = HeapRegionEnd;
            NewMapRegionEnd   = HeapRegionEnd + NewMapRegionSize;
            TlsIoRegionStart  = NewMapRegionEnd;
            TlsIoRegionEnd    = NewMapRegionEnd + TlsIoRegionSize;

            CurrentHeapAddr = HeapRegionStart;

            if (NewMapRegionSize == 0)
            {
                NewMapRegionStart = AddrSpaceStart;
                NewMapRegionEnd   = AddrSpaceEnd;
            }

            Blocks = new LinkedList <KMemoryBlock>();

            long AddrSpacePagesCount = (AddrSpaceEnd - AddrSpaceStart) / PageSize;

            InsertBlock(AddrSpaceStart, AddrSpacePagesCount, MemoryState.Unmapped);
        }
Exemplo n.º 13
0
        public KernelResult Initialize(
            ProcessCreationInfo CreationInfo,
            int[]               Caps,
            KResourceLimit ResourceLimit,
            MemoryRegion MemRegion)
        {
            this.ResourceLimit = ResourceLimit;
            this.MemRegion     = MemRegion;

            ulong PersonalMmHeapSize = GetPersonalMmHeapSize((ulong)CreationInfo.PersonalMmHeapPagesCount, MemRegion);

            ulong CodePagesCount = (ulong)CreationInfo.CodePagesCount;

            ulong NeededSizeForProcess = PersonalMmHeapSize + CodePagesCount * KMemoryManager.PageSize;

            if (NeededSizeForProcess != 0 && ResourceLimit != null)
            {
                if (!ResourceLimit.Reserve(LimitableResource.Memory, NeededSizeForProcess))
                {
                    return(KernelResult.ResLimitExceeded);
                }
            }

            void CleanUpForError()
            {
                if (NeededSizeForProcess != 0 && ResourceLimit != null)
                {
                    ResourceLimit.Release(LimitableResource.Memory, NeededSizeForProcess);
                }
            }

            PersonalMmHeapPagesCount = (ulong)CreationInfo.PersonalMmHeapPagesCount;

            KMemoryBlockAllocator MemoryBlockAllocator;

            if (PersonalMmHeapPagesCount != 0)
            {
                MemoryBlockAllocator = new KMemoryBlockAllocator(PersonalMmHeapPagesCount * KMemoryManager.PageSize);
            }
            else
            {
                MemoryBlockAllocator = (MmuFlags & 0x40) != 0
                    ? System.LargeMemoryBlockAllocator
                    : System.SmallMemoryBlockAllocator;
            }

            AddressSpaceType AddrSpaceType = (AddressSpaceType)((CreationInfo.MmuFlags >> 1) & 7);

            bool AslrEnabled = ((CreationInfo.MmuFlags >> 5) & 1) != 0;

            ulong CodeAddress = CreationInfo.CodeAddress;

            ulong CodeSize = CodePagesCount * KMemoryManager.PageSize;

            KernelResult Result = MemoryManager.InitializeForProcess(
                AddrSpaceType,
                AslrEnabled,
                !AslrEnabled,
                MemRegion,
                CodeAddress,
                CodeSize,
                MemoryBlockAllocator);

            if (Result != KernelResult.Success)
            {
                CleanUpForError();

                return(Result);
            }

            if (!ValidateCodeAddressAndSize(CodeAddress, CodeSize))
            {
                CleanUpForError();

                return(KernelResult.InvalidMemRange);
            }

            Result = MemoryManager.MapNewProcessCode(
                CodeAddress,
                CodePagesCount,
                MemoryState.CodeStatic,
                MemoryPermission.None);

            if (Result != KernelResult.Success)
            {
                CleanUpForError();

                return(Result);
            }

            Result = Capabilities.InitializeForUser(Caps, MemoryManager);

            if (Result != KernelResult.Success)
            {
                CleanUpForError();

                return(Result);
            }

            Pid = System.GetProcessId();

            if (Pid == -1 || (ulong)Pid < Horizon.InitialProcessId)
            {
                throw new InvalidOperationException($"Invalid Process Id {Pid}.");
            }

            Result = ParseProcessInfo(CreationInfo);

            if (Result != KernelResult.Success)
            {
                CleanUpForError();
            }

            return(Result);
        }
Exemplo n.º 14
0
        public KernelResult InitializeKip(
            ProcessCreationInfo CreationInfo,
            int[]               Caps,
            KPageList PageList,
            KResourceLimit ResourceLimit,
            MemoryRegion MemRegion)
        {
            this.ResourceLimit = ResourceLimit;
            this.MemRegion     = MemRegion;

            AddressSpaceType AddrSpaceType = (AddressSpaceType)((CreationInfo.MmuFlags >> 1) & 7);

            bool AslrEnabled = ((CreationInfo.MmuFlags >> 5) & 1) != 0;

            ulong CodeAddress = CreationInfo.CodeAddress;

            ulong CodeSize = (ulong)CreationInfo.CodePagesCount * KMemoryManager.PageSize;

            KMemoryBlockAllocator MemoryBlockAllocator = (MmuFlags & 0x40) != 0
                ? System.LargeMemoryBlockAllocator
                : System.SmallMemoryBlockAllocator;

            KernelResult Result = MemoryManager.InitializeForProcess(
                AddrSpaceType,
                AslrEnabled,
                !AslrEnabled,
                MemRegion,
                CodeAddress,
                CodeSize,
                MemoryBlockAllocator);

            if (Result != KernelResult.Success)
            {
                return(Result);
            }

            if (!ValidateCodeAddressAndSize(CodeAddress, CodeSize))
            {
                return(KernelResult.InvalidMemRange);
            }

            Result = MemoryManager.MapPages(
                CodeAddress,
                PageList,
                MemoryState.CodeStatic,
                MemoryPermission.None);

            if (Result != KernelResult.Success)
            {
                return(Result);
            }

            Result = Capabilities.InitializeForKernel(Caps, MemoryManager);

            if (Result != KernelResult.Success)
            {
                return(Result);
            }

            Pid = System.GetKipId();

            if (Pid == 0 || (ulong)Pid >= Horizon.InitialProcessId)
            {
                throw new InvalidOperationException($"Invalid KIP Id {Pid}.");
            }

            Result = ParseProcessInfo(CreationInfo);

            return(Result);
        }