diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/kernel/errors.h | 21 | ||||
-rw-r--r-- | src/core/hle/kernel/process.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/kernel/server_port.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/kernel/shared_memory.cpp | 7 | ||||
-rw-r--r-- | src/core/hle/kernel/svc.cpp | 13 | ||||
-rw-r--r-- | src/core/hle/kernel/vm_manager.cpp | 20 | ||||
-rw-r--r-- | src/core/hle/kernel/vm_manager.h | 8 |
7 files changed, 50 insertions, 29 deletions
diff --git a/src/core/hle/kernel/errors.h b/src/core/hle/kernel/errors.h index 885259618..ee698c8a7 100644 --- a/src/core/hle/kernel/errors.h +++ b/src/core/hle/kernel/errors.h @@ -10,11 +10,6 @@ namespace Kernel { namespace ErrCodes { enum { - // TODO(Subv): Remove these 3DS OS error codes. - SessionClosedByRemote = 26, - NoPendingSessions = 35, - InvalidBufferDescriptor = 48, - // Confirmed Switch OS error codes MaxConnectionsReached = 7, InvalidSize = 101, @@ -26,6 +21,7 @@ enum { InvalidThreadPriority = 112, InvalidProcessorId = 113, InvalidHandle = 114, + InvalidPointer = 115, InvalidCombination = 116, Timeout = 117, SynchronizationCanceled = 118, @@ -33,6 +29,7 @@ enum { InvalidEnumValue = 120, NoSuchEntry = 121, AlreadyRegistered = 122, + SessionClosed = 123, InvalidState = 125, ResourceLimitExceeded = 132, }; @@ -41,18 +38,14 @@ enum { // WARNING: The kernel is quite inconsistent in it's usage of errors code. Make sure to always // double check that the code matches before re-using the constant. -// TODO(bunnei): Replace -1 with correct errors for Switch OS constexpr ResultCode ERR_HANDLE_TABLE_FULL(ErrorModule::Kernel, ErrCodes::HandleTableFull); -constexpr ResultCode ERR_SESSION_CLOSED_BY_REMOTE(-1); +constexpr ResultCode ERR_SESSION_CLOSED_BY_REMOTE(ErrorModule::Kernel, ErrCodes::SessionClosed); constexpr ResultCode ERR_PORT_NAME_TOO_LONG(ErrorModule::Kernel, ErrCodes::TooLarge); constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(ErrorModule::Kernel, ErrCodes::MaxConnectionsReached); constexpr ResultCode ERR_INVALID_ENUM_VALUE(ErrorModule::Kernel, ErrCodes::InvalidEnumValue); -constexpr ResultCode ERR_INVALID_ENUM_VALUE_FND(-1); -constexpr ResultCode ERR_INVALID_COMBINATION(-1); constexpr ResultCode ERR_INVALID_COMBINATION_KERNEL(ErrorModule::Kernel, ErrCodes::InvalidCombination); -constexpr ResultCode ERR_OUT_OF_MEMORY(-1); constexpr ResultCode ERR_INVALID_ADDRESS(ErrorModule::Kernel, ErrCodes::InvalidAddress); constexpr ResultCode ERR_INVALID_ADDRESS_STATE(ErrorModule::Kernel, ErrCodes::InvalidMemoryState); constexpr ResultCode ERR_INVALID_MEMORY_PERMISSIONS(ErrorModule::Kernel, @@ -65,14 +58,8 @@ constexpr ResultCode ERR_ALREADY_REGISTERED(ErrorModule::Kernel, ErrCodes::Alrea constexpr ResultCode ERR_INVALID_STATE(ErrorModule::Kernel, ErrCodes::InvalidState); constexpr ResultCode ERR_INVALID_THREAD_PRIORITY(ErrorModule::Kernel, ErrCodes::InvalidThreadPriority); -constexpr ResultCode ERR_INVALID_POINTER(-1); -constexpr ResultCode ERR_INVALID_OBJECT_ADDR(-1); -constexpr ResultCode ERR_NOT_AUTHORIZED(-1); -/// Alternate code returned instead of ERR_INVALID_HANDLE in some code paths. -constexpr ResultCode ERR_INVALID_HANDLE_OS(-1); +constexpr ResultCode ERR_INVALID_POINTER(ErrorModule::Kernel, ErrCodes::InvalidPointer); constexpr ResultCode ERR_NOT_FOUND(ErrorModule::Kernel, ErrCodes::NoSuchEntry); constexpr ResultCode RESULT_TIMEOUT(ErrorModule::Kernel, ErrCodes::Timeout); -/// Returned when Accept() is called on a port with no sessions to be accepted. -constexpr ResultCode ERR_NO_PENDING_SESSIONS(-1); } // namespace Kernel diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 073dd5a7d..420218d59 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -232,6 +232,12 @@ void Process::LoadModule(CodeSet module_, VAddr base_addr) { MapSegment(module_.CodeSegment(), VMAPermission::ReadExecute, MemoryState::CodeStatic); MapSegment(module_.RODataSegment(), VMAPermission::Read, MemoryState::CodeMutable); MapSegment(module_.DataSegment(), VMAPermission::ReadWrite, MemoryState::CodeMutable); + + // Clear instruction cache in CPU JIT + Core::System::GetInstance().ArmInterface(0).ClearInstructionCache(); + Core::System::GetInstance().ArmInterface(1).ClearInstructionCache(); + Core::System::GetInstance().ArmInterface(2).ClearInstructionCache(); + Core::System::GetInstance().ArmInterface(3).ClearInstructionCache(); } ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) { diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index 3792e3e18..d6ceeb2da 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -18,7 +18,7 @@ ServerPort::~ServerPort() = default; ResultVal<SharedPtr<ServerSession>> ServerPort::Accept() { if (pending_sessions.empty()) { - return ERR_NO_PENDING_SESSIONS; + return ERR_NOT_FOUND; } auto session = std::move(pending_sessions.back()); @@ -28,7 +28,7 @@ ResultVal<SharedPtr<ServerSession>> ServerPort::Accept() { bool ServerPort::ShouldWait(Thread* thread) const { // If there are no pending sessions, we wait until a new one is added. - return pending_sessions.size() == 0; + return pending_sessions.empty(); } void ServerPort::Acquire(Thread* thread) { diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index d061e6155..a016a86b6 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -80,20 +80,19 @@ SharedPtr<SharedMemory> SharedMemory::CreateForApplet( ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermission permissions, MemoryPermission other_permissions) { - - MemoryPermission own_other_permissions = + const MemoryPermission own_other_permissions = target_process == owner_process ? this->permissions : this->other_permissions; // Automatically allocated memory blocks can only be mapped with other_permissions = DontCare if (base_address == 0 && other_permissions != MemoryPermission::DontCare) { - return ERR_INVALID_COMBINATION; + return ERR_INVALID_MEMORY_PERMISSIONS; } // Error out if the requested permissions don't match what the creator process allows. if (static_cast<u32>(permissions) & ~static_cast<u32>(own_other_permissions)) { LOG_ERROR(Kernel, "cannot map id={}, address=0x{:X} name={}, permissions don't match", GetObjectId(), address, name); - return ERR_INVALID_COMBINATION; + return ERR_INVALID_MEMORY_PERMISSIONS; } // Error out if the provided permissions are not compatible with what the creator process needs. diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 9a783d524..a5302d924 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -594,16 +594,17 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { } const auto* const current_process = Core::CurrentProcess(); - SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); - if (!thread) { - return ERR_INVALID_HANDLE; - } // Note: The kernel uses the current process's resource limit instead of // the one from the thread owner's resource limit. const ResourceLimit& resource_limit = current_process->GetResourceLimit(); if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) { - return ERR_NOT_AUTHORIZED; + return ERR_INVALID_THREAD_PRIORITY; + } + + SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); + if (!thread) { + return ERR_INVALID_HANDLE; } thread->SetPriority(priority); @@ -745,7 +746,7 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V auto* const current_process = Core::CurrentProcess(); const ResourceLimit& resource_limit = current_process->GetResourceLimit(); if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) { - return ERR_NOT_AUTHORIZED; + return ERR_INVALID_THREAD_PRIORITY; } if (processor_id == THREADPROCESSORID_DEFAULT) { diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index e1a34eef1..1a92c8f70 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -143,6 +143,26 @@ ResultVal<VMManager::VMAHandle> VMManager::MapBackingMemory(VAddr target, u8* me return MakeResult<VMAHandle>(MergeAdjacent(vma_handle)); } +ResultVal<VAddr> VMManager::FindFreeRegion(u64 size) const { + // Find the first Free VMA. + const VAddr base = GetASLRRegionBaseAddress(); + const VMAHandle vma_handle = std::find_if(vma_map.begin(), vma_map.end(), [&](const auto& vma) { + if (vma.second.type != VMAType::Free) + return false; + + const VAddr vma_end = vma.second.base + vma.second.size; + return vma_end > base && vma_end >= base + size; + }); + + if (vma_handle == vma_map.end()) { + // TODO(Subv): Find the correct error code here. + return ResultCode(-1); + } + + const VAddr target = std::max(base, vma_handle->second.base); + return MakeResult<VAddr>(target); +} + ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u64 size, MemoryState state, Memory::MemoryHookPointer mmio_handler) { diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 84c890224..2447cbb8f 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -158,6 +158,14 @@ public: ResultVal<VMAHandle> MapBackingMemory(VAddr target, u8* memory, u64 size, MemoryState state); /** + * Finds the first free address that can hold a region of the desired size. + * + * @param size Size of the desired region. + * @return The found free address. + */ + ResultVal<VAddr> FindFreeRegion(u64 size) const; + + /** * Maps a memory-mapped IO region at a given address. * * @param target The guest address to start the mapping at. |