Ejemplo n.º 1
0
        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();
        }