private KernelResult SetMemoryAttribute( ulong position, ulong size, MemoryAttribute attributeMask, MemoryAttribute attributeValue) { if (!PageAligned(position)) { return(KernelResult.InvalidAddress); } if (!PageAligned(size) || size == 0) { return(KernelResult.InvalidSize); } MemoryAttribute attributes = attributeMask | attributeValue; if (attributes != attributeMask || (attributes | MemoryAttribute.Uncached) != MemoryAttribute.Uncached) { return(KernelResult.InvalidCombination); } KernelResult result = _process.MemoryManager.SetMemoryAttribute( position, size, attributeMask, attributeValue); return(result); }
public void SetState(KMemoryPermission permission, MemoryState state, MemoryAttribute attribute) { Permission = permission; State = state; Attribute &= MemoryAttribute.IpcAndDeviceMapped; Attribute |= attribute; }
public long SetMemoryAttribute( long Position, long Size, MemoryAttribute AttributeMask, MemoryAttribute AttributeValue) { lock (Blocks) { if (CheckRange( Position, Size, MemoryState.AttributeChangeAllowed, MemoryState.AttributeChangeAllowed, MemoryPermission.None, MemoryPermission.None, MemoryAttribute.BorrowedAndIpcMapped, MemoryAttribute.None, MemoryAttribute.DeviceMappedAndUncached, out MemoryState State, out MemoryPermission Permission, out MemoryAttribute Attribute)) { long PagesCount = Size / PageSize; Attribute &= ~AttributeMask; Attribute |= AttributeMask & AttributeValue; InsertBlock(Position, PagesCount, State, Permission, Attribute); return(0); } } return(MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm)); }
public KernelResult SetMemoryAttribute64( ulong position, ulong size, MemoryAttribute attributeMask, MemoryAttribute attributeValue) { return(SetMemoryAttribute(position, size, attributeMask, attributeValue)); }
public KernelResult SetMemoryAttribute32( [R(0)] uint address, [R(1)] uint size, [R(2)] MemoryAttribute attributeMask, [R(3)] MemoryAttribute attributeValue) { return(_syscall.SetMemoryAttribute(address, size, attributeMask, attributeValue)); }
public KernelResult SetMemoryAttribute64( [R(0)] ulong position, [R(1)] ulong size, [R(2)] MemoryAttribute attributeMask, [R(3)] MemoryAttribute attributeValue) { return(_syscall.SetMemoryAttribute(position, size, attributeMask, attributeValue)); }
public KernelResult SetMemoryAttribute32( [R(0)] uint position, [R(1)] uint size, [R(2)] MemoryAttribute attributeMask, [R(3)] MemoryAttribute attributeValue) { return(SetMemoryAttribute(position, size, attributeMask, attributeValue)); }
private void SvcSetMemoryAttribute(CpuThreadState ThreadState) { long Position = (long)ThreadState.X0; long Size = (long)ThreadState.X1; if (!PageAligned(Position)) { Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress); return; } if (!PageAligned(Size) || Size == 0) { Logger.PrintWarning(LogClass.KernelSvc, $"Size 0x{Size:x16} is not page aligned or is zero!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidSize); return; } MemoryAttribute AttributeMask = (MemoryAttribute)ThreadState.X2; MemoryAttribute AttributeValue = (MemoryAttribute)ThreadState.X3; MemoryAttribute Attributes = AttributeMask | AttributeValue; if (Attributes != AttributeMask || (Attributes | MemoryAttribute.Uncached) != MemoryAttribute.Uncached) { Logger.PrintWarning(LogClass.KernelSvc, "Invalid memory attributes!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMaskValue); return; } long Result = Process.MemoryManager.SetMemoryAttribute( Position, Size, AttributeMask, AttributeValue); if (Result != 0) { Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{Result:x}!"); } else { Memory.StopObservingRegion(Position, Size); } ThreadState.X0 = (ulong)Result; }
private void SvcSetMemoryAttribute(CpuThreadState threadState) { ulong position = threadState.X0; ulong size = threadState.X1; if (!PageAligned(position)) { Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{position:x16} is not page aligned!"); threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress); return; } if (!PageAligned(size) || size == 0) { Logger.PrintWarning(LogClass.KernelSvc, $"Size 0x{size:x16} is not page aligned or is zero!"); threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidSize); return; } MemoryAttribute attributeMask = (MemoryAttribute)threadState.X2; MemoryAttribute attributeValue = (MemoryAttribute)threadState.X3; MemoryAttribute attributes = attributeMask | attributeValue; if (attributes != attributeMask || (attributes | MemoryAttribute.Uncached) != MemoryAttribute.Uncached) { Logger.PrintWarning(LogClass.KernelSvc, "Invalid memory attributes!"); threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMaskValue); return; } KernelResult result = _process.MemoryManager.SetMemoryAttribute( position, size, attributeMask, attributeValue); if (result != KernelResult.Success) { Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error \"{result}\"."); } else { _memory.StopObservingRegion((long)position, (long)size); } threadState.X0 = (ulong)result; }
public void InsertBlock( ulong baseAddress, ulong pagesCount, MemoryState state, KMemoryPermission permission = KMemoryPermission.None, MemoryAttribute attribute = MemoryAttribute.None) { // Inserts new block at the list, replacing and splitting // existing blocks as needed. int oldCount = _blocks.Count; ulong endAddr = baseAddress + pagesCount * PageSize; LinkedListNode <KMemoryBlock> node = _blocks.First; while (node != null) { LinkedListNode <KMemoryBlock> newNode = node; KMemoryBlock currBlock = node.Value; ulong currBaseAddr = currBlock.BaseAddress; ulong currEndAddr = currBlock.PagesCount * PageSize + currBaseAddr; if (baseAddress < currEndAddr && currBaseAddr < endAddr) { if (baseAddress > currBaseAddr) { _blocks.AddBefore(node, currBlock.SplitRightAtAddress(baseAddress)); } if (endAddr < currEndAddr) { newNode = _blocks.AddBefore(node, currBlock.SplitRightAtAddress(endAddr)); } newNode.Value.SetState(permission, state, attribute); newNode = MergeEqualStateNeighbors(newNode); } if (currEndAddr - 1 >= endAddr - 1) { break; } node = newNode.Next; } _slabManager.Count += _blocks.Count - oldCount; ValidateInternalState(); }
public void InsertBlock( ulong baseAddress, ulong pagesCount, MemoryState state, KMemoryPermission permission = KMemoryPermission.None, MemoryAttribute attribute = MemoryAttribute.None) { // Inserts new block at the list, replacing and splitting // existing blocks as needed. int oldCount = _blockTree.Count; ulong endAddr = baseAddress + pagesCount * PageSize; KMemoryBlock currBlock = FindBlock(baseAddress); while (currBlock != null) { ulong currBaseAddr = currBlock.BaseAddress; ulong currEndAddr = currBlock.PagesCount * PageSize + currBaseAddr; if (baseAddress < currEndAddr && currBaseAddr < endAddr) { if (baseAddress > currBaseAddr) { KMemoryBlock newBlock = currBlock.SplitRightAtAddress(baseAddress); _blockTree.Add(newBlock); } if (endAddr < currEndAddr) { KMemoryBlock newBlock = currBlock.SplitRightAtAddress(endAddr); _blockTree.Add(newBlock); currBlock = newBlock; } currBlock.SetState(permission, state, attribute); currBlock = MergeEqualStateNeighbors(currBlock); } if (currEndAddr - 1 >= endAddr - 1) { break; } currBlock = currBlock.Successor; } _slabManager.Count += _blockTree.Count - oldCount; ValidateInternalState(); }
public void Write(int Address, int Value, MemoryAttribute Attr = MemoryAttribute.DATA) { if (Address >= RegisterBaseAddr && Address <= RegisterBaseAddr + 15) { Register[Address - RegisterBaseAddr] = Value; } else { Address += offset; Memory.Write(Address, Value, Attr); } }
public KMemoryBlock( long BasePosition, long PagesCount, MemoryState State, MemoryPermission Permission, MemoryAttribute Attribute) { this.BasePosition = BasePosition; this.PagesCount = PagesCount; this.State = State; this.Attribute = Attribute; this.Permission = Permission; }
public KMemoryBlock( ulong BaseAddress, ulong PagesCount, MemoryState State, MemoryPermission Permission, MemoryAttribute Attribute) { this.BaseAddress = BaseAddress; this.PagesCount = PagesCount; this.State = State; this.Attribute = Attribute; this.Permission = Permission; }
public KMemoryBlock( ulong baseAddress, ulong pagesCount, MemoryState state, MemoryPermission permission, MemoryAttribute attribute) { BaseAddress = baseAddress; PagesCount = pagesCount; State = state; Attribute = attribute; Permission = permission; }
public KMemoryInfo( ulong address, ulong size, MemoryState state, MemoryPermission permission, MemoryAttribute attribute, int ipcRefCount, int deviceRefCount) { Address = address; Size = size; State = state; Attribute = attribute; Permission = permission; IpcRefCount = ipcRefCount; DeviceRefCount = deviceRefCount; }
/// <summary> /// 写数据到某个地址 /// </summary> /// <param name="Address">地址</param> /// <param name="Value">值</param> /// <param name="Attr">属性</param> public void Write(int Address, int Value, MemoryAttribute Attr = MemoryAttribute.DATA) { if (Address < 0 || Address > 1024) { throw new VMException(VMFault.InvalidAddr, $"无效的内存地址:{Address}"); } if (memoryAttribute[Address] != MemoryAttribute.DATA) { throw new VMException(VMFault.ReadOnly, $"内存地址禁止访问:{Address}"); } memoryPool[Address] = Value; memoryAttribute[Address] = Attr; if (Attr == MemoryAttribute.CODE) { ParamBaseAddress = Address + 1; } }
public KMemoryBlock( ulong baseAddress, ulong pagesCount, MemoryState state, KMemoryPermission permission, MemoryAttribute attribute, int ipcRefCount = 0, int deviceRefCount = 0) { BaseAddress = baseAddress; PagesCount = pagesCount; State = state; Attribute = attribute; Permission = permission; IpcRefCount = ipcRefCount; DeviceRefCount = deviceRefCount; }
public KMemoryInfo( long Position, long Size, MemoryState State, MemoryPermission Permission, MemoryAttribute Attribute, int IpcRefCount, int DeviceRefCount) { this.Position = Position; this.Size = Size; this.State = State; this.Attribute = Attribute; this.Permission = Permission; this.IpcRefCount = IpcRefCount; this.DeviceRefCount = DeviceRefCount; }
public KMemoryInfo( ulong Address, ulong Size, MemoryState State, MemoryPermission Permission, MemoryAttribute Attribute, int IpcRefCount, int DeviceRefCount) { this.Address = Address; this.Size = Size; this.State = State; this.Attribute = Attribute; this.Permission = Permission; this.IpcRefCount = IpcRefCount; this.DeviceRefCount = DeviceRefCount; }
private bool CheckRange( long Position, long Size, MemoryState StateMask, MemoryState StateExpected, MemoryPermission PermissionMask, MemoryPermission PermissionExpected, MemoryAttribute AttributeMask, MemoryAttribute AttributeExpected, MemoryAttribute AttributeIgnoreMask, out MemoryState OutState, out MemoryPermission OutPermission, out MemoryAttribute OutAttribute) { KMemoryInfo BlkInfo = FindBlock(Position).GetInfo(); ulong Start = (ulong)Position; ulong End = (ulong)Size + Start; if (End <= (ulong)(BlkInfo.Position + BlkInfo.Size)) { if ((BlkInfo.Attribute & AttributeMask) == AttributeExpected && (BlkInfo.State & StateMask) == StateExpected && (BlkInfo.Permission & PermissionMask) == PermissionExpected) { OutState = BlkInfo.State; OutPermission = BlkInfo.Permission; OutAttribute = BlkInfo.Attribute & ~AttributeIgnoreMask; return(true); } } OutState = MemoryState.Unmapped; OutPermission = MemoryPermission.None; OutAttribute = MemoryAttribute.None; return(false); }
private KernelResult CopyToClient(KMemoryManager memoryManager, List<KBufferDescriptor> list) { foreach (KBufferDescriptor desc in list) { MemoryState stateMask; switch (desc.State) { case MemoryState.IpcBuffer0: stateMask = MemoryState.IpcSendAllowedType0; break; case MemoryState.IpcBuffer1: stateMask = MemoryState.IpcSendAllowedType1; break; case MemoryState.IpcBuffer3: stateMask = MemoryState.IpcSendAllowedType3; break; default: return KernelResult.InvalidCombination; } MemoryAttribute attributeMask = MemoryAttribute.Borrowed | MemoryAttribute.Uncached; if (desc.State == MemoryState.IpcBuffer0) { attributeMask |= MemoryAttribute.DeviceMapped; } ulong clientAddrTruncated = BitUtils.AlignDown(desc.ClientAddress, KMemoryManager.PageSize); ulong clientAddrRounded = BitUtils.AlignUp (desc.ClientAddress, KMemoryManager.PageSize); // Check if address is not aligned, in this case we need to perform 2 copies. if (clientAddrTruncated != clientAddrRounded) { ulong copySize = clientAddrRounded - desc.ClientAddress; if (copySize > desc.Size) { copySize = desc.Size; } KernelResult result = memoryManager.CopyDataFromCurrentProcess( desc.ClientAddress, copySize, stateMask, stateMask, KMemoryPermission.ReadAndWrite, attributeMask, MemoryAttribute.None, desc.ServerAddress); if (result != KernelResult.Success) { return result; } } ulong clientEndAddr = desc.ClientAddress + desc.Size; ulong serverEndAddr = desc.ServerAddress + desc.Size; ulong clientEndAddrTruncated = BitUtils.AlignDown(clientEndAddr, KMemoryManager.PageSize); ulong clientEndAddrRounded = BitUtils.AlignUp (clientEndAddr, KMemoryManager.PageSize); ulong serverEndAddrTruncated = BitUtils.AlignDown(serverEndAddr, KMemoryManager.PageSize); if (clientEndAddrTruncated < clientEndAddrRounded && (clientAddrTruncated == clientAddrRounded || clientAddrTruncated < clientEndAddrTruncated)) { KernelResult result = memoryManager.CopyDataFromCurrentProcess( clientEndAddrTruncated, clientEndAddr - clientEndAddrTruncated, stateMask, stateMask, KMemoryPermission.ReadAndWrite, attributeMask, MemoryAttribute.None, serverEndAddrTruncated); if (result != KernelResult.Success) { return result; } } } return KernelResult.Success; }
static void Main() { Application.SetCompatibleTextRenderingDefault(false); Application.SetHighDpiMode(HighDpiMode.SystemAware); Application.EnableVisualStyles(); var texturePathA = Path.Combine(Path.GetDirectoryName(AppContext.BaseDirectory), "a.png"); var texturePathB = Path.Combine(Path.GetDirectoryName(AppContext.BaseDirectory), "b.png"); var textureDataA = File.ReadAllBytes(texturePathA); var textureDataB = File.ReadAllBytes(texturePathB); var vertexShader = File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(AppContext.BaseDirectory), "VertexShader.cso")); var pixelShader = File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(AppContext.BaseDirectory), "PixelShader.cso")); using var form = new Form(); using var scene = new Scene3D(); #if DEBUG scene.EnableDebug(); #endif scene.Initialize(form.Handle, 0.0f, 0.0f, form.Size.Width, form.Size.Height); float w = 1600; float h = 450; var indices = new ushort[6] { 0, 1, 2, 0, 2, 3 }; var vertices = new Vertex[4] { new Vertex() { Position = new Vector3F32(), Normal = new Vector3F32 { Z = 1.0f }, TexCoord = new Vector2F32 { X = 0.0f, Y = 1.0f } }, new Vertex() { Position = new Vector3F32 { X = w }, Normal = new Vector3F32 { Z = 1.0f }, TexCoord = new Vector2F32 { X = 2.0f, Y = 1.0f } }, new Vertex() { Position = new Vector3F32 { X = w, Y = h }, Normal = new Vector3F32 { Z = 1.0f }, TexCoord = new Vector2F32 { X = 2.0f, Y = 0.0f } }, new Vertex() { Position = new Vector3F32 { Y = h }, Normal = new Vector3F32 { Z = 1.0f }, TexCoord = new Vector2F32() } }; var textureMatrixX = stackalloc float[9]; var textureMatrixY = stackalloc float[12]; var color = stackalloc float[4] { 0.0f, 0.0f, 0.0f, 0.0f, }; textureMatrixX[0] = textureMatrixX[4] = textureMatrixX[8] = 1.0f; textureMatrixY[0] = textureMatrixY[5] = textureMatrixY[10] = 1.0f; var inputs = new List <InputElement>() { new InputElement() { SemanticName = "POS", SemanticIndex = 0, Format = Format.R32G32B32Float, InputSolt = 0, AlignedByteOffset = InputElement.AppendAlignedElement, InputSlotClass = InputClassification.PerVertexData, InstanceDataStepRate = 0 }, new InputElement() { SemanticName = "NORMAL", SemanticIndex = 0, Format = Format.R32G32B32Float, InputSolt = 0, AlignedByteOffset = InputElement.AppendAlignedElement, InputSlotClass = InputClassification.PerVertexData, InstanceDataStepRate = 0 }, new InputElement() { SemanticName = "TEXCOORD", SemanticIndex = 0, Format = Format.R32G32Float, InputSolt = 0, AlignedByteOffset = InputElement.AppendAlignedElement, InputSlotClass = InputClassification.PerVertexData, InstanceDataStepRate = 0 }, new InputElement() { SemanticName = "TEXMATRIX", SemanticIndex = 0, Format = Format.R32G32B32Float, InputSolt = 1, AlignedByteOffset = InputElement.AppendAlignedElement, InputSlotClass = InputClassification.PerInstanceData, InstanceDataStepRate = 0 }, new InputElement() { SemanticName = "TEXMATRIX", SemanticIndex = 1, Format = Format.R32G32B32Float, InputSolt = 1, AlignedByteOffset = InputElement.AppendAlignedElement, InputSlotClass = InputClassification.PerInstanceData, InstanceDataStepRate = 0 }, new InputElement() { SemanticName = "TEXMATRIX", SemanticIndex = 2, Format = Format.R32G32B32Float, InputSolt = 1, AlignedByteOffset = InputElement.AppendAlignedElement, InputSlotClass = InputClassification.PerInstanceData, InstanceDataStepRate = 0 } }; using var index = new MemoryIndex <ushort>(scene, indices); using var attribute1 = new MemoryAttribute <Vertex>(scene, vertices, (uint) sizeof(Vertex)); using var attribute2 = new DX.Sharp.Attribute(scene, textureMatrixX, 4, 9, 36); using var constant = new Constant(scene, textureMatrixY, 4, 12); using var constant2 = new Constant(scene, color, 4, 4); using var textureHeap1 = new DescriptorHeap(scene.Device, 2); using var textureHeap2 = new DescriptorHeap(scene.Device, 2); using var samplerHeap = new DescriptorHeap(scene.Device, DescriptorHeapType.Sampler, DescriptorHeapFlags.ShaderVisible, 1); using var effect = new Effect3D(inputs, new Constant[] { constant2 }, 1, 2, 1); using var loader = new TextureLoader(scene.Device, scene.CommandQueue); effect.Initialize(scene, vertexShader, pixelShader, ref BlendDescription.Opaque, ref DepthStencilDescription.Default, ref RasteriazerDescription.Default, Format.B8G8R8A8UNorm, Format.D32Float); var textures = new List <Resource>() { new Resource(), new Resource() }; scene.Device.CreateSampler(ref SamplerDescrption.LinearWrap, samplerHeap.GetCpuHandle(0)); loader.Begin(); loader.CreateTexture(textureDataA, textures[0]); loader.CreateShaderResourceView(textures[0], textureHeap1.GetCpuHandle(0)); loader.CreateShaderResourceView(textures[0], textureHeap2.GetCpuHandle(1)); loader.CreateTexture(textureDataB, textures[1]); loader.CreateShaderResourceView(textures[1], textureHeap1.GetCpuHandle(1)); loader.CreateShaderResourceView(textures[1], textureHeap2.GetCpuHandle(0)); loader.End(); using var obj1 = new Object3D(new List <DX.Sharp.Attribute> { attribute1, attribute2 }, index, new List <Constant> { constant }, effect, textureHeap1, samplerHeap); using var obj2 = new Object3D(new List <DX.Sharp.Attribute> { attribute1, attribute2 }, index, new List <Constant> { constant }, effect, textureHeap2, samplerHeap); obj1.Initialize(scene); obj2.Initialize(scene); scene.SetRenderList(new List <Object3D> { obj1, obj2 }); using var transform = new XMMatrix(); var minimized = false; scene.SetInactiveTargetUpdateTimeout(true, 1.0 / 30); form.Resize += (sender, e) => { if (form.WindowState == FormWindowState.Minimized) { scene.OnSuspending(); minimized = true; } else if (minimized) { scene.OnResuming(); minimized = false; } scene.OnWindowSizeChanged(0.0f, 0.0f, form.Size.Width, form.Size.Height); scene.Tick(); }; form.Activated += (sender, e) => { scene.OnActivated(); }; form.Deactivate += (sender, e) => { scene.OnDeactivated(); }; uint count = 0; float scale = 1; float step = 0.01f; float angle = 0; float angleStep = 1; var random = new Random(); var viewMatrix = new XMMatrix(); scene.OnUpdate += (scene, second, frame) => { if (frame > 1) { scale += step; angle += angleStep; count++; } if (angle > 360) { angle -= 360; } if (scale > 1.0f || scale < 0.1) { step = -step; } textureMatrixX[0] = scale; textureMatrixY[5] = scale; if (count == 10) { count = 0; color[0] = (float)random.NextDouble(); color[1] = (float)random.NextDouble(); color[2] = (float)random.NextDouble(); color[3] = (float)random.NextDouble(); } attribute2.Update(textureMatrixX); constant.Update(textureMatrixY); constant2.Update(color); Transform(transform, scene.Viewport, angle, scale, w, h); obj1.UpdateModelView(transform, viewMatrix); Transform(transform, scene.Viewport, angle * 2, scale, w, h); obj2.UpdateModelView(transform, viewMatrix); }; RenderLoop.Run(form, scene.Tick); }
public void InsertBlock( ulong baseAddress, ulong pagesCount, MemoryState oldState, KMemoryPermission oldPermission, MemoryAttribute oldAttribute, MemoryState newState, KMemoryPermission newPermission, MemoryAttribute newAttribute) { // Insert new block on the list only on areas where the state // of the block matches the state specified on the old* state // arguments, otherwise leave it as is. int oldCount = _blocks.Count; oldAttribute |= MemoryAttribute.IpcAndDeviceMapped; ulong endAddr = baseAddress + pagesCount * PageSize; LinkedListNode <KMemoryBlock> node = _blocks.First; while (node != null) { LinkedListNode <KMemoryBlock> newNode = node; KMemoryBlock currBlock = node.Value; ulong currBaseAddr = currBlock.BaseAddress; ulong currEndAddr = currBlock.PagesCount * PageSize + currBaseAddr; if (baseAddress < currEndAddr && currBaseAddr < endAddr) { MemoryAttribute currBlockAttr = currBlock.Attribute | MemoryAttribute.IpcAndDeviceMapped; if (currBlock.State != oldState || currBlock.Permission != oldPermission || currBlockAttr != oldAttribute) { node = node.Next; continue; } if (baseAddress > currBaseAddr) { _blocks.AddBefore(node, currBlock.SplitRightAtAddress(baseAddress)); } if (endAddr < currEndAddr) { newNode = _blocks.AddBefore(node, currBlock.SplitRightAtAddress(endAddr)); } newNode.Value.SetState(newPermission, newState, newAttribute); newNode = MergeEqualStateNeighbors(newNode); } if (currEndAddr - 1 >= endAddr - 1) { break; } node = newNode.Next; } _slabManager.Count += _blocks.Count - oldCount; ValidateInternalState(); }
private void InsertBlock( long BasePosition, long PagesCount, MemoryState State, MemoryPermission Permission = MemoryPermission.None, MemoryAttribute Attribute = MemoryAttribute.None) { //Inserts new block at the list, replacing and spliting //existing blocks as needed. KMemoryBlock Block = new KMemoryBlock(BasePosition, PagesCount, State, Permission, Attribute); ulong Start = (ulong)BasePosition; ulong End = (ulong)PagesCount * PageSize + Start; LinkedListNode <KMemoryBlock> NewNode = null; LinkedListNode <KMemoryBlock> Node = Blocks.First; while (Node != null) { KMemoryBlock CurrBlock = Node.Value; LinkedListNode <KMemoryBlock> NextNode = Node.Next; ulong CurrStart = (ulong)CurrBlock.BasePosition; ulong CurrEnd = (ulong)CurrBlock.PagesCount * PageSize + CurrStart; if (Start < CurrEnd && CurrStart < End) { if (Start >= CurrStart && End <= CurrEnd) { Block.Attribute |= CurrBlock.Attribute & MemoryAttribute.IpcAndDeviceMapped; } if (Start > CurrStart && End < CurrEnd) { CurrBlock.PagesCount = (long)((Start - CurrStart) / PageSize); long NextPagesCount = (long)((CurrEnd - End) / PageSize); NewNode = Blocks.AddAfter(Node, Block); Blocks.AddAfter(NewNode, new KMemoryBlock( (long)End, NextPagesCount, CurrBlock.State, CurrBlock.Permission, CurrBlock.Attribute)); break; } else if (Start <= CurrStart && End < CurrEnd) { CurrBlock.BasePosition = (long)End; CurrBlock.PagesCount = (long)((CurrEnd - End) / PageSize); if (NewNode == null) { NewNode = Blocks.AddBefore(Node, Block); } } else if (Start > CurrStart && End >= CurrEnd) { CurrBlock.PagesCount = (long)((Start - CurrStart) / PageSize); if (NewNode == null) { NewNode = Blocks.AddAfter(Node, Block); } } else { if (NewNode == null) { NewNode = Blocks.AddBefore(Node, Block); } Blocks.Remove(Node); } } Node = NextNode; } if (NewNode == null) { NewNode = Blocks.AddFirst(Block); } MergeEqualStateNeighbours(NewNode); }
public void InsertBlock( ulong baseAddress, ulong pagesCount, MemoryState oldState, KMemoryPermission oldPermission, MemoryAttribute oldAttribute, MemoryState newState, KMemoryPermission newPermission, MemoryAttribute newAttribute) { // Insert new block on the list only on areas where the state // of the block matches the state specified on the old* state // arguments, otherwise leave it as is. int oldCount = _blockTree.Count; oldAttribute |= MemoryAttribute.IpcAndDeviceMapped; ulong endAddr = baseAddress + pagesCount * PageSize; KMemoryBlock currBlock = FindBlock(baseAddress); while (currBlock != null) { ulong currBaseAddr = currBlock.BaseAddress; ulong currEndAddr = currBlock.PagesCount * PageSize + currBaseAddr; if (baseAddress < currEndAddr && currBaseAddr < endAddr) { MemoryAttribute currBlockAttr = currBlock.Attribute | MemoryAttribute.IpcAndDeviceMapped; if (currBlock.State != oldState || currBlock.Permission != oldPermission || currBlockAttr != oldAttribute) { currBlock = currBlock.Successor; continue; } if (baseAddress > currBaseAddr) { KMemoryBlock newBlock = currBlock.SplitRightAtAddress(baseAddress); _blockTree.Add(newBlock); } if (endAddr < currEndAddr) { KMemoryBlock newBlock = currBlock.SplitRightAtAddress(endAddr); _blockTree.Add(newBlock); currBlock = newBlock; } currBlock.SetState(newPermission, newState, newAttribute); currBlock = MergeEqualStateNeighbors(currBlock); } if (currEndAddr - 1 >= endAddr - 1) { break; } currBlock = currBlock.Successor; } _slabManager.Count += _blockTree.Count - oldCount; ValidateInternalState(); }
private void InsertBlock( long BasePosition, long PagesCount, MemoryState OldState, MemoryPermission OldPermission, MemoryAttribute OldAttribute, MemoryState NewState, MemoryPermission NewPermission, MemoryAttribute NewAttribute) { //Insert new block on the list only on areas where the state //of the block matches the state specified on the Old* state //arguments, otherwise leave it as is. OldAttribute |= MemoryAttribute.IpcAndDeviceMapped; ulong Start = (ulong)BasePosition; ulong End = (ulong)PagesCount * PageSize + Start; LinkedListNode <KMemoryBlock> Node = Blocks.First; while (Node != null) { LinkedListNode <KMemoryBlock> NewNode = Node; LinkedListNode <KMemoryBlock> NextNode = Node.Next; KMemoryBlock CurrBlock = Node.Value; ulong CurrStart = (ulong)CurrBlock.BasePosition; ulong CurrEnd = (ulong)CurrBlock.PagesCount * PageSize + CurrStart; if (Start < CurrEnd && CurrStart < End) { MemoryAttribute CurrBlockAttr = CurrBlock.Attribute | MemoryAttribute.IpcAndDeviceMapped; if (CurrBlock.State != OldState || CurrBlock.Permission != OldPermission || CurrBlockAttr != OldAttribute) { Node = NextNode; continue; } if (CurrStart >= Start && CurrEnd <= End) { CurrBlock.State = NewState; CurrBlock.Permission = NewPermission; CurrBlock.Attribute &= ~MemoryAttribute.IpcAndDeviceMapped; CurrBlock.Attribute |= NewAttribute; } else if (CurrStart >= Start) { CurrBlock.BasePosition = (long)End; CurrBlock.PagesCount = (long)((CurrEnd - End) / PageSize); long NewPagesCount = (long)((End - CurrStart) / PageSize); NewNode = Blocks.AddBefore(Node, new KMemoryBlock( (long)CurrStart, NewPagesCount, NewState, NewPermission, NewAttribute)); } else if (CurrEnd <= End) { CurrBlock.PagesCount = (long)((Start - CurrStart) / PageSize); long NewPagesCount = (long)((CurrEnd - Start) / PageSize); NewNode = Blocks.AddAfter(Node, new KMemoryBlock( BasePosition, NewPagesCount, NewState, NewPermission, NewAttribute)); } else { CurrBlock.PagesCount = (long)((Start - CurrStart) / PageSize); long NextPagesCount = (long)((CurrEnd - End) / PageSize); NewNode = Blocks.AddAfter(Node, new KMemoryBlock( BasePosition, PagesCount, NewState, NewPermission, NewAttribute)); Blocks.AddAfter(NewNode, new KMemoryBlock( (long)End, NextPagesCount, CurrBlock.State, CurrBlock.Permission, CurrBlock.Attribute)); NextNode = null; } MergeEqualStateNeighbours(NewNode); } Node = NextNode; } }