using System;
namespace Ryujinx.HLE.HOS.Kernel.Memory
{
class KMemoryBlock
public ulong BaseAddress { get; private set; }
public ulong PagesCount { get; private set; }
public MemoryState State { get; private set; }
public MemoryPermission Permission { get; private set; }
public MemoryAttribute Attribute { get; private set; }
public MemoryPermission SourcePermission { get; private set; }
public int IpcRefCount { get; private set; }
public int DeviceRefCount { get; private set; }
public KMemoryBlock(
ulong baseAddress,
ulong pagesCount,
MemoryState state,
MemoryPermission permission,
MemoryAttribute attribute,
int ipcRefCount = 0,
int deviceRefCount = 0)
BaseAddress = baseAddress;
PagesCount = pagesCount;
State = state;
Attribute = attribute;
Permission = permission;
IpcRefCount = ipcRefCount;
DeviceRefCount = deviceRefCount;
}
public void SetState(MemoryPermission permission, MemoryState state, MemoryAttribute attribute)
Attribute &= MemoryAttribute.IpcAndDeviceMapped;
Attribute |= attribute;
public void SetIpcMappingPermission(MemoryPermission permission)
int oldIpcRefCount = IpcRefCount++;
if ((ushort)IpcRefCount == 0)
throw new InvalidOperationException("IPC reference count increment overflowed.");
if (oldIpcRefCount == 0)
SourcePermission = permission;
Permission &= ~MemoryPermission.ReadAndWrite;
Permission |= MemoryPermission.ReadAndWrite & permission;
Attribute |= MemoryAttribute.IpcMapped;
public void RestoreIpcMappingPermission()
int oldIpcRefCount = IpcRefCount--;
throw new InvalidOperationException("IPC reference count decrement underflowed.");
if (oldIpcRefCount == 1)
Permission = SourcePermission;
SourcePermission = MemoryPermission.None;
Attribute &= ~MemoryAttribute.IpcMapped;
public KMemoryBlock SplitRightAtAddress(ulong address)
ulong leftAddress = BaseAddress;
ulong leftPagesCount = (address - leftAddress) / KMemoryManager.PageSize;
BaseAddress = address;
PagesCount -= leftPagesCount;
return new KMemoryBlock(
leftAddress,
leftPagesCount,
State,
Permission,
Attribute,
IpcRefCount,
DeviceRefCount);
public void AddPages(ulong pagesCount)
PagesCount += pagesCount;
public KMemoryInfo GetInfo()
ulong size = PagesCount * KMemoryManager.PageSize;
return new KMemoryInfo(
BaseAddress,
size,
SourcePermission,