mirror of
https://github.com/PabloMK7/citra.git
synced 2025-12-01 04:48:47 +00:00
kernel: Update to use atmosphere macros and correct Result (#7242)
* kernel: Switch to atmosphere style macros * code: Rename ResultCode to Result * code: Result constants are lower case * Address review comments * core: Remove CASCADE_CODE * R_TRY replaces completely * core: Run clang format
This commit is contained in:
parent
811303ea54
commit
5a7f615da1
132 changed files with 2807 additions and 2995 deletions
|
|
@ -108,8 +108,8 @@ void AddressArbiter::WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> t
|
|||
waiting_threads.end());
|
||||
};
|
||||
|
||||
ResultCode AddressArbiter::ArbitrateAddress(std::shared_ptr<Thread> thread, ArbitrationType type,
|
||||
VAddr address, s32 value, u64 nanoseconds) {
|
||||
Result AddressArbiter::ArbitrateAddress(std::shared_ptr<Thread> thread, ArbitrationType type,
|
||||
VAddr address, s32 value, u64 nanoseconds) {
|
||||
switch (type) {
|
||||
|
||||
// Signal thread(s) waiting for arbitrate address...
|
||||
|
|
@ -171,17 +171,16 @@ ResultCode AddressArbiter::ArbitrateAddress(std::shared_ptr<Thread> thread, Arbi
|
|||
|
||||
default:
|
||||
LOG_ERROR(Kernel, "unknown type={}", type);
|
||||
return ERR_INVALID_ENUM_VALUE_FND;
|
||||
return ResultInvalidEnumValueFnd;
|
||||
}
|
||||
|
||||
// The calls that use a timeout seem to always return a Timeout error even if they did not put
|
||||
// the thread to sleep
|
||||
if (type == ArbitrationType::WaitIfLessThanWithTimeout ||
|
||||
type == ArbitrationType::DecrementAndWaitIfLessThanWithTimeout) {
|
||||
|
||||
return RESULT_TIMEOUT;
|
||||
return ResultTimeout;
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
} // namespace Kernel
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ public:
|
|||
std::shared_ptr<ResourceLimit> resource_limit;
|
||||
std::string name; ///< Name of address arbiter object (optional)
|
||||
|
||||
ResultCode ArbitrateAddress(std::shared_ptr<Thread> thread, ArbitrationType type, VAddr address,
|
||||
s32 value, u64 nanoseconds);
|
||||
Result ArbitrateAddress(std::shared_ptr<Thread> thread, ArbitrationType type, VAddr address,
|
||||
s32 value, u64 nanoseconds);
|
||||
|
||||
class Callback;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,32 +20,31 @@ namespace Kernel {
|
|||
ClientPort::ClientPort(KernelSystem& kernel) : Object(kernel), kernel(kernel) {}
|
||||
ClientPort::~ClientPort() = default;
|
||||
|
||||
ResultVal<std::shared_ptr<ClientSession>> ClientPort::Connect() {
|
||||
Result ClientPort::Connect(std::shared_ptr<ClientSession>* out_client_session) {
|
||||
// Note: Threads do not wait for the server endpoint to call
|
||||
// AcceptSession before returning from this call.
|
||||
|
||||
if (active_sessions >= max_sessions) {
|
||||
return ERR_MAX_CONNECTIONS_REACHED;
|
||||
}
|
||||
R_UNLESS(active_sessions < max_sessions, ResultMaxConnectionsReached);
|
||||
active_sessions++;
|
||||
|
||||
// Create a new session pair, let the created sessions inherit the parent port's HLE handler.
|
||||
auto [server, client] = kernel.CreateSessionPair(server_port->GetName(), SharedFrom(this));
|
||||
|
||||
if (server_port->hle_handler)
|
||||
if (server_port->hle_handler) {
|
||||
server_port->hle_handler->ClientConnected(server);
|
||||
else
|
||||
} else {
|
||||
server_port->pending_sessions.push_back(server);
|
||||
}
|
||||
|
||||
// Wake the threads waiting on the ServerPort
|
||||
server_port->WakeupAllWaitingThreads();
|
||||
|
||||
return client;
|
||||
*out_client_session = client;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
void ClientPort::ConnectionClosed() {
|
||||
ASSERT(active_sessions > 0);
|
||||
|
||||
--active_sessions;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ public:
|
|||
* waiting on it to awake.
|
||||
* @returns ClientSession The client endpoint of the created Session pair, or error code.
|
||||
*/
|
||||
ResultVal<std::shared_ptr<ClientSession>> Connect();
|
||||
Result Connect(std::shared_ptr<ClientSession>* out_client_session);
|
||||
|
||||
/**
|
||||
* Signifies that a previously active connection has been closed,
|
||||
|
|
|
|||
|
|
@ -44,11 +44,10 @@ ClientSession::~ClientSession() {
|
|||
}
|
||||
}
|
||||
|
||||
ResultCode ClientSession::SendSyncRequest(std::shared_ptr<Thread> thread) {
|
||||
Result ClientSession::SendSyncRequest(std::shared_ptr<Thread> thread) {
|
||||
// Keep ServerSession alive until we're done working with it.
|
||||
std::shared_ptr<ServerSession> server = SharedFrom(parent->server);
|
||||
if (server == nullptr)
|
||||
return ERR_SESSION_CLOSED_BY_REMOTE;
|
||||
R_UNLESS(server, ResultSessionClosed);
|
||||
|
||||
// Signal the server session that new data is available
|
||||
return server->HandleSyncRequest(std::move(thread));
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@ public:
|
|||
/**
|
||||
* Sends an SyncRequest from the current emulated thread.
|
||||
* @param thread Thread that initiated the request.
|
||||
* @return ResultCode of the operation.
|
||||
* @return Result of the operation.
|
||||
*/
|
||||
ResultCode SendSyncRequest(std::shared_ptr<Thread> thread);
|
||||
Result SendSyncRequest(std::shared_ptr<Thread> thread);
|
||||
|
||||
std::string name; ///< Name of client port (optional)
|
||||
|
||||
|
|
|
|||
|
|
@ -31,85 +31,83 @@ 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.
|
||||
|
||||
constexpr ResultCode ERR_OUT_OF_HANDLES(ErrCodes::OutOfHandles, ErrorModule::Kernel,
|
||||
ErrorSummary::OutOfResource,
|
||||
ErrorLevel::Permanent); // 0xD8600413
|
||||
constexpr ResultCode ERR_SESSION_CLOSED_BY_REMOTE(ErrCodes::SessionClosedByRemote, ErrorModule::OS,
|
||||
ErrorSummary::Canceled,
|
||||
ErrorLevel::Status); // 0xC920181A
|
||||
constexpr ResultCode ERR_PORT_NAME_TOO_LONG(ErrCodes::PortNameTooLong, ErrorModule::OS,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Usage); // 0xE0E0181E
|
||||
constexpr ResultCode ERR_WRONG_PERMISSION(ErrCodes::WrongPermission, ErrorModule::OS,
|
||||
ErrorSummary::WrongArgument, ErrorLevel::Permanent);
|
||||
constexpr ResultCode ERR_INVALID_BUFFER_DESCRIPTOR(ErrCodes::InvalidBufferDescriptor,
|
||||
ErrorModule::OS, ErrorSummary::WrongArgument,
|
||||
ErrorLevel::Permanent);
|
||||
constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(ErrCodes::MaxConnectionsReached, ErrorModule::OS,
|
||||
ErrorSummary::WouldBlock,
|
||||
ErrorLevel::Temporary); // 0xD0401834
|
||||
|
||||
constexpr ResultCode ERR_NOT_AUTHORIZED(ErrorDescription::NotAuthorized, ErrorModule::OS,
|
||||
ErrorSummary::WrongArgument,
|
||||
ErrorLevel::Permanent); // 0xD9001BEA
|
||||
constexpr ResultCode ERR_INVALID_ENUM_VALUE(ErrorDescription::InvalidEnumValue, ErrorModule::Kernel,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Permanent); // 0xD8E007ED
|
||||
constexpr ResultCode ERR_INVALID_ENUM_VALUE_FND(ErrorDescription::InvalidEnumValue,
|
||||
ErrorModule::FND, ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Permanent); // 0xD8E093ED
|
||||
constexpr ResultCode ERR_INVALID_COMBINATION(ErrorDescription::InvalidCombination, ErrorModule::OS,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Usage); // 0xE0E01BEE
|
||||
constexpr ResultCode ERR_INVALID_COMBINATION_KERNEL(ErrorDescription::InvalidCombination,
|
||||
ErrorModule::Kernel,
|
||||
ErrorSummary::WrongArgument,
|
||||
ErrorLevel::Permanent); // 0xD90007EE
|
||||
constexpr ResultCode ERR_MISALIGNED_ADDRESS(ErrorDescription::MisalignedAddress, ErrorModule::OS,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Usage); // 0xE0E01BF1
|
||||
constexpr ResultCode ERR_MISALIGNED_SIZE(ErrorDescription::MisalignedSize, ErrorModule::OS,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Usage); // 0xE0E01BF2
|
||||
constexpr ResultCode ERR_OUT_OF_MEMORY(ErrorDescription::OutOfMemory, ErrorModule::Kernel,
|
||||
ErrorSummary::OutOfResource,
|
||||
ErrorLevel::Permanent); // 0xD86007F3
|
||||
/// Returned when out of heap or linear heap memory when allocating
|
||||
constexpr ResultCode ERR_OUT_OF_HEAP_MEMORY(ErrorDescription::OutOfMemory, ErrorModule::OS,
|
||||
ErrorSummary::OutOfResource,
|
||||
ErrorLevel::Status); // 0xC860180A
|
||||
constexpr ResultCode ERR_NOT_IMPLEMENTED(ErrorDescription::NotImplemented, ErrorModule::OS,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Usage); // 0xE0E01BF4
|
||||
constexpr ResultCode ERR_INVALID_ADDRESS(ErrorDescription::InvalidAddress, ErrorModule::OS,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Usage); // 0xE0E01BF5
|
||||
constexpr ResultCode ERR_INVALID_ADDRESS_STATE(ErrorDescription::InvalidAddress, ErrorModule::OS,
|
||||
ErrorSummary::InvalidState,
|
||||
ErrorLevel::Usage); // 0xE0A01BF5
|
||||
constexpr ResultCode ERR_INVALID_POINTER(ErrorDescription::InvalidPointer, ErrorModule::Kernel,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Permanent); // 0xD8E007F6
|
||||
constexpr ResultCode ERR_INVALID_HANDLE(ErrorDescription::InvalidHandle, ErrorModule::Kernel,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Permanent); // 0xD8E007F7
|
||||
/// Alternate code returned instead of ERR_INVALID_HANDLE in some code paths.
|
||||
constexpr ResultCode ERR_INVALID_HANDLE_OS(ErrorDescription::InvalidHandle, ErrorModule::OS,
|
||||
ErrorSummary::WrongArgument,
|
||||
ErrorLevel::Permanent); // 0xD9001BF7
|
||||
constexpr ResultCode ERR_NOT_FOUND(ErrorDescription::NotFound, ErrorModule::Kernel,
|
||||
ErrorSummary::NotFound, ErrorLevel::Permanent); // 0xD88007FA
|
||||
constexpr ResultCode ERR_OUT_OF_RANGE(ErrorDescription::OutOfRange, ErrorModule::OS,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Usage); // 0xE0E01BFD
|
||||
constexpr ResultCode ERR_OUT_OF_RANGE_KERNEL(ErrorDescription::OutOfRange, ErrorModule::Kernel,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Permanent); // 0xD8E007FD
|
||||
constexpr ResultCode RESULT_TIMEOUT(ErrorDescription::Timeout, ErrorModule::OS,
|
||||
ErrorSummary::StatusChanged, ErrorLevel::Info);
|
||||
/// Returned when Accept() is called on a port with no sessions to be accepted.
|
||||
constexpr ResultCode ERR_NO_PENDING_SESSIONS(ErrCodes::NoPendingSessions, ErrorModule::OS,
|
||||
constexpr Result ResultOutOfHandles(ErrCodes::OutOfHandles, ErrorModule::Kernel,
|
||||
ErrorSummary::OutOfResource,
|
||||
ErrorLevel::Permanent); // 0xD8600413
|
||||
constexpr Result ResultSessionClosed(ErrCodes::SessionClosedByRemote, ErrorModule::OS,
|
||||
ErrorSummary::Canceled,
|
||||
ErrorLevel::Status); // 0xC920181A
|
||||
constexpr Result ResultPortNameTooLong(ErrCodes::PortNameTooLong, ErrorModule::OS,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Usage); // 0xE0E0181E
|
||||
constexpr Result ResultWrongPermission(ErrCodes::WrongPermission, ErrorModule::OS,
|
||||
ErrorSummary::WrongArgument, ErrorLevel::Permanent);
|
||||
constexpr Result ResultInvalidBufferDescriptor(ErrCodes::InvalidBufferDescriptor, ErrorModule::OS,
|
||||
ErrorSummary::WrongArgument, ErrorLevel::Permanent);
|
||||
constexpr Result ResultMaxConnectionsReached(ErrCodes::MaxConnectionsReached, ErrorModule::OS,
|
||||
ErrorSummary::WouldBlock,
|
||||
ErrorLevel::Permanent); // 0xD8401823
|
||||
ErrorLevel::Temporary); // 0xD0401834
|
||||
|
||||
constexpr Result ResultNotAuthorized(ErrorDescription::NotAuthorized, ErrorModule::OS,
|
||||
ErrorSummary::WrongArgument,
|
||||
ErrorLevel::Permanent); // 0xD9001BEA
|
||||
constexpr Result ResultInvalidEnumValue(ErrorDescription::InvalidEnumValue, ErrorModule::Kernel,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Permanent); // 0xD8E007ED
|
||||
constexpr Result ResultInvalidEnumValueFnd(ErrorDescription::InvalidEnumValue, ErrorModule::FND,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Permanent); // 0xD8E093ED
|
||||
constexpr Result ResultInvalidCombination(ErrorDescription::InvalidCombination, ErrorModule::OS,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Usage); // 0xE0E01BEE
|
||||
constexpr Result ResultInvalidCombinationKernel(ErrorDescription::InvalidCombination,
|
||||
ErrorModule::Kernel, ErrorSummary::WrongArgument,
|
||||
ErrorLevel::Permanent); // 0xD90007EE
|
||||
constexpr Result ResultMisalignedAddress(ErrorDescription::MisalignedAddress, ErrorModule::OS,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Usage); // 0xE0E01BF1
|
||||
constexpr Result ResultMisalignedSize(ErrorDescription::MisalignedSize, ErrorModule::OS,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Usage); // 0xE0E01BF2
|
||||
constexpr Result ResultOutOfMemory(ErrorDescription::OutOfMemory, ErrorModule::Kernel,
|
||||
ErrorSummary::OutOfResource,
|
||||
ErrorLevel::Permanent); // 0xD86007F3
|
||||
/// Returned when out of heap or linear heap memory when allocating
|
||||
constexpr Result ResultOutOfHeapMemory(ErrorDescription::OutOfMemory, ErrorModule::OS,
|
||||
ErrorSummary::OutOfResource,
|
||||
ErrorLevel::Status); // 0xC860180A
|
||||
constexpr Result ResultNotImplemented(ErrorDescription::NotImplemented, ErrorModule::OS,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Usage); // 0xE0E01BF4
|
||||
constexpr Result ResultInvalidAddress(ErrorDescription::InvalidAddress, ErrorModule::OS,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Usage); // 0xE0E01BF5
|
||||
constexpr Result ResultInvalidAddressState(ErrorDescription::InvalidAddress, ErrorModule::OS,
|
||||
ErrorSummary::InvalidState,
|
||||
ErrorLevel::Usage); // 0xE0A01BF5
|
||||
constexpr Result ResultInvalidPointer(ErrorDescription::InvalidPointer, ErrorModule::Kernel,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Permanent); // 0xD8E007F6
|
||||
constexpr Result ResultInvalidHandle(ErrorDescription::InvalidHandle, ErrorModule::Kernel,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Permanent); // 0xD8E007F7
|
||||
/// Alternate code returned instead of ResultInvalidHandle in some code paths.
|
||||
constexpr Result ResultInvalidHandleOs(ErrorDescription::InvalidHandle, ErrorModule::OS,
|
||||
ErrorSummary::WrongArgument,
|
||||
ErrorLevel::Permanent); // 0xD9001BF7
|
||||
constexpr Result ResultNotFound(ErrorDescription::NotFound, ErrorModule::Kernel,
|
||||
ErrorSummary::NotFound, ErrorLevel::Permanent); // 0xD88007FA
|
||||
constexpr Result ResultOutOfRange(ErrorDescription::OutOfRange, ErrorModule::OS,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Usage); // 0xE0E01BFD
|
||||
constexpr Result ResultOutOfRangeKernel(ErrorDescription::OutOfRange, ErrorModule::Kernel,
|
||||
ErrorSummary::InvalidArgument,
|
||||
ErrorLevel::Permanent); // 0xD8E007FD
|
||||
constexpr Result ResultTimeout(ErrorDescription::Timeout, ErrorModule::OS,
|
||||
ErrorSummary::StatusChanged, ErrorLevel::Info);
|
||||
/// Returned when Accept() is called on a port with no sessions to be accepted.
|
||||
constexpr Result ResultNoPendingSessions(ErrCodes::NoPendingSessions, ErrorModule::OS,
|
||||
ErrorSummary::WouldBlock,
|
||||
ErrorLevel::Permanent); // 0xD8401823
|
||||
|
||||
} // namespace Kernel
|
||||
|
|
|
|||
|
|
@ -36,8 +36,9 @@ bool Event::ShouldWait(const Thread* thread) const {
|
|||
void Event::Acquire(Thread* thread) {
|
||||
ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
|
||||
|
||||
if (reset_type == ResetType::OneShot)
|
||||
if (reset_type == ResetType::OneShot) {
|
||||
signaled = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Event::Signal() {
|
||||
|
|
@ -52,8 +53,9 @@ void Event::Clear() {
|
|||
void Event::WakeupAllWaitingThreads() {
|
||||
WaitObject::WakeupAllWaitingThreads();
|
||||
|
||||
if (reset_type == ResetType::Pulse)
|
||||
if (reset_type == ResetType::Pulse) {
|
||||
signaled = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Kernel
|
||||
|
|
|
|||
|
|
@ -28,56 +28,48 @@ HandleTable::HandleTable(KernelSystem& kernel) : kernel(kernel) {
|
|||
|
||||
HandleTable::~HandleTable() = default;
|
||||
|
||||
ResultVal<Handle> HandleTable::Create(std::shared_ptr<Object> obj) {
|
||||
Result HandleTable::Create(Handle* out_handle, std::shared_ptr<Object> obj) {
|
||||
DEBUG_ASSERT(obj != nullptr);
|
||||
|
||||
u16 slot = next_free_slot;
|
||||
if (slot >= generations.size()) {
|
||||
LOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use.");
|
||||
return ERR_OUT_OF_HANDLES;
|
||||
}
|
||||
R_UNLESS(slot < generations.size(), ResultOutOfHandles);
|
||||
next_free_slot = generations[slot];
|
||||
|
||||
u16 generation = next_generation++;
|
||||
|
||||
// Overflow count so it fits in the 15 bits dedicated to the generation in the handle.
|
||||
// CTR-OS doesn't use generation 0, so skip straight to 1.
|
||||
if (next_generation >= (1 << 15))
|
||||
if (next_generation >= (1 << 15)) {
|
||||
next_generation = 1;
|
||||
}
|
||||
|
||||
generations[slot] = generation;
|
||||
objects[slot] = std::move(obj);
|
||||
|
||||
Handle handle = generation | (slot << 15);
|
||||
return handle;
|
||||
*out_handle = generation | (slot << 15);
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
|
||||
Result HandleTable::Duplicate(Handle* out_handle, Handle handle) {
|
||||
std::shared_ptr<Object> object = GetGeneric(handle);
|
||||
if (object == nullptr) {
|
||||
LOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle);
|
||||
return ERR_INVALID_HANDLE;
|
||||
}
|
||||
return Create(std::move(object));
|
||||
R_UNLESS(object, ResultInvalidHandle);
|
||||
return Create(out_handle, std::move(object));
|
||||
}
|
||||
|
||||
ResultCode HandleTable::Close(Handle handle) {
|
||||
if (!IsValid(handle))
|
||||
return ERR_INVALID_HANDLE;
|
||||
|
||||
u16 slot = GetSlot(handle);
|
||||
Result HandleTable::Close(Handle handle) {
|
||||
R_UNLESS(IsValid(handle), ResultInvalidHandle);
|
||||
|
||||
const u16 slot = GetSlot(handle);
|
||||
objects[slot] = nullptr;
|
||||
|
||||
generations[slot] = next_free_slot;
|
||||
next_free_slot = slot;
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
bool HandleTable::IsValid(Handle handle) const {
|
||||
std::size_t slot = GetSlot(handle);
|
||||
u16 generation = GetGeneration(handle);
|
||||
|
||||
const u16 slot = GetSlot(handle);
|
||||
const u16 generation = GetGeneration(handle);
|
||||
return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,24 +51,24 @@ public:
|
|||
/**
|
||||
* Allocates a handle for the given object.
|
||||
* @return The created Handle or one of the following errors:
|
||||
* - `ERR_OUT_OF_HANDLES`: the maximum number of handles has been exceeded.
|
||||
* - `ResultOutOfHandles`: the maximum number of handles has been exceeded.
|
||||
*/
|
||||
ResultVal<Handle> Create(std::shared_ptr<Object> obj);
|
||||
Result Create(Handle* out_handle, std::shared_ptr<Object> obj);
|
||||
|
||||
/**
|
||||
* Returns a new handle that points to the same object as the passed in handle.
|
||||
* @return The duplicated Handle or one of the following errors:
|
||||
* - `ERR_INVALID_HANDLE`: an invalid handle was passed in.
|
||||
* - `ResultInvalidHandle`: an invalid handle was passed in.
|
||||
* - Any errors returned by `Create()`.
|
||||
*/
|
||||
ResultVal<Handle> Duplicate(Handle handle);
|
||||
Result Duplicate(Handle* out_handle, Handle handle);
|
||||
|
||||
/**
|
||||
* Closes a handle, removing it from the table and decreasing the object's ref-count.
|
||||
* @return `RESULT_SUCCESS` or one of the following errors:
|
||||
* - `ERR_INVALID_HANDLE`: an invalid handle was passed in.
|
||||
* @return `ResultSuccess` or one of the following errors:
|
||||
* - `ResultInvalidHandle`: an invalid handle was passed in.
|
||||
*/
|
||||
ResultCode Close(Handle handle);
|
||||
Result Close(Handle handle);
|
||||
|
||||
/// Checks if a handle is valid and points to an existing object.
|
||||
bool IsValid(Handle handle) const;
|
||||
|
|
|
|||
|
|
@ -126,8 +126,8 @@ void HLERequestContext::AddStaticBuffer(u8 buffer_id, std::vector<u8> data) {
|
|||
static_buffers[buffer_id] = std::move(data);
|
||||
}
|
||||
|
||||
ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(
|
||||
const u32_le* src_cmdbuf, std::shared_ptr<Process> src_process_) {
|
||||
Result HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf,
|
||||
std::shared_ptr<Process> src_process_) {
|
||||
auto& src_process = *src_process_;
|
||||
IPC::Header header{src_cmdbuf[0]};
|
||||
|
||||
|
|
@ -203,11 +203,11 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(
|
|||
std::move(translated_cmdbuf));
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf,
|
||||
Process& dst_process) const {
|
||||
Result HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf,
|
||||
Process& dst_process) const {
|
||||
IPC::Header header{cmd_buf[0]};
|
||||
|
||||
std::size_t untranslated_size = 1u + header.normal_params_size;
|
||||
|
|
@ -239,7 +239,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf,
|
|||
Handle handle = 0;
|
||||
if (object != nullptr) {
|
||||
// TODO(yuriks): Figure out the proper error handling for if this fails
|
||||
handle = dst_process.handle_table.Create(object).Unwrap();
|
||||
R_ASSERT(dst_process.handle_table.Create(std::addressof(handle), object));
|
||||
}
|
||||
dst_cmdbuf[i++] = handle;
|
||||
}
|
||||
|
|
@ -281,7 +281,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf,
|
|||
std::move(translated_cmdbuf));
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
MappedBuffer& HLERequestContext::GetMappedBuffer(u32 id_from_cmdbuf) {
|
||||
|
|
|
|||
|
|
@ -363,10 +363,10 @@ public:
|
|||
MappedBuffer& GetMappedBuffer(u32 id_from_cmdbuf);
|
||||
|
||||
/// Populates this context with data from the requesting process/thread.
|
||||
ResultCode PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf,
|
||||
std::shared_ptr<Process> src_process);
|
||||
Result PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf,
|
||||
std::shared_ptr<Process> src_process);
|
||||
/// Writes data from this context back to the requesting process/thread.
|
||||
ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process) const;
|
||||
Result WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process) const;
|
||||
|
||||
/// Reports an unimplemented function.
|
||||
void ReportUnimplemented() const;
|
||||
|
|
|
|||
|
|
@ -18,12 +18,11 @@
|
|||
|
||||
namespace Kernel {
|
||||
|
||||
ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySystem& memory,
|
||||
std::shared_ptr<Thread> src_thread,
|
||||
std::shared_ptr<Thread> dst_thread, VAddr src_address,
|
||||
VAddr dst_address,
|
||||
std::vector<MappedBufferContext>& mapped_buffer_context,
|
||||
bool reply) {
|
||||
Result TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySystem& memory,
|
||||
std::shared_ptr<Thread> src_thread,
|
||||
std::shared_ptr<Thread> dst_thread, VAddr src_address,
|
||||
VAddr dst_address,
|
||||
std::vector<MappedBufferContext>& mapped_buffer_context, bool reply) {
|
||||
auto src_process = src_thread->owner_process.lock();
|
||||
auto dst_process = dst_thread->owner_process.lock();
|
||||
ASSERT(src_process && dst_process);
|
||||
|
|
@ -60,8 +59,8 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy
|
|||
// Note: The real kernel does not check that the number of handles fits into the command
|
||||
// buffer before writing them, only after finishing.
|
||||
if (i + num_handles > command_size) {
|
||||
return ResultCode(ErrCodes::CommandTooLarge, ErrorModule::OS,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Status);
|
||||
return Result(ErrCodes::CommandTooLarge, ErrorModule::OS,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Status);
|
||||
}
|
||||
|
||||
for (u32 j = 0; j < num_handles; ++j) {
|
||||
|
|
@ -88,8 +87,8 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy
|
|||
continue;
|
||||
}
|
||||
|
||||
auto result = dst_process->handle_table.Create(std::move(object));
|
||||
cmd_buf[i++] = result.ValueOr(0);
|
||||
R_ASSERT(dst_process->handle_table.Create(std::addressof(cmd_buf[i++]),
|
||||
std::move(object)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -180,10 +179,10 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy
|
|||
next_vma.meminfo_state == MemoryState::Reserved);
|
||||
|
||||
// Unmap the buffer and guard pages from the source process
|
||||
ResultCode result =
|
||||
Result result =
|
||||
src_process->vm_manager.UnmapRange(page_start - Memory::CITRA_PAGE_SIZE,
|
||||
(num_pages + 2) * Memory::CITRA_PAGE_SIZE);
|
||||
ASSERT(result == RESULT_SUCCESS);
|
||||
ASSERT(result == ResultSuccess);
|
||||
|
||||
mapped_buffer_context.erase(found);
|
||||
|
||||
|
|
@ -216,11 +215,11 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy
|
|||
ASSERT(dst_process->vm_manager.ChangeMemoryState(
|
||||
low_guard_address, Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Shared,
|
||||
Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Reserved,
|
||||
Kernel::VMAPermission::None) == RESULT_SUCCESS);
|
||||
Kernel::VMAPermission::None) == ResultSuccess);
|
||||
ASSERT(dst_process->vm_manager.ChangeMemoryState(
|
||||
high_guard_address, Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Shared,
|
||||
Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Reserved,
|
||||
Kernel::VMAPermission::None) == RESULT_SUCCESS);
|
||||
Kernel::VMAPermission::None) == ResultSuccess);
|
||||
|
||||
// Get proper mapped buffer address and store it in the cmd buffer.
|
||||
target_address += Memory::CITRA_PAGE_SIZE;
|
||||
|
|
@ -249,6 +248,6 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy
|
|||
|
||||
memory.WriteBlock(*dst_process, dst_address, cmd_buf.data(), command_size * sizeof(u32));
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
} // namespace Kernel
|
||||
|
|
|
|||
|
|
@ -40,10 +40,9 @@ private:
|
|||
};
|
||||
|
||||
/// Performs IPC command buffer translation from one process to another.
|
||||
ResultCode TranslateCommandBuffer(KernelSystem& system, Memory::MemorySystem& memory,
|
||||
std::shared_ptr<Thread> src_thread,
|
||||
std::shared_ptr<Thread> dst_thread, VAddr src_address,
|
||||
VAddr dst_address,
|
||||
std::vector<MappedBufferContext>& mapped_buffer_context,
|
||||
bool reply);
|
||||
Result TranslateCommandBuffer(KernelSystem& system, Memory::MemorySystem& memory,
|
||||
std::shared_ptr<Thread> src_thread,
|
||||
std::shared_ptr<Thread> dst_thread, VAddr src_address,
|
||||
VAddr dst_address,
|
||||
std::vector<MappedBufferContext>& mapped_buffer_context, bool reply);
|
||||
} // namespace Kernel
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ void Mutex::Acquire(Thread* thread) {
|
|||
lock_count++;
|
||||
}
|
||||
|
||||
ResultCode Mutex::Release(Thread* thread) {
|
||||
Result Mutex::Release(Thread* thread) {
|
||||
// We can only release the mutex if it's held by the calling thread.
|
||||
if (thread != holding_thread.get()) {
|
||||
if (holding_thread) {
|
||||
|
|
@ -75,15 +75,15 @@ ResultCode Mutex::Release(Thread* thread) {
|
|||
"Tried to release a mutex (owned by thread id {}) from a different thread id {}",
|
||||
holding_thread->thread_id, thread->thread_id);
|
||||
}
|
||||
return ResultCode(ErrCodes::WrongLockingThread, ErrorModule::Kernel,
|
||||
ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
|
||||
return Result(ErrCodes::WrongLockingThread, ErrorModule::Kernel,
|
||||
ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
|
||||
}
|
||||
|
||||
// Note: It should not be possible for the situation where the mutex has a holding thread with a
|
||||
// zero lock count to occur. The real kernel still checks for this, so we do too.
|
||||
if (lock_count <= 0)
|
||||
return ResultCode(ErrorDescription::InvalidResultValue, ErrorModule::Kernel,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Permanent);
|
||||
return Result(ErrorDescription::InvalidResultValue, ErrorModule::Kernel,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Permanent);
|
||||
|
||||
lock_count--;
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ ResultCode Mutex::Release(Thread* thread) {
|
|||
kernel.PrepareReschedule();
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
void Mutex::AddWaitingThread(std::shared_ptr<Thread> thread) {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ public:
|
|||
* @param thread Thread that wants to release the mutex.
|
||||
* @returns The result code of the operation.
|
||||
*/
|
||||
ResultCode Release(Thread* thread);
|
||||
Result Release(Thread* thread);
|
||||
|
||||
private:
|
||||
KernelSystem& kernel;
|
||||
|
|
|
|||
|
|
@ -192,9 +192,12 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) {
|
|||
return;
|
||||
}
|
||||
|
||||
VAddr out_addr{};
|
||||
|
||||
auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
|
||||
MemoryState memory_state) {
|
||||
HeapAllocate(segment.addr, segment.size, permissions, memory_state, true);
|
||||
HeapAllocate(std::addressof(out_addr), segment.addr, segment.size, permissions,
|
||||
memory_state, true);
|
||||
kernel.memory.WriteBlock(*this, segment.addr, codeset->memory.data() + segment.offset,
|
||||
segment.size);
|
||||
};
|
||||
|
|
@ -205,8 +208,8 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) {
|
|||
MapSegment(codeset->DataSegment(), VMAPermission::ReadWrite, MemoryState::Private);
|
||||
|
||||
// Allocate and map stack
|
||||
HeapAllocate(Memory::HEAP_VADDR_END - stack_size, stack_size, VMAPermission::ReadWrite,
|
||||
MemoryState::Locked, true);
|
||||
HeapAllocate(std::addressof(out_addr), Memory::HEAP_VADDR_END - stack_size, stack_size,
|
||||
VMAPermission::ReadWrite, MemoryState::Locked, true);
|
||||
|
||||
// Map special address mappings
|
||||
kernel.MapSharedPages(vm_manager);
|
||||
|
|
@ -246,14 +249,14 @@ VAddr Process::GetLinearHeapLimit() const {
|
|||
return GetLinearHeapBase() + memory_region->size;
|
||||
}
|
||||
|
||||
ResultVal<VAddr> Process::HeapAllocate(VAddr target, u32 size, VMAPermission perms,
|
||||
MemoryState memory_state, bool skip_range_check) {
|
||||
Result Process::HeapAllocate(VAddr* out_addr, VAddr target, u32 size, VMAPermission perms,
|
||||
MemoryState memory_state, bool skip_range_check) {
|
||||
LOG_DEBUG(Kernel, "Allocate heap target={:08X}, size={:08X}", target, size);
|
||||
if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END ||
|
||||
target + size < target) {
|
||||
if (!skip_range_check) {
|
||||
LOG_ERROR(Kernel, "Invalid heap address");
|
||||
return ERR_INVALID_ADDRESS;
|
||||
return ResultInvalidAddress;
|
||||
}
|
||||
}
|
||||
{
|
||||
|
|
@ -261,13 +264,13 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u32 size, VMAPermission per
|
|||
if (vma->second.type != VMAType::Free ||
|
||||
vma->second.base + vma->second.size < target + size) {
|
||||
LOG_ERROR(Kernel, "Trying to allocate already allocated memory");
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
return ResultInvalidAddressState;
|
||||
}
|
||||
}
|
||||
auto allocated_fcram = memory_region->HeapAllocate(size);
|
||||
if (allocated_fcram.empty()) {
|
||||
LOG_ERROR(Kernel, "Not enough space");
|
||||
return ERR_OUT_OF_HEAP_MEMORY;
|
||||
return ResultOutOfHeapMemory;
|
||||
}
|
||||
|
||||
// Maps heap block by block
|
||||
|
|
@ -290,20 +293,19 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u32 size, VMAPermission per
|
|||
memory_used += size;
|
||||
resource_limit->Reserve(ResourceLimitType::Commit, size);
|
||||
|
||||
return target;
|
||||
*out_addr = target;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
ResultCode Process::HeapFree(VAddr target, u32 size) {
|
||||
Result Process::HeapFree(VAddr target, u32 size) {
|
||||
LOG_DEBUG(Kernel, "Free heap target={:08X}, size={:08X}", target, size);
|
||||
if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END ||
|
||||
target + size < target) {
|
||||
LOG_ERROR(Kernel, "Invalid heap address");
|
||||
return ERR_INVALID_ADDRESS;
|
||||
return ResultInvalidAddress;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
R_SUCCEED_IF(size == 0);
|
||||
|
||||
// Free heaps block by block
|
||||
CASCADE_RESULT(auto backing_blocks, vm_manager.GetBackingBlocksForRange(target, size));
|
||||
|
|
@ -313,23 +315,23 @@ ResultCode Process::HeapFree(VAddr target, u32 size) {
|
|||
holding_memory -= MemoryRegionInfo::Interval(backing_offset, backing_offset + block_size);
|
||||
}
|
||||
|
||||
ResultCode result = vm_manager.UnmapRange(target, size);
|
||||
Result result = vm_manager.UnmapRange(target, size);
|
||||
ASSERT(result.IsSuccess());
|
||||
|
||||
memory_used -= size;
|
||||
resource_limit->Release(ResourceLimitType::Commit, size);
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission perms) {
|
||||
Result Process::LinearAllocate(VAddr* out_addr, VAddr target, u32 size, VMAPermission perms) {
|
||||
LOG_DEBUG(Kernel, "Allocate linear heap target={:08X}, size={:08X}", target, size);
|
||||
u32 physical_offset;
|
||||
if (target == 0) {
|
||||
auto offset = memory_region->LinearAllocate(size);
|
||||
if (!offset) {
|
||||
LOG_ERROR(Kernel, "Not enough space");
|
||||
return ERR_OUT_OF_HEAP_MEMORY;
|
||||
return ResultOutOfHeapMemory;
|
||||
}
|
||||
physical_offset = *offset;
|
||||
target = physical_offset + GetLinearHeapAreaAddress();
|
||||
|
|
@ -337,7 +339,7 @@ ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission p
|
|||
if (target < GetLinearHeapBase() || target + size > GetLinearHeapLimit() ||
|
||||
target + size < target) {
|
||||
LOG_ERROR(Kernel, "Invalid linear heap address");
|
||||
return ERR_INVALID_ADDRESS;
|
||||
return ResultInvalidAddress;
|
||||
}
|
||||
|
||||
// Kernel would crash/return error when target doesn't meet some requirement.
|
||||
|
|
@ -350,7 +352,7 @@ ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission p
|
|||
physical_offset = target - GetLinearHeapAreaAddress(); // relative to FCRAM
|
||||
if (!memory_region->LinearAllocate(physical_offset, size)) {
|
||||
LOG_ERROR(Kernel, "Trying to allocate already allocated memory");
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
return ResultInvalidAddressState;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -366,26 +368,20 @@ ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission p
|
|||
resource_limit->Reserve(ResourceLimitType::Commit, size);
|
||||
|
||||
LOG_DEBUG(Kernel, "Allocated at target={:08X}", target);
|
||||
return target;
|
||||
*out_addr = target;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
ResultCode Process::LinearFree(VAddr target, u32 size) {
|
||||
Result Process::LinearFree(VAddr target, u32 size) {
|
||||
LOG_DEBUG(Kernel, "Free linear heap target={:08X}, size={:08X}", target, size);
|
||||
if (target < GetLinearHeapBase() || target + size > GetLinearHeapLimit() ||
|
||||
target + size < target) {
|
||||
LOG_ERROR(Kernel, "Invalid linear heap address");
|
||||
return ERR_INVALID_ADDRESS;
|
||||
return ResultInvalidAddress;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ResultCode result = vm_manager.UnmapRange(target, size);
|
||||
if (result.IsError()) {
|
||||
LOG_ERROR(Kernel, "Trying to free already freed memory");
|
||||
return result;
|
||||
}
|
||||
R_SUCCEED_IF(size == 0);
|
||||
R_TRY(vm_manager.UnmapRange(target, size));
|
||||
|
||||
u32 physical_offset = target - GetLinearHeapAreaAddress(); // relative to FCRAM
|
||||
memory_region->Free(physical_offset, size);
|
||||
|
|
@ -394,7 +390,7 @@ ResultCode Process::LinearFree(VAddr target, u32 size) {
|
|||
memory_used -= size;
|
||||
resource_limit->Release(ResourceLimitType::Commit, size);
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
ResultVal<VAddr> Process::AllocateThreadLocalStorage() {
|
||||
|
|
@ -435,7 +431,7 @@ ResultVal<VAddr> Process::AllocateThreadLocalStorage() {
|
|||
if (!offset) {
|
||||
LOG_ERROR(Kernel_SVC,
|
||||
"Not enough space in BASE linear region to allocate a new TLS page");
|
||||
return ERR_OUT_OF_MEMORY;
|
||||
return ResultOutOfMemory;
|
||||
}
|
||||
|
||||
holding_tls_memory +=
|
||||
|
|
@ -467,14 +463,13 @@ ResultVal<VAddr> Process::AllocateThreadLocalStorage() {
|
|||
return tls_address;
|
||||
}
|
||||
|
||||
ResultCode Process::Map(VAddr target, VAddr source, u32 size, VMAPermission perms,
|
||||
bool privileged) {
|
||||
Result Process::Map(VAddr target, VAddr source, u32 size, VMAPermission perms, bool privileged) {
|
||||
LOG_DEBUG(Kernel, "Map memory target={:08X}, source={:08X}, size={:08X}, perms={:08X}", target,
|
||||
source, size, perms);
|
||||
if (!privileged && (source < Memory::HEAP_VADDR || source + size > Memory::HEAP_VADDR_END ||
|
||||
source + size < source)) {
|
||||
LOG_ERROR(Kernel, "Invalid source address");
|
||||
return ERR_INVALID_ADDRESS;
|
||||
return ResultInvalidAddress;
|
||||
}
|
||||
|
||||
// TODO(wwylele): check target address range. Is it also restricted to heap region?
|
||||
|
|
@ -489,17 +484,17 @@ ResultCode Process::Map(VAddr target, VAddr source, u32 size, VMAPermission perm
|
|||
VMAPermission::ReadWrite,
|
||||
MemoryState::AliasCode, perms);
|
||||
} else {
|
||||
return ERR_INVALID_ADDRESS;
|
||||
return ResultInvalidAddress;
|
||||
}
|
||||
} else {
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
return ResultInvalidAddressState;
|
||||
}
|
||||
}
|
||||
|
||||
auto vma = vm_manager.FindVMA(target);
|
||||
if (vma->second.type != VMAType::Free || vma->second.base + vma->second.size < target + size) {
|
||||
LOG_ERROR(Kernel, "Trying to map to already allocated memory");
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
return ResultInvalidAddressState;
|
||||
}
|
||||
|
||||
MemoryState source_state = privileged ? MemoryState::Locked : MemoryState::Aliased;
|
||||
|
|
@ -507,8 +502,8 @@ ResultCode Process::Map(VAddr target, VAddr source, u32 size, VMAPermission perm
|
|||
VMAPermission source_perm = privileged ? VMAPermission::None : VMAPermission::ReadWrite;
|
||||
|
||||
// Mark source region as Aliased
|
||||
CASCADE_CODE(vm_manager.ChangeMemoryState(source, size, MemoryState::Private,
|
||||
VMAPermission::ReadWrite, source_state, source_perm));
|
||||
R_TRY(vm_manager.ChangeMemoryState(source, size, MemoryState::Private, VMAPermission::ReadWrite,
|
||||
source_state, source_perm));
|
||||
|
||||
CASCADE_RESULT(auto backing_blocks, vm_manager.GetBackingBlocksForRange(source, size));
|
||||
VAddr interval_target = target;
|
||||
|
|
@ -520,16 +515,15 @@ ResultCode Process::Map(VAddr target, VAddr source, u32 size, VMAPermission perm
|
|||
interval_target += block_size;
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission perms,
|
||||
bool privileged) {
|
||||
Result Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission perms, bool privileged) {
|
||||
LOG_DEBUG(Kernel, "Unmap memory target={:08X}, source={:08X}, size={:08X}, perms={:08X}",
|
||||
target, source, size, perms);
|
||||
if (!privileged && (source < Memory::HEAP_VADDR || source + size > Memory::HEAP_VADDR_END ||
|
||||
source + size < source)) {
|
||||
LOG_ERROR(Kernel, "Invalid source address");
|
||||
return ERR_INVALID_ADDRESS;
|
||||
return ResultInvalidAddress;
|
||||
}
|
||||
|
||||
// TODO(wwylele): check target address range. Is it also restricted to heap region?
|
||||
|
|
@ -543,10 +537,10 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe
|
|||
VMAPermission::None, MemoryState::Private,
|
||||
perms);
|
||||
} else {
|
||||
return ERR_INVALID_ADDRESS;
|
||||
return ResultInvalidAddress;
|
||||
}
|
||||
} else {
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
return ResultInvalidAddressState;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -555,13 +549,13 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe
|
|||
|
||||
MemoryState source_state = privileged ? MemoryState::Locked : MemoryState::Aliased;
|
||||
|
||||
CASCADE_CODE(vm_manager.UnmapRange(target, size));
|
||||
R_TRY(vm_manager.UnmapRange(target, size));
|
||||
|
||||
// Change back source region state. Note that the permission is reprotected according to param
|
||||
CASCADE_CODE(vm_manager.ChangeMemoryState(source, size, source_state, VMAPermission::None,
|
||||
MemoryState::Private, perms));
|
||||
R_TRY(vm_manager.ChangeMemoryState(source, size, source_state, VMAPermission::None,
|
||||
MemoryState::Private, perms));
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
void Process::FreeAllMemory() {
|
||||
|
|
|
|||
|
|
@ -231,20 +231,19 @@ public:
|
|||
VAddr GetLinearHeapBase() const;
|
||||
VAddr GetLinearHeapLimit() const;
|
||||
|
||||
ResultVal<VAddr> HeapAllocate(VAddr target, u32 size, VMAPermission perms,
|
||||
MemoryState memory_state = MemoryState::Private,
|
||||
bool skip_range_check = false);
|
||||
ResultCode HeapFree(VAddr target, u32 size);
|
||||
Result HeapAllocate(VAddr* out_addr, VAddr target, u32 size, VMAPermission perms,
|
||||
MemoryState memory_state = MemoryState::Private,
|
||||
bool skip_range_check = false);
|
||||
Result HeapFree(VAddr target, u32 size);
|
||||
|
||||
ResultVal<VAddr> LinearAllocate(VAddr target, u32 size, VMAPermission perms);
|
||||
ResultCode LinearFree(VAddr target, u32 size);
|
||||
Result LinearAllocate(VAddr* out_addr, VAddr target, u32 size, VMAPermission perms);
|
||||
Result LinearFree(VAddr target, u32 size);
|
||||
|
||||
ResultVal<VAddr> AllocateThreadLocalStorage();
|
||||
|
||||
ResultCode Map(VAddr target, VAddr source, u32 size, VMAPermission perms,
|
||||
bool privileged = false);
|
||||
ResultCode Unmap(VAddr target, VAddr source, u32 size, VMAPermission perms,
|
||||
bool privileged = false);
|
||||
Result Map(VAddr target, VAddr source, u32 size, VMAPermission perms, bool privileged = false);
|
||||
Result Unmap(VAddr target, VAddr source, u32 size, VMAPermission perms,
|
||||
bool privileged = false);
|
||||
|
||||
private:
|
||||
void FreeAllMemory();
|
||||
|
|
|
|||
|
|
@ -26,9 +26,7 @@ ResultVal<std::shared_ptr<Semaphore>> KernelSystem::CreateSemaphore(s32 initial_
|
|||
s32 max_count,
|
||||
std::string name) {
|
||||
|
||||
if (initial_count > max_count) {
|
||||
return ERR_INVALID_COMBINATION_KERNEL;
|
||||
}
|
||||
R_UNLESS(initial_count <= max_count, ResultInvalidCombinationKernel);
|
||||
|
||||
// When the semaphore is created, some slots are reserved for other threads,
|
||||
// and the rest is reserved for the caller thread
|
||||
|
|
@ -44,21 +42,20 @@ bool Semaphore::ShouldWait(const Thread* thread) const {
|
|||
}
|
||||
|
||||
void Semaphore::Acquire(Thread* thread) {
|
||||
if (available_count <= 0)
|
||||
if (available_count <= 0) {
|
||||
return;
|
||||
}
|
||||
--available_count;
|
||||
}
|
||||
|
||||
ResultVal<s32> Semaphore::Release(s32 release_count) {
|
||||
if (max_count - available_count < release_count)
|
||||
return ERR_OUT_OF_RANGE_KERNEL;
|
||||
Result Semaphore::Release(s32* out_count, s32 release_count) {
|
||||
R_UNLESS(max_count >= release_count + available_count, ResultOutOfRangeKernel);
|
||||
|
||||
s32 previous_count = available_count;
|
||||
*out_count = available_count;
|
||||
available_count += release_count;
|
||||
|
||||
WakeupAllWaitingThreads();
|
||||
|
||||
return previous_count;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
} // namespace Kernel
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public:
|
|||
* @param release_count The number of slots to release
|
||||
* @return The number of free slots the semaphore had before this call
|
||||
*/
|
||||
ResultVal<s32> Release(s32 release_count);
|
||||
Result Release(s32* out_count, s32 release_count);
|
||||
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
|
|
|
|||
|
|
@ -24,14 +24,12 @@ namespace Kernel {
|
|||
ServerPort::ServerPort(KernelSystem& kernel) : WaitObject(kernel) {}
|
||||
ServerPort::~ServerPort() {}
|
||||
|
||||
ResultVal<std::shared_ptr<ServerSession>> ServerPort::Accept() {
|
||||
if (pending_sessions.empty()) {
|
||||
return ERR_NO_PENDING_SESSIONS;
|
||||
}
|
||||
Result ServerPort::Accept(std::shared_ptr<ServerSession>* out_server_session) {
|
||||
R_UNLESS(!pending_sessions.empty(), ResultNoPendingSessions);
|
||||
|
||||
auto session = std::move(pending_sessions.back());
|
||||
*out_server_session = std::move(pending_sessions.back());
|
||||
pending_sessions.pop_back();
|
||||
return session;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
bool ServerPort::ShouldWait(const Thread* thread) const {
|
||||
|
|
|
|||
|
|
@ -39,9 +39,9 @@ public:
|
|||
|
||||
/**
|
||||
* Accepts a pending incoming connection on this port. If there are no pending sessions, will
|
||||
* return ERR_NO_PENDING_SESSIONS.
|
||||
* return ResultNoPendingSessions.
|
||||
*/
|
||||
ResultVal<std::shared_ptr<ServerSession>> Accept();
|
||||
Result Accept(std::shared_ptr<ServerSession>* out_server_session);
|
||||
|
||||
/**
|
||||
* Sets the HLE handler template for the port. ServerSessions crated by connecting to this port
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ void ServerSession::Acquire(Thread* thread) {
|
|||
pending_requesting_threads.pop_back();
|
||||
}
|
||||
|
||||
ResultCode ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread) {
|
||||
Result ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread) {
|
||||
// The ServerSession received a sync request, this means that there's new data available
|
||||
// from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or
|
||||
// similar.
|
||||
|
|
@ -136,7 +136,7 @@ ResultCode ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread) {
|
|||
// If this ServerSession does not have an HLE implementation, just wake up the threads waiting
|
||||
// on it.
|
||||
WakeupAllWaitingThreads();
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
KernelSystem::SessionPair KernelSystem::CreateSessionPair(const std::string& name,
|
||||
|
|
|
|||
|
|
@ -66,9 +66,9 @@ public:
|
|||
/**
|
||||
* Handle a sync request from the emulated application.
|
||||
* @param thread Thread that initiated the request.
|
||||
* @returns ResultCode from the operation.
|
||||
* @returns Result from the operation.
|
||||
*/
|
||||
ResultCode HandleSyncRequest(std::shared_ptr<Thread> thread);
|
||||
Result HandleSyncRequest(std::shared_ptr<Thread> thread);
|
||||
|
||||
bool ShouldWait(const Thread* thread) const override;
|
||||
|
||||
|
|
|
|||
|
|
@ -67,9 +67,9 @@ ResultVal<std::shared_ptr<SharedMemory>> KernelSystem::CreateSharedMemory(
|
|||
auto& vm_manager = owner_process->vm_manager;
|
||||
// The memory is already available and mapped in the owner process.
|
||||
|
||||
CASCADE_CODE(vm_manager.ChangeMemoryState(address, size, MemoryState::Private,
|
||||
VMAPermission::ReadWrite, MemoryState::Locked,
|
||||
SharedMemory::ConvertPermissions(permissions)));
|
||||
R_TRY(vm_manager.ChangeMemoryState(address, size, MemoryState::Private,
|
||||
VMAPermission::ReadWrite, MemoryState::Locked,
|
||||
SharedMemory::ConvertPermissions(permissions)));
|
||||
|
||||
auto backing_blocks = vm_manager.GetBackingBlocksForRange(address, size);
|
||||
ASSERT(backing_blocks.Succeeded()); // should success after verifying memory state above
|
||||
|
|
@ -107,29 +107,29 @@ std::shared_ptr<SharedMemory> KernelSystem::CreateSharedMemoryForApplet(
|
|||
return shared_memory;
|
||||
}
|
||||
|
||||
ResultCode SharedMemory::Map(Process& target_process, VAddr address, MemoryPermission permissions,
|
||||
MemoryPermission other_permissions) {
|
||||
Result SharedMemory::Map(Process& target_process, VAddr address, MemoryPermission permissions,
|
||||
MemoryPermission other_permissions) {
|
||||
|
||||
MemoryPermission own_other_permissions =
|
||||
&target_process == owner_process.lock().get() ? 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 ResultInvalidCombination;
|
||||
}
|
||||
|
||||
// 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{:08X} name={}, permissions don't match",
|
||||
GetObjectId(), address, name);
|
||||
return ERR_INVALID_COMBINATION;
|
||||
return ResultInvalidCombination;
|
||||
}
|
||||
|
||||
// Heap-backed memory blocks can not be mapped with other_permissions = DontCare
|
||||
if (base_address != 0 && other_permissions == MemoryPermission::DontCare) {
|
||||
LOG_ERROR(Kernel, "cannot map id={}, address=0x{08X} name={}, permissions don't match",
|
||||
GetObjectId(), address, name);
|
||||
return ERR_INVALID_COMBINATION;
|
||||
return ResultInvalidCombination;
|
||||
}
|
||||
|
||||
// Error out if the provided permissions are not compatible with what the creator process needs.
|
||||
|
|
@ -137,12 +137,12 @@ ResultCode SharedMemory::Map(Process& target_process, VAddr address, MemoryPermi
|
|||
static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) {
|
||||
LOG_ERROR(Kernel, "cannot map id={}, address=0x{:08X} name={}, permissions don't match",
|
||||
GetObjectId(), address, name);
|
||||
return ERR_WRONG_PERMISSION;
|
||||
return ResultWrongPermission;
|
||||
}
|
||||
|
||||
// TODO(Subv): Check for the Shared Device Mem flag in the creator process.
|
||||
/*if (was_created_with_shared_device_mem && address != 0) {
|
||||
return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS,
|
||||
return Result(ErrorDescription::InvalidCombination, ErrorModule::OS,
|
||||
ErrorSummary::InvalidArgument, ErrorLevel::Usage);
|
||||
}*/
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ ResultCode SharedMemory::Map(Process& target_process, VAddr address, MemoryPermi
|
|||
if (address < Memory::HEAP_VADDR || address + size >= Memory::SHARED_MEMORY_VADDR_END) {
|
||||
LOG_ERROR(Kernel, "cannot map id={}, address=0x{:08X} name={}, invalid address",
|
||||
GetObjectId(), address, name);
|
||||
return ERR_INVALID_ADDRESS;
|
||||
return ResultInvalidAddress;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ ResultCode SharedMemory::Map(Process& target_process, VAddr address, MemoryPermi
|
|||
Kernel,
|
||||
"cannot map id={}, address=0x{:08X} name={}, mapping to already allocated memory",
|
||||
GetObjectId(), address, name);
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
return ResultInvalidAddressState;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -188,10 +188,10 @@ ResultCode SharedMemory::Map(Process& target_process, VAddr address, MemoryPermi
|
|||
interval_target += interval.second;
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
ResultCode SharedMemory::Unmap(Process& target_process, VAddr address) {
|
||||
Result SharedMemory::Unmap(Process& target_process, VAddr address) {
|
||||
// TODO(Subv): Verify what happens if the application tries to unmap an address that is not
|
||||
// mapped to a SharedMemory.
|
||||
return target_process.vm_manager.UnmapRange(address, size);
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@ public:
|
|||
* @param permissions Memory block map permissions (specified by SVC field)
|
||||
* @param other_permissions Memory block map other permissions (specified by SVC field)
|
||||
*/
|
||||
ResultCode Map(Process& target_process, VAddr address, MemoryPermission permissions,
|
||||
MemoryPermission other_permissions);
|
||||
Result Map(Process& target_process, VAddr address, MemoryPermission permissions,
|
||||
MemoryPermission other_permissions);
|
||||
|
||||
/**
|
||||
* Unmaps a shared memory block from the specified address in system memory
|
||||
|
|
@ -70,7 +70,7 @@ public:
|
|||
* @param address Address in system memory where the shared memory block is mapped
|
||||
* @return Result code of the unmap operation
|
||||
*/
|
||||
ResultCode Unmap(Process& target_process, VAddr address);
|
||||
Result Unmap(Process& target_process, VAddr address);
|
||||
|
||||
/**
|
||||
* Gets a pointer to the shared memory block
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -281,21 +281,21 @@ private:
|
|||
};
|
||||
|
||||
template <typename SVCT>
|
||||
struct WrapPass<SVCT, ResultCode /*empty for T, Ts...*/> {
|
||||
struct WrapPass<SVCT, Result /*empty for T, Ts...*/> {
|
||||
// Call function R(Context::svc)(Us...) and transfer the return value to registers
|
||||
template <typename... Us>
|
||||
static void Call(Context& context, SVCT svc, Us... u) {
|
||||
static_assert(std::is_same_v<SVCT, ResultCode (Context::*)(Us...)>);
|
||||
if constexpr (std::is_void_v<ResultCode>) {
|
||||
static_assert(std::is_same_v<SVCT, Result (Context::*)(Us...)>);
|
||||
if constexpr (std::is_void_v<Result>) {
|
||||
(context.*svc)(u...);
|
||||
} else {
|
||||
ResultCode r = (context.*svc)(u...);
|
||||
Result r = (context.*svc)(u...);
|
||||
if (r.IsError()) {
|
||||
LOG_ERROR(Kernel_SVC, "level={} summary={} module={} description={}",
|
||||
r.level.ExtractValue(r.raw), r.summary.ExtractValue(r.raw),
|
||||
r.module.ExtractValue(r.raw), r.description.ExtractValue(r.raw));
|
||||
}
|
||||
SetParam<INDEX_RETURN, ResultCode, ResultCode, Us...>(context, r);
|
||||
SetParam<INDEX_RETURN, Result, Result, Us...>(context, r);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -332,20 +332,20 @@ ResultVal<std::shared_ptr<Thread>> KernelSystem::CreateThread(
|
|||
// Check if priority is in ranged. Lowest priority -> highest priority id.
|
||||
if (priority > ThreadPrioLowest) {
|
||||
LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority);
|
||||
return ERR_OUT_OF_RANGE;
|
||||
return ResultOutOfRange;
|
||||
}
|
||||
|
||||
if (processor_id > ThreadProcessorIdMax) {
|
||||
LOG_ERROR(Kernel_SVC, "Invalid processor id: {}", processor_id);
|
||||
return ERR_OUT_OF_RANGE_KERNEL;
|
||||
return ResultOutOfRangeKernel;
|
||||
}
|
||||
|
||||
// TODO(yuriks): Other checks, returning 0xD9001BEA
|
||||
if (!memory.IsValidVirtualAddress(*owner_process, entry_point)) {
|
||||
LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:08x}", name, entry_point);
|
||||
// TODO: Verify error
|
||||
return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel,
|
||||
ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
|
||||
return Result(ErrorDescription::InvalidAddress, ErrorModule::Kernel,
|
||||
ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
|
||||
}
|
||||
|
||||
auto thread = std::make_shared<Thread>(*this, processor_id);
|
||||
|
|
@ -445,7 +445,7 @@ void ThreadManager::Reschedule() {
|
|||
SwitchContext(next);
|
||||
}
|
||||
|
||||
void Thread::SetWaitSynchronizationResult(ResultCode result) {
|
||||
void Thread::SetWaitSynchronizationResult(Result result) {
|
||||
context.cpu_registers[0] = result.raw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ public:
|
|||
* Sets the result after the thread awakens (from either WaitSynchronization SVC)
|
||||
* @param result Value to set to the returned result
|
||||
*/
|
||||
void SetWaitSynchronizationResult(ResultCode result);
|
||||
void SetWaitSynchronizationResult(Result result);
|
||||
|
||||
/**
|
||||
* Sets the output parameter value after the thread awakens (from WaitSynchronizationN SVC only)
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ ResultVal<VAddr> VMManager::MapBackingMemoryToBase(VAddr base, u32 region_size,
|
|||
// Do not try to allocate the block if there are no available addresses within the desired
|
||||
// region.
|
||||
if (vma_handle == vma_map.end() || target + size > base + region_size) {
|
||||
return ResultCode(ErrorDescription::OutOfMemory, ErrorModule::Kernel,
|
||||
ErrorSummary::OutOfResource, ErrorLevel::Permanent);
|
||||
return Result(ErrorDescription::OutOfMemory, ErrorModule::Kernel,
|
||||
ErrorSummary::OutOfResource, ErrorLevel::Permanent);
|
||||
}
|
||||
|
||||
auto result = MapBackingMemory(target, memory, size, state);
|
||||
|
|
@ -114,11 +114,11 @@ ResultVal<VMManager::VMAHandle> VMManager::MapBackingMemory(VAddr target, Memory
|
|||
return MergeAdjacent(vma_handle);
|
||||
}
|
||||
|
||||
ResultCode VMManager::ChangeMemoryState(VAddr target, u32 size, MemoryState expected_state,
|
||||
VMAPermission expected_perms, MemoryState new_state,
|
||||
VMAPermission new_perms) {
|
||||
Result VMManager::ChangeMemoryState(VAddr target, u32 size, MemoryState expected_state,
|
||||
VMAPermission expected_perms, MemoryState new_state,
|
||||
VMAPermission new_perms) {
|
||||
if (is_locked) {
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
VAddr target_end = target + size;
|
||||
|
|
@ -126,16 +126,16 @@ ResultCode VMManager::ChangeMemoryState(VAddr target, u32 size, MemoryState expe
|
|||
VMAIter i_end = vma_map.lower_bound(target_end);
|
||||
|
||||
if (begin_vma == vma_map.end())
|
||||
return ERR_INVALID_ADDRESS;
|
||||
return ResultInvalidAddress;
|
||||
|
||||
for (auto i = begin_vma; i != i_end; ++i) {
|
||||
auto& vma = i->second;
|
||||
if (vma.meminfo_state != expected_state) {
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
return ResultInvalidAddressState;
|
||||
}
|
||||
u32 perms = static_cast<u32>(expected_perms);
|
||||
if ((static_cast<u32>(vma.permissions) & perms) != perms) {
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
return ResultInvalidAddressState;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -151,7 +151,7 @@ ResultCode VMManager::ChangeMemoryState(VAddr target, u32 size, MemoryState expe
|
|||
vma = std::next(MergeAdjacent(vma));
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
VMManager::VMAIter VMManager::Unmap(VMAIter vma_handle) {
|
||||
|
|
@ -168,7 +168,7 @@ VMManager::VMAIter VMManager::Unmap(VMAIter vma_handle) {
|
|||
return MergeAdjacent(vma_handle);
|
||||
}
|
||||
|
||||
ResultCode VMManager::UnmapRange(VAddr target, u32 size) {
|
||||
Result VMManager::UnmapRange(VAddr target, u32 size) {
|
||||
ASSERT(!is_locked);
|
||||
|
||||
CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size));
|
||||
|
|
@ -182,7 +182,7 @@ ResultCode VMManager::UnmapRange(VAddr target, u32 size) {
|
|||
}
|
||||
|
||||
ASSERT(FindVMA(target)->second.size >= size);
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
VMManager::VMAHandle VMManager::Reprotect(VMAHandle vma_handle, VMAPermission new_perms) {
|
||||
|
|
@ -197,7 +197,7 @@ VMManager::VMAHandle VMManager::Reprotect(VMAHandle vma_handle, VMAPermission ne
|
|||
return MergeAdjacent(iter);
|
||||
}
|
||||
|
||||
ResultCode VMManager::ReprotectRange(VAddr target, u32 size, VMAPermission new_perms) {
|
||||
Result VMManager::ReprotectRange(VAddr target, u32 size, VMAPermission new_perms) {
|
||||
ASSERT(!is_locked);
|
||||
|
||||
CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size));
|
||||
|
|
@ -210,7 +210,7 @@ ResultCode VMManager::ReprotectRange(VAddr target, u32 size, VMAPermission new_p
|
|||
vma = std::next(StripIterConstness(Reprotect(vma, new_perms)));
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
void VMManager::LogLayout(Common::Log::Level log_level) const {
|
||||
|
|
@ -242,13 +242,13 @@ ResultVal<VMManager::VMAIter> VMManager::CarveVMA(VAddr base, u32 size) {
|
|||
VMAIter vma_handle = StripIterConstness(FindVMA(base));
|
||||
if (vma_handle == vma_map.end()) {
|
||||
// Target address is outside the range managed by the kernel
|
||||
return ERR_INVALID_ADDRESS;
|
||||
return ResultInvalidAddress;
|
||||
}
|
||||
|
||||
const VirtualMemoryArea& vma = vma_handle->second;
|
||||
if (vma.type != VMAType::Free) {
|
||||
// Region is already allocated
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
return ResultInvalidAddressState;
|
||||
}
|
||||
|
||||
const VAddr start_in_vma = base - vma.base;
|
||||
|
|
@ -256,7 +256,7 @@ ResultVal<VMManager::VMAIter> VMManager::CarveVMA(VAddr base, u32 size) {
|
|||
|
||||
if (end_in_vma > vma.size) {
|
||||
// Requested allocation doesn't fit inside VMA
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
return ResultInvalidAddressState;
|
||||
}
|
||||
|
||||
if (end_in_vma != vma.size) {
|
||||
|
|
@ -284,7 +284,7 @@ ResultVal<VMManager::VMAIter> VMManager::CarveVMARange(VAddr target, u32 size) {
|
|||
const VMAIter i_end = vma_map.lower_bound(target_end);
|
||||
if (std::any_of(begin_vma, i_end,
|
||||
[](const auto& entry) { return entry.second.type == VMAType::Free; })) {
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
return ResultInvalidAddressState;
|
||||
}
|
||||
|
||||
if (target != begin_vma->second.base) {
|
||||
|
|
@ -367,7 +367,7 @@ ResultVal<std::vector<std::pair<MemoryRef, u32>>> VMManager::GetBackingBlocksFor
|
|||
auto vma = FindVMA(interval_target);
|
||||
if (vma->second.type != VMAType::BackingMemory) {
|
||||
LOG_ERROR(Kernel, "Trying to use already freed memory");
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
return ResultInvalidAddressState;
|
||||
}
|
||||
|
||||
VAddr interval_end = std::min(address + size, vma->second.base + vma->second.size);
|
||||
|
|
|
|||
|
|
@ -165,18 +165,18 @@ public:
|
|||
* @param new_state New MemoryState for the range.
|
||||
* @param new_perms New VMAPermission for the range.
|
||||
*/
|
||||
ResultCode ChangeMemoryState(VAddr target, u32 size, MemoryState expected_state,
|
||||
VMAPermission expected_perms, MemoryState new_state,
|
||||
VMAPermission new_perms);
|
||||
Result ChangeMemoryState(VAddr target, u32 size, MemoryState expected_state,
|
||||
VMAPermission expected_perms, MemoryState new_state,
|
||||
VMAPermission new_perms);
|
||||
|
||||
/// Unmaps a range of addresses, splitting VMAs as necessary.
|
||||
ResultCode UnmapRange(VAddr target, u32 size);
|
||||
Result UnmapRange(VAddr target, u32 size);
|
||||
|
||||
/// Changes the permissions of the given VMA.
|
||||
VMAHandle Reprotect(VMAHandle vma, VMAPermission new_perms);
|
||||
|
||||
/// Changes the permissions of a range of addresses, splitting VMAs as necessary.
|
||||
ResultCode ReprotectRange(VAddr target, u32 size, VMAPermission new_perms);
|
||||
Result ReprotectRange(VAddr target, u32 size, VMAPermission new_perms);
|
||||
|
||||
/// Dumps the address space layout to the log, for debugging
|
||||
void LogLayout(Common::Log::Level log_level) const;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue