diff --git a/libstratosphere/include/stratosphere/os.hpp b/libstratosphere/include/stratosphere/os.hpp index 4db89690..0e3c22d3 100644 --- a/libstratosphere/include/stratosphere/os.hpp +++ b/libstratosphere/include/stratosphere/os.hpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/libstratosphere/include/stratosphere/os/os_managed_handle.hpp b/libstratosphere/include/stratosphere/os/os_managed_handle.hpp index b5e5281d..737c3c24 100644 --- a/libstratosphere/include/stratosphere/os/os_managed_handle.hpp +++ b/libstratosphere/include/stratosphere/os/os_managed_handle.hpp @@ -70,6 +70,11 @@ namespace ams::os { return h; } + void Detach() { + const Handle h = this->Move(); + AMS_UNUSED(h); + } + void Reset(Handle h) { ManagedHandle(h).Swap(*this); } diff --git a/libstratosphere/include/stratosphere/os/os_transfer_memory.hpp b/libstratosphere/include/stratosphere/os/os_transfer_memory.hpp new file mode 100644 index 00000000..c06e352b --- /dev/null +++ b/libstratosphere/include/stratosphere/os/os_transfer_memory.hpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include +#include + +namespace ams::os { + + class TransferMemory { + NON_COPYABLE(TransferMemory); + NON_MOVEABLE(TransferMemory); + private: + TransferMemoryType tmem; + public: + constexpr TransferMemory() : tmem{ .state = TransferMemoryType::State_NotInitialized } { + /* ... */ + } + + TransferMemory(void *address, size_t size, MemoryPermission perm) { + R_ABORT_UNLESS(CreateTransferMemory(std::addressof(this->tmem), address, size, perm)); + } + + TransferMemory(size_t size, Handle handle, bool managed) { + this->Attach(size, handle, managed); + } + + ~TransferMemory() { + if (this->tmem.state == TransferMemoryType::State_NotInitialized) { + return; + } + DestroyTransferMemory(std::addressof(this->tmem)); + } + + void Attach(size_t size, Handle handle, bool managed) { + AttachTransferMemory(std::addressof(this->tmem), size, handle, managed); + } + + Handle Detach() { + return DetachTransferMemory(std::addressof(this->tmem)); + } + + Result Map(void **out, MemoryPermission owner_perm) { + return MapTransferMemory(out, std::addressof(this->tmem), owner_perm); + } + + void Unmap() { + UnmapTransferMemory(std::addressof(this->tmem)); + } + + operator TransferMemoryType &() { + return this->tmem; + } + + operator const TransferMemoryType &() const { + return this->tmem; + } + + TransferMemoryType *GetBase() { + return std::addressof(this->tmem); + } + }; + +} diff --git a/libstratosphere/include/stratosphere/os/os_transfer_memory_api.hpp b/libstratosphere/include/stratosphere/os/os_transfer_memory_api.hpp new file mode 100644 index 00000000..2891903f --- /dev/null +++ b/libstratosphere/include/stratosphere/os/os_transfer_memory_api.hpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include + +namespace ams::os { + + struct TransferMemoryType; + + Result CreateTransferMemory(TransferMemoryType *tmem, void *address, size_t size, MemoryPermission perm); + + Result AttachTransferMemory(TransferMemoryType *tmem, size_t size, Handle handle, bool managed); + Handle DetachTransferMemory(TransferMemoryType *tmem); + + void DestroyTransferMemory(TransferMemoryType *tmem); + + Result MapTransferMemory(void **out, TransferMemoryType *tmem, MemoryPermission owner_perm); + void UnmapTransferMemory(TransferMemoryType *tmem); + +} diff --git a/libstratosphere/include/stratosphere/os/os_transfer_memory_types.hpp b/libstratosphere/include/stratosphere/os/os_transfer_memory_types.hpp new file mode 100644 index 00000000..2b532c0b --- /dev/null +++ b/libstratosphere/include/stratosphere/os/os_transfer_memory_types.hpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include + +namespace ams::os { + + struct TransferMemoryType { + enum State { + State_NotInitialized = 0, + State_Created = 1, + State_Mapped = 2, + State_Detached = 3, + }; + + u8 state; + bool handle_managed; + bool allocated; + + void *address; + size_t size; + Handle handle; + + mutable impl::InternalCriticalSectionStorage cs_transfer_memory; + }; + static_assert(std::is_trivial::value); + +} diff --git a/libstratosphere/include/stratosphere/settings.hpp b/libstratosphere/include/stratosphere/settings.hpp index d78e42be..5b995f59 100644 --- a/libstratosphere/include/stratosphere/settings.hpp +++ b/libstratosphere/include/stratosphere/settings.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/libstratosphere/include/stratosphere/settings/system/settings_platform_region.hpp b/libstratosphere/include/stratosphere/settings/system/settings_platform_region.hpp new file mode 100644 index 00000000..242358cf --- /dev/null +++ b/libstratosphere/include/stratosphere/settings/system/settings_platform_region.hpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include + +namespace ams::settings::system { + + enum PlatformRegion { + PlatformRegion_Invalid = 0, + PlatformRegion_Global = 1, + PlatformRegion_China = 2, + }; + + PlatformRegion GetPlatformRegion(); + +} diff --git a/libstratosphere/source/os/impl/os_transfer_memory_impl.hpp b/libstratosphere/source/os/impl/os_transfer_memory_impl.hpp new file mode 100644 index 00000000..39d18a5a --- /dev/null +++ b/libstratosphere/source/os/impl/os_transfer_memory_impl.hpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::os::impl { + + class TransferMemoryImpl { + public: + static Result Create(Handle *out, void *address, size_t size, MemoryPermission perm); + static void Close(Handle handle); + + static Result Map(void **out, Handle handle, void *address, size_t size, MemoryPermission owner_perm); + static void Unmap(Handle handle, void *address, size_t size); + }; + +} \ No newline at end of file diff --git a/libstratosphere/source/os/impl/os_transfer_memory_impl.os.horizon.cpp b/libstratosphere/source/os/impl/os_transfer_memory_impl.os.horizon.cpp new file mode 100644 index 00000000..d67a87b7 --- /dev/null +++ b/libstratosphere/source/os/impl/os_transfer_memory_impl.os.horizon.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "os_transfer_memory_impl.hpp" + +namespace ams::os::impl { + + namespace { + + svc::MemoryPermission ConvertToSvcMemoryPermission(os::MemoryPermission perm) { + switch (perm) { + case os::MemoryPermission_None: return svc::MemoryPermission_None; + case os::MemoryPermission_ReadOnly: return svc::MemoryPermission_Read; + case os::MemoryPermission_WriteOnly: return svc::MemoryPermission_Write; + case os::MemoryPermission_ReadWrite: return svc::MemoryPermission_ReadWrite; + AMS_UNREACHABLE_DEFAULT_CASE(); + } + } + + } + + Result TransferMemoryImpl::Create(Handle *out, void *address, size_t size, MemoryPermission perm) { + /* Convert memory permission. */ + auto svc_perm = ConvertToSvcMemoryPermission(perm); + + /* Create the memory. */ + svc::Handle handle; + R_TRY_CATCH(svc::CreateTransferMemory(std::addressof(handle), reinterpret_cast(address), size, svc_perm)) { + R_CONVERT(svc::ResultOutOfHandles, os::ResultOutOfHandles()) + R_CONVERT(svc::ResultOutOfResource, os::ResultOutOfTransferMemory()) + } R_END_TRY_CATCH_WITH_ABORT_UNLESS; + + *out = handle; + return ResultSuccess(); + } + + void TransferMemoryImpl::Close(Handle handle) { + R_ABORT_UNLESS(svc::CloseHandle(handle)); + } + + Result TransferMemoryImpl::Map(void **out, Handle handle, void *address, size_t size, MemoryPermission owner_perm) { + AMS_ASSERT(address != nullptr); + + /* Convert memory permission. */ + auto svc_owner_perm = ConvertToSvcMemoryPermission(owner_perm); + + /* Map the memory. */ + R_TRY_CATCH(svc::MapTransferMemory(handle, reinterpret_cast(address), size, svc_owner_perm)) { + R_CONVERT(svc::ResultInvalidHandle, os::ResultInvalidHandle()) + R_CONVERT(svc::ResultInvalidSize, os::ResultInvalidTransferMemorySize()) + R_CONVERT(svc::ResultInvalidState, os::ResultInvalidTransferMemoryState()) + R_CONVERT(svc::ResultInvalidCurrentMemory, os::ResultInvalidCurrentMemoryState()) + R_CONVERT(svc::ResultInvalidMemoryRegion, os::ResultInvalidCurrentMemoryState()) + } R_END_TRY_CATCH_WITH_ABORT_UNLESS; + + *out = address; + return ResultSuccess(); + } + + void TransferMemoryImpl::Unmap(Handle handle, void *address, size_t size) { + R_ABORT_UNLESS(svc::UnmapTransferMemory(handle, reinterpret_cast(address), size)); + } + +} diff --git a/libstratosphere/source/os/os_transfer_memory_api.cpp b/libstratosphere/source/os/os_transfer_memory_api.cpp new file mode 100644 index 00000000..747e1492 --- /dev/null +++ b/libstratosphere/source/os/os_transfer_memory_api.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "impl/os_thread_manager.hpp" +#include "impl/os_transfer_memory_impl.hpp" + +namespace ams::os { + + namespace { + + Result MapTransferMemoryWithAddressUnsafe(TransferMemoryType *tmem, void *address, os::MemoryPermission owner_perm) { + /* Map the transfer memory. */ + void *mapped_address = nullptr; + R_TRY(impl::TransferMemoryImpl::Map(std::addressof(mapped_address), tmem->handle, address, tmem->size, owner_perm)); + + /* Set fields now that we've mapped. */ + tmem->address = mapped_address; + tmem->state = TransferMemoryType::State_Mapped; + + return ResultSuccess(); + } + + inline void SetupTransferMemoryType(TransferMemoryType *tmem, size_t size, Handle handle, bool managed) { + /* Set members. */ + tmem->handle = handle; + tmem->size = size; + tmem->address = nullptr; + tmem->allocated = false; + + /* Set managed. */ + tmem->handle_managed = managed; + + /* Create the critical section. */ + new (GetPointer(tmem->cs_transfer_memory)) impl::InternalCriticalSection; + } + + } + + Result CreateTransferMemory(TransferMemoryType *tmem, void *address, size_t size, MemoryPermission perm) { + /* Validate pre-conditions. */ + AMS_ASSERT(size > 0); + AMS_ASSERT(util::IsAligned(size, os::MemoryPageSize)); + AMS_ASSERT(address != nullptr); + AMS_ASSERT(util::IsAligned(reinterpret_cast(address), os::MemoryPageSize)); + + /* Create the memory. */ + Handle handle; + R_TRY(impl::TransferMemoryImpl::Create(std::addressof(handle), address, size, perm)); + + /* Setup the object. */ + SetupTransferMemoryType(tmem, size, handle, true); + + return ResultSuccess(); + } + + Result AttachTransferMemory(TransferMemoryType *tmem, size_t size, Handle handle, bool managed) { + AMS_ASSERT(size > 0); + AMS_ASSERT(util::IsAligned(size, os::MemoryPageSize)); + AMS_ASSERT(handle != svc::InvalidHandle); + + /* Setup the object. */ + SetupTransferMemoryType(tmem, size, handle, managed); + + return ResultSuccess(); + } + + Handle DetachTransferMemory(TransferMemoryType *tmem) { + AMS_ASSERT(tmem->state == TransferMemoryType::State_Created); + + /* Set state to detached. */ + tmem->state = TransferMemoryType::State_Detached; + + /* Clear handle. */ + Handle handle = tmem->handle; + + tmem->handle = svc::InvalidHandle; + tmem->handle_managed = false; + + return handle; + } + + void DestroyTransferMemory(TransferMemoryType *tmem) { + /* Unmap the transfer memory, if required. */ + if (tmem->state == TransferMemoryType::State_Mapped) { + UnmapTransferMemory(tmem); + } + + /* Check the state is valid. */ + AMS_ASSERT(tmem->state == TransferMemoryType::State_Created || tmem->state == TransferMemoryType::State_Detached); + + /* Set state to not initialized. */ + tmem->state = TransferMemoryType::State_NotInitialized; + + /* Close the handle, if it's managed. */ + if (tmem->handle_managed) { + impl::TransferMemoryImpl::Close(tmem->handle); + } + tmem->handle_managed = false; + + /* Clear members. */ + tmem->address = nullptr; + tmem->size = 0; + tmem->handle = svc::InvalidHandle; + + /* Destroy the critical section. */ + GetReference(tmem->cs_transfer_memory).~InternalCriticalSection(); + } + + Result MapTransferMemory(void **out, TransferMemoryType *tmem, MemoryPermission owner_perm) { + /* Lock the current thread, and then the transfer memory. */ + std::scoped_lock thread_lk(GetReference(impl::GetCurrentThread()->cs_thread)); + std::scoped_lock lk(GetReference(tmem->cs_transfer_memory)); + + /* Ensure we're in a mappable state. */ + AMS_ASSERT(tmem->state == TransferMemoryType::State_Created); + + /* Try to map up to 64 times. */ + for (int i = 0; i < 64; ++i) { + /* Reserve space to map the memory. */ + /* TODO: os::AslrSpaceManager */ + void *map_address = ::virtmemReserve(tmem->size); + R_UNLESS(map_address != nullptr, os::ResultOutOfAddressSpace()); + + /* Mark allocated. */ + tmem->allocated = true; + auto alloc_guard = SCOPE_GUARD { tmem->allocated = false; }; + + /* Try to map. */ + R_TRY_CATCH(MapTransferMemoryWithAddressUnsafe(tmem, map_address, owner_perm)) { + /* If we failed to map at the address, retry. */ + R_CATCH(os::ResultInvalidCurrentMemoryState) { continue; } + } R_END_TRY_CATCH; + + /* TODO: Check guard space via aslr manager. */ + if (false /* !impl::GetAslrSpaceManager()->CheckGuardSpace(reinterpret_cast(tmem->address), tmem->size) */) { + impl::TransferMemoryImpl::Unmap(tmem->handle, tmem->address, tmem->size); + continue; + } + + /* We mapped successfully. */ + alloc_guard.Cancel(); + *out = tmem->address; + return ResultSuccess(); + } + + /* We failed to map. */ + return os::ResultOutOfAddressSpace(); + } + + void UnmapTransferMemory(TransferMemoryType *tmem) { + /* Lock the memory. */ + std::scoped_lock lk(GetReference(tmem->cs_transfer_memory)); + + /* If the memory isn't mapped, we can't unmap it. */ + if (tmem->state != TransferMemoryType::State_Mapped) { + return; + } + + /* Unmap the memory. */ + impl::TransferMemoryImpl::Unmap(tmem->handle, tmem->address, tmem->size); + + /* Unmapped memory is necessarily not allocated. */ + if (tmem->allocated) { + tmem->allocated = false; + } + + /* Clear the address. */ + tmem->address = nullptr; + tmem->state = TransferMemoryType::State_Created; + } + +} diff --git a/libstratosphere/source/settings/impl/settings_platform_region_impl.cpp b/libstratosphere/source/settings/impl/settings_platform_region_impl.cpp new file mode 100644 index 00000000..ce0b62eb --- /dev/null +++ b/libstratosphere/source/settings/impl/settings_platform_region_impl.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "settings_platform_region_impl.hpp" + +namespace ams::settings::impl { + + Result GetPlatformRegion(s32 *out) { + static_assert(sizeof(*out) == sizeof(::SetSysPlatformRegion)); + return ::setsysGetPlatformRegion(reinterpret_cast<::SetSysPlatformRegion *>(out)); + } + +} diff --git a/libstratosphere/source/settings/impl/settings_platform_region_impl.hpp b/libstratosphere/source/settings/impl/settings_platform_region_impl.hpp new file mode 100644 index 00000000..d5b6833e --- /dev/null +++ b/libstratosphere/source/settings/impl/settings_platform_region_impl.hpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::settings::impl { + + Result GetPlatformRegion(s32 *out); + +} diff --git a/libstratosphere/source/settings/settings_platform_region.cpp b/libstratosphere/source/settings/settings_platform_region.cpp new file mode 100644 index 00000000..b4c26b8c --- /dev/null +++ b/libstratosphere/source/settings/settings_platform_region.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "impl/settings_platform_region_impl.hpp" + +namespace ams::settings::system { + + PlatformRegion GetPlatformRegion() { + if (hos::GetVersion() >= hos::Version_9_0_0) { + s32 region = 0; + R_ABORT_UNLESS(settings::impl::GetPlatformRegion(std::addressof(region))); + return static_cast(region); + } else { + return PlatformRegion_Global; + } + } + +} diff --git a/libvapours/include/vapours/results/ns_results.hpp b/libvapours/include/vapours/results/ns_results.hpp index 557b03c8..32f95422 100644 --- a/libvapours/include/vapours/results/ns_results.hpp +++ b/libvapours/include/vapours/results/ns_results.hpp @@ -21,7 +21,11 @@ namespace ams::ns { R_DEFINE_NAMESPACE_RESULT_MODULE(16); - R_DEFINE_ERROR_RESULT(Canceled, 90); - R_DEFINE_ERROR_RESULT(OutOfMaxRunningTask, 110); + R_DEFINE_ERROR_RESULT(Canceled, 90); + R_DEFINE_ERROR_RESULT(OutOfMaxRunningTask, 110); + R_DEFINE_ERROR_RESULT(CardUpdateNotSetup, 270); + R_DEFINE_ERROR_RESULT(CardUpdateNotPrepared, 280); + R_DEFINE_ERROR_RESULT(CardUpdateAlreadySetup, 290); + R_DEFINE_ERROR_RESULT(PrepareCardUpdateAlreadyRequested, 460); } diff --git a/libvapours/include/vapours/results/os_results.hpp b/libvapours/include/vapours/results/os_results.hpp index 742b12c6..05479e26 100644 --- a/libvapours/include/vapours/results/os_results.hpp +++ b/libvapours/include/vapours/results/os_results.hpp @@ -21,12 +21,20 @@ namespace ams::os { R_DEFINE_NAMESPACE_RESULT_MODULE(3); - R_DEFINE_ERROR_RESULT(Busy, 4); + R_DEFINE_ERROR_RESULT(Busy, 4); - R_DEFINE_ERROR_RESULT(OutOfMemory, 8); - R_DEFINE_ERROR_RESULT(OutOfResource, 9); + R_DEFINE_ERROR_RESULT(OutOfMemory, 8); + R_DEFINE_ERROR_RESULT(OutOfResource, 9); - R_DEFINE_ERROR_RESULT(OutOfVirtualAddressSpace, 12); - R_DEFINE_ERROR_RESULT(ResourceLimit, 13); + R_DEFINE_ERROR_RESULT(OutOfVirtualAddressSpace, 12); + R_DEFINE_ERROR_RESULT(ResourceLimit, 13); + + R_DEFINE_ERROR_RESULT(OutOfHandles, 500); + R_DEFINE_ERROR_RESULT(InvalidHandle, 501); + R_DEFINE_ERROR_RESULT(InvalidCurrentMemoryState, 502); + R_DEFINE_ERROR_RESULT(InvalidTransferMemoryState, 503); + R_DEFINE_ERROR_RESULT(InvalidTransferMemorySize, 504); + R_DEFINE_ERROR_RESULT(OutOfTransferMemory, 505); + R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 506); }