Add support for PermissionLocked attribute added on firmware 17.0.0 (#6072)
* Update MemoryState enum and add new flags * Add support for new PermissionLocked attribute added on firmware 17.0.0 * Format whitespace
This commit is contained in:
parent
f11d663df7
commit
6f50b9bdb0
4 changed files with 172 additions and 35 deletions
|
@ -675,7 +675,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||||
KMemoryPermission.None,
|
KMemoryPermission.None,
|
||||||
MemoryAttribute.Mask,
|
MemoryAttribute.Mask,
|
||||||
MemoryAttribute.None,
|
MemoryAttribute.None,
|
||||||
MemoryAttribute.IpcAndDeviceMapped,
|
MemoryAttribute.IpcAndDeviceMapped | MemoryAttribute.PermissionLocked,
|
||||||
out MemoryState state,
|
out MemoryState state,
|
||||||
out _,
|
out _,
|
||||||
out _);
|
out _);
|
||||||
|
@ -687,7 +687,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||||
state,
|
state,
|
||||||
KMemoryPermission.None,
|
KMemoryPermission.None,
|
||||||
KMemoryPermission.None,
|
KMemoryPermission.None,
|
||||||
MemoryAttribute.Mask,
|
MemoryAttribute.Mask & ~MemoryAttribute.PermissionLocked,
|
||||||
MemoryAttribute.None);
|
MemoryAttribute.None);
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
|
@ -913,19 +913,27 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result SetMemoryAttribute(
|
public Result SetMemoryAttribute(ulong address, ulong size, MemoryAttribute attributeMask, MemoryAttribute attributeValue)
|
||||||
ulong address,
|
|
||||||
ulong size,
|
|
||||||
MemoryAttribute attributeMask,
|
|
||||||
MemoryAttribute attributeValue)
|
|
||||||
{
|
{
|
||||||
lock (_blockManager)
|
lock (_blockManager)
|
||||||
{
|
{
|
||||||
|
MemoryState stateCheckMask = 0;
|
||||||
|
|
||||||
|
if (attributeMask.HasFlag(MemoryAttribute.Uncached))
|
||||||
|
{
|
||||||
|
stateCheckMask = MemoryState.AttributeChangeAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attributeMask.HasFlag(MemoryAttribute.PermissionLocked))
|
||||||
|
{
|
||||||
|
stateCheckMask |= MemoryState.PermissionLockAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
if (CheckRange(
|
if (CheckRange(
|
||||||
address,
|
address,
|
||||||
size,
|
size,
|
||||||
MemoryState.AttributeChangeAllowed,
|
stateCheckMask,
|
||||||
MemoryState.AttributeChangeAllowed,
|
stateCheckMask,
|
||||||
KMemoryPermission.None,
|
KMemoryPermission.None,
|
||||||
KMemoryPermission.None,
|
KMemoryPermission.None,
|
||||||
MemoryAttribute.BorrowedAndIpcMapped,
|
MemoryAttribute.BorrowedAndIpcMapped,
|
||||||
|
|
|
@ -12,11 +12,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||||
IpcMapped = 1 << 1,
|
IpcMapped = 1 << 1,
|
||||||
DeviceMapped = 1 << 2,
|
DeviceMapped = 1 << 2,
|
||||||
Uncached = 1 << 3,
|
Uncached = 1 << 3,
|
||||||
|
PermissionLocked = 1 << 4,
|
||||||
|
|
||||||
IpcAndDeviceMapped = IpcMapped | DeviceMapped,
|
IpcAndDeviceMapped = IpcMapped | DeviceMapped,
|
||||||
|
|
||||||
BorrowedAndIpcMapped = Borrowed | IpcMapped,
|
BorrowedAndIpcMapped = Borrowed | IpcMapped,
|
||||||
|
|
||||||
DeviceMappedAndUncached = DeviceMapped | Uncached,
|
DeviceMappedAndUncached = DeviceMapped | Uncached,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,35 +5,155 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||||
[Flags]
|
[Flags]
|
||||||
enum MemoryState : uint
|
enum MemoryState : uint
|
||||||
{
|
{
|
||||||
Unmapped = 0x00000000,
|
Unmapped = 0x0,
|
||||||
Io = 0x00002001,
|
Io = Mapped | 0x1,
|
||||||
Normal = 0x00042002,
|
Normal = Mapped | QueryPhysicalAddressAllowed | 0x2,
|
||||||
CodeStatic = 0x00DC7E03,
|
CodeStatic = ForceReadWritableByDebugSyscalls |
|
||||||
CodeMutable = 0x03FEBD04,
|
IpcSendAllowedType0 |
|
||||||
Heap = 0x037EBD05,
|
IpcSendAllowedType3 |
|
||||||
SharedMemory = 0x00402006,
|
IpcSendAllowedType1 |
|
||||||
ModCodeStatic = 0x00DD7E08,
|
Mapped |
|
||||||
ModCodeMutable = 0x03FFBD09,
|
ProcessPermissionChangeAllowed |
|
||||||
IpcBuffer0 = 0x005C3C0A,
|
QueryPhysicalAddressAllowed |
|
||||||
Stack = 0x005C3C0B,
|
MapDeviceAllowed |
|
||||||
ThreadLocal = 0x0040200C,
|
MapDeviceAlignedAllowed |
|
||||||
TransferMemoryIsolated = 0x015C3C0D,
|
IsPoolAllocated |
|
||||||
TransferMemory = 0x005C380E,
|
MapProcessAllowed |
|
||||||
ProcessMemory = 0x0040380F,
|
LinearMapped |
|
||||||
Reserved = 0x00000010,
|
0x3,
|
||||||
IpcBuffer1 = 0x005C3811,
|
CodeMutable = PermissionChangeAllowed |
|
||||||
IpcBuffer3 = 0x004C2812,
|
IpcSendAllowedType0 |
|
||||||
KernelStack = 0x00002013,
|
IpcSendAllowedType3 |
|
||||||
CodeReadOnly = 0x00402214,
|
IpcSendAllowedType1 |
|
||||||
CodeWritable = 0x00402015,
|
Mapped |
|
||||||
UserMask = 0xff,
|
MapAllowed |
|
||||||
Mask = 0xffffffff,
|
TransferMemoryAllowed |
|
||||||
|
QueryPhysicalAddressAllowed |
|
||||||
|
MapDeviceAllowed |
|
||||||
|
MapDeviceAlignedAllowed |
|
||||||
|
IpcBufferAllowed |
|
||||||
|
IsPoolAllocated |
|
||||||
|
MapProcessAllowed |
|
||||||
|
AttributeChangeAllowed |
|
||||||
|
CodeMemoryAllowed |
|
||||||
|
LinearMapped |
|
||||||
|
PermissionLockAllowed |
|
||||||
|
0x4,
|
||||||
|
Heap = PermissionChangeAllowed |
|
||||||
|
IpcSendAllowedType0 |
|
||||||
|
IpcSendAllowedType3 |
|
||||||
|
IpcSendAllowedType1 |
|
||||||
|
Mapped |
|
||||||
|
MapAllowed |
|
||||||
|
TransferMemoryAllowed |
|
||||||
|
QueryPhysicalAddressAllowed |
|
||||||
|
MapDeviceAllowed |
|
||||||
|
MapDeviceAlignedAllowed |
|
||||||
|
IpcBufferAllowed |
|
||||||
|
IsPoolAllocated |
|
||||||
|
AttributeChangeAllowed |
|
||||||
|
CodeMemoryAllowed |
|
||||||
|
LinearMapped |
|
||||||
|
0x5,
|
||||||
|
SharedMemory = Mapped | IsPoolAllocated | LinearMapped | 0x6,
|
||||||
|
ModCodeStatic = ForceReadWritableByDebugSyscalls |
|
||||||
|
IpcSendAllowedType0 |
|
||||||
|
IpcSendAllowedType3 |
|
||||||
|
IpcSendAllowedType1 |
|
||||||
|
Mapped |
|
||||||
|
ProcessPermissionChangeAllowed |
|
||||||
|
UnmapProcessCodeMemoryAllowed |
|
||||||
|
QueryPhysicalAddressAllowed |
|
||||||
|
MapDeviceAllowed |
|
||||||
|
MapDeviceAlignedAllowed |
|
||||||
|
IsPoolAllocated |
|
||||||
|
MapProcessAllowed |
|
||||||
|
LinearMapped |
|
||||||
|
0x8,
|
||||||
|
ModCodeMutable = PermissionChangeAllowed |
|
||||||
|
IpcSendAllowedType0 |
|
||||||
|
IpcSendAllowedType3 |
|
||||||
|
IpcSendAllowedType1 |
|
||||||
|
Mapped |
|
||||||
|
MapAllowed |
|
||||||
|
UnmapProcessCodeMemoryAllowed |
|
||||||
|
TransferMemoryAllowed |
|
||||||
|
QueryPhysicalAddressAllowed |
|
||||||
|
MapDeviceAllowed |
|
||||||
|
MapDeviceAlignedAllowed |
|
||||||
|
IpcBufferAllowed |
|
||||||
|
IsPoolAllocated |
|
||||||
|
MapProcessAllowed |
|
||||||
|
AttributeChangeAllowed |
|
||||||
|
CodeMemoryAllowed |
|
||||||
|
LinearMapped |
|
||||||
|
PermissionLockAllowed |
|
||||||
|
0x9,
|
||||||
|
IpcBuffer0 = IpcSendAllowedType0 |
|
||||||
|
IpcSendAllowedType3 |
|
||||||
|
IpcSendAllowedType1 |
|
||||||
|
Mapped |
|
||||||
|
QueryPhysicalAddressAllowed |
|
||||||
|
MapDeviceAllowed |
|
||||||
|
MapDeviceAlignedAllowed |
|
||||||
|
IsPoolAllocated |
|
||||||
|
LinearMapped |
|
||||||
|
0xA,
|
||||||
|
Stack = IpcSendAllowedType0 |
|
||||||
|
IpcSendAllowedType3 |
|
||||||
|
IpcSendAllowedType1 |
|
||||||
|
Mapped |
|
||||||
|
QueryPhysicalAddressAllowed |
|
||||||
|
MapDeviceAllowed |
|
||||||
|
MapDeviceAlignedAllowed |
|
||||||
|
IsPoolAllocated |
|
||||||
|
LinearMapped |
|
||||||
|
0xB,
|
||||||
|
ThreadLocal = Mapped | IsPoolAllocated | LinearMapped | 0xC,
|
||||||
|
TransferMemoryIsolated = IpcSendAllowedType0 |
|
||||||
|
IpcSendAllowedType3 |
|
||||||
|
IpcSendAllowedType1 |
|
||||||
|
Mapped |
|
||||||
|
QueryPhysicalAddressAllowed |
|
||||||
|
MapDeviceAllowed |
|
||||||
|
MapDeviceAlignedAllowed |
|
||||||
|
IsPoolAllocated |
|
||||||
|
AttributeChangeAllowed |
|
||||||
|
LinearMapped |
|
||||||
|
0xD,
|
||||||
|
TransferMemory = IpcSendAllowedType3 |
|
||||||
|
IpcSendAllowedType1 |
|
||||||
|
Mapped |
|
||||||
|
QueryPhysicalAddressAllowed |
|
||||||
|
MapDeviceAllowed |
|
||||||
|
MapDeviceAlignedAllowed |
|
||||||
|
IsPoolAllocated |
|
||||||
|
LinearMapped |
|
||||||
|
0xE,
|
||||||
|
ProcessMemory = IpcSendAllowedType3 | IpcSendAllowedType1 | Mapped | IsPoolAllocated | LinearMapped | 0xF,
|
||||||
|
Reserved = 0x10,
|
||||||
|
IpcBuffer1 = IpcSendAllowedType3 |
|
||||||
|
IpcSendAllowedType1 |
|
||||||
|
Mapped |
|
||||||
|
QueryPhysicalAddressAllowed |
|
||||||
|
MapDeviceAllowed |
|
||||||
|
MapDeviceAlignedAllowed |
|
||||||
|
IsPoolAllocated |
|
||||||
|
LinearMapped |
|
||||||
|
0x11,
|
||||||
|
IpcBuffer3 = IpcSendAllowedType3 | Mapped | QueryPhysicalAddressAllowed | MapDeviceAllowed | IsPoolAllocated | LinearMapped | 0x12,
|
||||||
|
KernelStack = Mapped | 0x13,
|
||||||
|
CodeReadOnly = ForceReadWritableByDebugSyscalls | Mapped | IsPoolAllocated | LinearMapped | 0x14,
|
||||||
|
CodeWritable = Mapped | IsPoolAllocated | LinearMapped | 0x15,
|
||||||
|
UserMask = 0xFF,
|
||||||
|
Mask = 0xFFFFFFFF,
|
||||||
|
|
||||||
PermissionChangeAllowed = 1 << 8,
|
PermissionChangeAllowed = 1 << 8,
|
||||||
ForceReadWritableByDebugSyscalls = 1 << 9,
|
ForceReadWritableByDebugSyscalls = 1 << 9,
|
||||||
IpcSendAllowedType0 = 1 << 10,
|
IpcSendAllowedType0 = 1 << 10,
|
||||||
IpcSendAllowedType3 = 1 << 11,
|
IpcSendAllowedType3 = 1 << 11,
|
||||||
IpcSendAllowedType1 = 1 << 12,
|
IpcSendAllowedType1 = 1 << 12,
|
||||||
|
Mapped = 1 << 13,
|
||||||
ProcessPermissionChangeAllowed = 1 << 14,
|
ProcessPermissionChangeAllowed = 1 << 14,
|
||||||
MapAllowed = 1 << 15,
|
MapAllowed = 1 << 15,
|
||||||
UnmapProcessCodeMemoryAllowed = 1 << 16,
|
UnmapProcessCodeMemoryAllowed = 1 << 16,
|
||||||
|
@ -46,5 +166,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||||
MapProcessAllowed = 1 << 23,
|
MapProcessAllowed = 1 << 23,
|
||||||
AttributeChangeAllowed = 1 << 24,
|
AttributeChangeAllowed = 1 << 24,
|
||||||
CodeMemoryAllowed = 1 << 25,
|
CodeMemoryAllowed = 1 << 25,
|
||||||
|
LinearMapped = 1 << 26,
|
||||||
|
PermissionLockAllowed = 1 << 27,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -949,8 +949,16 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||||
|
|
||||||
MemoryAttribute attributes = attributeMask | attributeValue;
|
MemoryAttribute attributes = attributeMask | attributeValue;
|
||||||
|
|
||||||
|
const MemoryAttribute SupportedAttributes = MemoryAttribute.Uncached | MemoryAttribute.PermissionLocked;
|
||||||
|
|
||||||
if (attributes != attributeMask ||
|
if (attributes != attributeMask ||
|
||||||
(attributes | MemoryAttribute.Uncached) != MemoryAttribute.Uncached)
|
(attributes | SupportedAttributes) != SupportedAttributes)
|
||||||
|
{
|
||||||
|
return KernelResult.InvalidCombination;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The permission locked attribute can't be unset.
|
||||||
|
if ((attributeMask & MemoryAttribute.PermissionLocked) != (attributeValue & MemoryAttribute.PermissionLocked))
|
||||||
{
|
{
|
||||||
return KernelResult.InvalidCombination;
|
return KernelResult.InvalidCombination;
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue