|
|
|
@ -35,26 +35,32 @@ enum class KMemoryState : u32 {
|
|
|
|
|
FlagCanMapProcess = (1 << 23),
|
|
|
|
|
FlagCanChangeAttribute = (1 << 24),
|
|
|
|
|
FlagCanCodeMemory = (1 << 25),
|
|
|
|
|
FlagLinearMapped = (1 << 26),
|
|
|
|
|
|
|
|
|
|
FlagsData = FlagCanReprotect | FlagCanUseIpc | FlagCanUseNonDeviceIpc | FlagCanUseNonSecureIpc |
|
|
|
|
|
FlagMapped | FlagCanAlias | FlagCanTransfer | FlagCanQueryPhysical |
|
|
|
|
|
FlagCanDeviceMap | FlagCanAlignedDeviceMap | FlagCanIpcUserBuffer |
|
|
|
|
|
FlagReferenceCounted | FlagCanChangeAttribute,
|
|
|
|
|
FlagReferenceCounted | FlagCanChangeAttribute | FlagLinearMapped,
|
|
|
|
|
|
|
|
|
|
FlagsCode = FlagCanDebug | FlagCanUseIpc | FlagCanUseNonDeviceIpc | FlagCanUseNonSecureIpc |
|
|
|
|
|
FlagMapped | FlagCode | FlagCanQueryPhysical | FlagCanDeviceMap |
|
|
|
|
|
FlagCanAlignedDeviceMap | FlagReferenceCounted,
|
|
|
|
|
FlagCanAlignedDeviceMap | FlagReferenceCounted | FlagLinearMapped,
|
|
|
|
|
|
|
|
|
|
FlagsMisc = FlagMapped | FlagReferenceCounted | FlagCanQueryPhysical | FlagCanDeviceMap,
|
|
|
|
|
FlagsMisc = FlagMapped | FlagReferenceCounted | FlagCanQueryPhysical | FlagCanDeviceMap |
|
|
|
|
|
FlagLinearMapped,
|
|
|
|
|
|
|
|
|
|
Free = static_cast<u32>(Svc::MemoryState::Free),
|
|
|
|
|
Io = static_cast<u32>(Svc::MemoryState::Io) | FlagMapped,
|
|
|
|
|
Io = static_cast<u32>(Svc::MemoryState::Io) | FlagMapped | FlagCanDeviceMap |
|
|
|
|
|
FlagCanAlignedDeviceMap,
|
|
|
|
|
Static = static_cast<u32>(Svc::MemoryState::Static) | FlagMapped | FlagCanQueryPhysical,
|
|
|
|
|
Code = static_cast<u32>(Svc::MemoryState::Code) | FlagsCode | FlagCanMapProcess,
|
|
|
|
|
CodeData = static_cast<u32>(Svc::MemoryState::CodeData) | FlagsData | FlagCanMapProcess |
|
|
|
|
|
FlagCanCodeMemory,
|
|
|
|
|
Shared = static_cast<u32>(Svc::MemoryState::Shared) | FlagMapped | FlagReferenceCounted,
|
|
|
|
|
Normal = static_cast<u32>(Svc::MemoryState::Normal) | FlagsData | FlagCanCodeMemory,
|
|
|
|
|
Shared = static_cast<u32>(Svc::MemoryState::Shared) | FlagMapped | FlagReferenceCounted |
|
|
|
|
|
FlagLinearMapped,
|
|
|
|
|
|
|
|
|
|
// Alias was removed after 1.0.0.
|
|
|
|
|
|
|
|
|
|
AliasCode = static_cast<u32>(Svc::MemoryState::AliasCode) | FlagsCode | FlagCanMapProcess |
|
|
|
|
|
FlagCanCodeAlias,
|
|
|
|
@ -67,18 +73,18 @@ enum class KMemoryState : u32 {
|
|
|
|
|
Stack = static_cast<u32>(Svc::MemoryState::Stack) | FlagsMisc | FlagCanAlignedDeviceMap |
|
|
|
|
|
FlagCanUseIpc | FlagCanUseNonSecureIpc | FlagCanUseNonDeviceIpc,
|
|
|
|
|
|
|
|
|
|
ThreadLocal =
|
|
|
|
|
static_cast<u32>(Svc::MemoryState::ThreadLocal) | FlagMapped | FlagReferenceCounted,
|
|
|
|
|
ThreadLocal = static_cast<u32>(Svc::MemoryState::ThreadLocal) | FlagMapped | FlagLinearMapped,
|
|
|
|
|
|
|
|
|
|
Transfered = static_cast<u32>(Svc::MemoryState::Transferred) | FlagsMisc |
|
|
|
|
|
Transfered = static_cast<u32>(Svc::MemoryState::Transfered) | FlagsMisc |
|
|
|
|
|
FlagCanAlignedDeviceMap | FlagCanChangeAttribute | FlagCanUseIpc |
|
|
|
|
|
FlagCanUseNonSecureIpc | FlagCanUseNonDeviceIpc,
|
|
|
|
|
|
|
|
|
|
SharedTransfered = static_cast<u32>(Svc::MemoryState::SharedTransferred) | FlagsMisc |
|
|
|
|
|
SharedTransfered = static_cast<u32>(Svc::MemoryState::SharedTransfered) | FlagsMisc |
|
|
|
|
|
FlagCanAlignedDeviceMap | FlagCanUseNonSecureIpc | FlagCanUseNonDeviceIpc,
|
|
|
|
|
|
|
|
|
|
SharedCode = static_cast<u32>(Svc::MemoryState::SharedCode) | FlagMapped |
|
|
|
|
|
FlagReferenceCounted | FlagCanUseNonSecureIpc | FlagCanUseNonDeviceIpc,
|
|
|
|
|
FlagReferenceCounted | FlagLinearMapped | FlagCanUseNonSecureIpc |
|
|
|
|
|
FlagCanUseNonDeviceIpc,
|
|
|
|
|
|
|
|
|
|
Inaccessible = static_cast<u32>(Svc::MemoryState::Inaccessible),
|
|
|
|
|
|
|
|
|
@ -91,69 +97,69 @@ enum class KMemoryState : u32 {
|
|
|
|
|
Kernel = static_cast<u32>(Svc::MemoryState::Kernel) | FlagMapped,
|
|
|
|
|
|
|
|
|
|
GeneratedCode = static_cast<u32>(Svc::MemoryState::GeneratedCode) | FlagMapped |
|
|
|
|
|
FlagReferenceCounted | FlagCanDebug,
|
|
|
|
|
CodeOut = static_cast<u32>(Svc::MemoryState::CodeOut) | FlagMapped | FlagReferenceCounted,
|
|
|
|
|
FlagReferenceCounted | FlagCanDebug | FlagLinearMapped,
|
|
|
|
|
CodeOut = static_cast<u32>(Svc::MemoryState::CodeOut) | FlagMapped | FlagReferenceCounted |
|
|
|
|
|
FlagLinearMapped,
|
|
|
|
|
|
|
|
|
|
Coverage = static_cast<u32>(Svc::MemoryState::Coverage) | FlagMapped,
|
|
|
|
|
|
|
|
|
|
Insecure = static_cast<u32>(Svc::MemoryState::Insecure) | FlagMapped | FlagReferenceCounted |
|
|
|
|
|
FlagLinearMapped | FlagCanChangeAttribute | FlagCanDeviceMap |
|
|
|
|
|
FlagCanAlignedDeviceMap | FlagCanUseNonSecureIpc | FlagCanUseNonDeviceIpc,
|
|
|
|
|
};
|
|
|
|
|
DECLARE_ENUM_FLAG_OPERATORS(KMemoryState);
|
|
|
|
|
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Free) == 0x00000000);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Io) == 0x00002001);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Io) == 0x00182001);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Static) == 0x00042002);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Code) == 0x00DC7E03);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::CodeData) == 0x03FEBD04);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Normal) == 0x037EBD05);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Shared) == 0x00402006);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::AliasCode) == 0x00DD7E08);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::AliasCodeData) == 0x03FFBD09);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Ipc) == 0x005C3C0A);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Stack) == 0x005C3C0B);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::ThreadLocal) == 0x0040200C);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Transfered) == 0x015C3C0D);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::SharedTransfered) == 0x005C380E);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::SharedCode) == 0x0040380F);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Code) == 0x04DC7E03);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::CodeData) == 0x07FEBD04);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Normal) == 0x077EBD05);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Shared) == 0x04402006);
|
|
|
|
|
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::AliasCode) == 0x04DD7E08);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::AliasCodeData) == 0x07FFBD09);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Ipc) == 0x045C3C0A);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Stack) == 0x045C3C0B);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::ThreadLocal) == 0x0400200C);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Transfered) == 0x055C3C0D);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::SharedTransfered) == 0x045C380E);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::SharedCode) == 0x0440380F);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Inaccessible) == 0x00000010);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::NonSecureIpc) == 0x005C3811);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::NonDeviceIpc) == 0x004C2812);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::NonSecureIpc) == 0x045C3811);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::NonDeviceIpc) == 0x044C2812);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Kernel) == 0x00002013);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::GeneratedCode) == 0x00402214);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::CodeOut) == 0x00402015);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::GeneratedCode) == 0x04402214);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::CodeOut) == 0x04402015);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Coverage) == 0x00002016);
|
|
|
|
|
static_assert(static_cast<u32>(KMemoryState::Insecure) == 0x05583817);
|
|
|
|
|
|
|
|
|
|
enum class KMemoryPermission : u8 {
|
|
|
|
|
None = 0,
|
|
|
|
|
All = static_cast<u8>(~None),
|
|
|
|
|
|
|
|
|
|
Read = 1 << 0,
|
|
|
|
|
Write = 1 << 1,
|
|
|
|
|
Execute = 1 << 2,
|
|
|
|
|
|
|
|
|
|
ReadAndWrite = Read | Write,
|
|
|
|
|
ReadAndExecute = Read | Execute,
|
|
|
|
|
|
|
|
|
|
UserMask = static_cast<u8>(Svc::MemoryPermission::Read | Svc::MemoryPermission::Write |
|
|
|
|
|
Svc::MemoryPermission::Execute),
|
|
|
|
|
|
|
|
|
|
KernelShift = 3,
|
|
|
|
|
|
|
|
|
|
KernelRead = Read << KernelShift,
|
|
|
|
|
KernelWrite = Write << KernelShift,
|
|
|
|
|
KernelExecute = Execute << KernelShift,
|
|
|
|
|
KernelRead = static_cast<u8>(Svc::MemoryPermission::Read) << KernelShift,
|
|
|
|
|
KernelWrite = static_cast<u8>(Svc::MemoryPermission::Write) << KernelShift,
|
|
|
|
|
KernelExecute = static_cast<u8>(Svc::MemoryPermission::Execute) << KernelShift,
|
|
|
|
|
|
|
|
|
|
NotMapped = (1 << (2 * KernelShift)),
|
|
|
|
|
|
|
|
|
|
KernelReadWrite = KernelRead | KernelWrite,
|
|
|
|
|
KernelReadExecute = KernelRead | KernelExecute,
|
|
|
|
|
|
|
|
|
|
UserRead = Read | KernelRead,
|
|
|
|
|
UserWrite = Write | KernelWrite,
|
|
|
|
|
UserExecute = Execute,
|
|
|
|
|
UserRead = static_cast<u8>(Svc::MemoryPermission::Read) | KernelRead,
|
|
|
|
|
UserWrite = static_cast<u8>(Svc::MemoryPermission::Write) | KernelWrite,
|
|
|
|
|
UserExecute = static_cast<u8>(Svc::MemoryPermission::Execute),
|
|
|
|
|
|
|
|
|
|
UserReadWrite = UserRead | UserWrite,
|
|
|
|
|
UserReadExecute = UserRead | UserExecute,
|
|
|
|
|
|
|
|
|
|
IpcLockChangeMask = NotMapped | UserReadWrite
|
|
|
|
|
UserMask = static_cast<u8>(Svc::MemoryPermission::Read | Svc::MemoryPermission::Write |
|
|
|
|
|
Svc::MemoryPermission::Execute),
|
|
|
|
|
|
|
|
|
|
IpcLockChangeMask = NotMapped | UserReadWrite,
|
|
|
|
|
};
|
|
|
|
|
DECLARE_ENUM_FLAG_OPERATORS(KMemoryPermission);
|
|
|
|
|
|
|
|
|
@ -468,6 +474,7 @@ public:
|
|
|
|
|
|
|
|
|
|
constexpr void UpdateDeviceDisableMergeStateForShareLeft(
|
|
|
|
|
[[maybe_unused]] KMemoryPermission new_perm, bool left, [[maybe_unused]] bool right) {
|
|
|
|
|
// New permission/right aren't used.
|
|
|
|
|
if (left) {
|
|
|
|
|
m_disable_merge_attribute = static_cast<KMemoryBlockDisableMergeAttribute>(
|
|
|
|
|
m_disable_merge_attribute | KMemoryBlockDisableMergeAttribute::DeviceLeft);
|
|
|
|
@ -478,6 +485,7 @@ public:
|
|
|
|
|
|
|
|
|
|
constexpr void UpdateDeviceDisableMergeStateForShareRight(
|
|
|
|
|
[[maybe_unused]] KMemoryPermission new_perm, [[maybe_unused]] bool left, bool right) {
|
|
|
|
|
// New permission/left aren't used.
|
|
|
|
|
if (right) {
|
|
|
|
|
m_disable_merge_attribute = static_cast<KMemoryBlockDisableMergeAttribute>(
|
|
|
|
|
m_disable_merge_attribute | KMemoryBlockDisableMergeAttribute::DeviceRight);
|
|
|
|
@ -494,6 +502,8 @@ public:
|
|
|
|
|
|
|
|
|
|
constexpr void ShareToDevice([[maybe_unused]] KMemoryPermission new_perm, bool left,
|
|
|
|
|
bool right) {
|
|
|
|
|
// New permission isn't used.
|
|
|
|
|
|
|
|
|
|
// We must either be shared or have a zero lock count.
|
|
|
|
|
ASSERT((m_attribute & KMemoryAttribute::DeviceShared) == KMemoryAttribute::DeviceShared ||
|
|
|
|
|
m_device_use_count == 0);
|
|
|
|
@ -509,6 +519,7 @@ public:
|
|
|
|
|
|
|
|
|
|
constexpr void UpdateDeviceDisableMergeStateForUnshareLeft(
|
|
|
|
|
[[maybe_unused]] KMemoryPermission new_perm, bool left, [[maybe_unused]] bool right) {
|
|
|
|
|
// New permission/right aren't used.
|
|
|
|
|
|
|
|
|
|
if (left) {
|
|
|
|
|
if (!m_device_disable_merge_left_count) {
|
|
|
|
@ -528,6 +539,8 @@ public:
|
|
|
|
|
|
|
|
|
|
constexpr void UpdateDeviceDisableMergeStateForUnshareRight(
|
|
|
|
|
[[maybe_unused]] KMemoryPermission new_perm, [[maybe_unused]] bool left, bool right) {
|
|
|
|
|
// New permission/left aren't used.
|
|
|
|
|
|
|
|
|
|
if (right) {
|
|
|
|
|
const u16 old_device_disable_merge_right_count = m_device_disable_merge_right_count--;
|
|
|
|
|
ASSERT(old_device_disable_merge_right_count > 0);
|
|
|
|
@ -546,6 +559,8 @@ public:
|
|
|
|
|
|
|
|
|
|
constexpr void UnshareToDevice([[maybe_unused]] KMemoryPermission new_perm, bool left,
|
|
|
|
|
bool right) {
|
|
|
|
|
// New permission isn't used.
|
|
|
|
|
|
|
|
|
|
// We must be shared.
|
|
|
|
|
ASSERT((m_attribute & KMemoryAttribute::DeviceShared) == KMemoryAttribute::DeviceShared);
|
|
|
|
|
|
|
|
|
@ -563,6 +578,7 @@ public:
|
|
|
|
|
|
|
|
|
|
constexpr void UnshareToDeviceRight([[maybe_unused]] KMemoryPermission new_perm, bool left,
|
|
|
|
|
bool right) {
|
|
|
|
|
// New permission isn't used.
|
|
|
|
|
|
|
|
|
|
// We must be shared.
|
|
|
|
|
ASSERT((m_attribute & KMemoryAttribute::DeviceShared) == KMemoryAttribute::DeviceShared);
|
|
|
|
@ -613,6 +629,8 @@ public:
|
|
|
|
|
|
|
|
|
|
constexpr void UnlockForIpc([[maybe_unused]] KMemoryPermission new_perm, bool left,
|
|
|
|
|
[[maybe_unused]] bool right) {
|
|
|
|
|
// New permission isn't used.
|
|
|
|
|
|
|
|
|
|
// We must be locked.
|
|
|
|
|
ASSERT((m_attribute & KMemoryAttribute::IpcLocked) == KMemoryAttribute::IpcLocked);
|
|
|
|
|
|
|
|
|
|