SVC: Change return type of handlers to ResultCode
This commit is contained in:
		@@ -33,114 +33,109 @@ static inline void FuncReturn64(u64 res) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Function wrappers that return type s32
 | 
			
		||||
// Function wrappers that return type ResultCode
 | 
			
		||||
 | 
			
		||||
template<s32 func(u32, u32, u32, u32)> void Wrap() {
 | 
			
		||||
    FuncReturn(func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)));
 | 
			
		||||
template<ResultCode func(u32, u32, u32, u32)> void Wrap() {
 | 
			
		||||
    FuncReturn(func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)).raw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(u32, u32, u32, u32, u32)> void Wrap() {
 | 
			
		||||
    FuncReturn(func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)));
 | 
			
		||||
template<ResultCode func(u32, u32, u32, u32, u32)> void Wrap() {
 | 
			
		||||
    FuncReturn(func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(u32*, u32, u32, u32, u32, u32)> void Wrap(){
 | 
			
		||||
template<ResultCode func(u32*, u32, u32, u32, u32, u32)> void Wrap(){
 | 
			
		||||
    u32 param_1 = 0;
 | 
			
		||||
    u32 retval = func(¶m_1, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
 | 
			
		||||
    u32 retval = func(¶m_1, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw;
 | 
			
		||||
    Core::g_app_core->SetReg(1, param_1);
 | 
			
		||||
    FuncReturn(retval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(s32*, u32*, s32, bool, s64)> void Wrap() {
 | 
			
		||||
template<ResultCode func(s32*, u32*, s32, bool, s64)> void Wrap() {
 | 
			
		||||
    s32 param_1 = 0;
 | 
			
		||||
    s32 retval = func(¶m_1, (Handle*)Memory::GetPointer(PARAM(1)), (s32)PARAM(2),
 | 
			
		||||
        (PARAM(3) != 0), (((s64)PARAM(4) << 32) | PARAM(0)));
 | 
			
		||||
        (PARAM(3) != 0), (((s64)PARAM(4) << 32) | PARAM(0))).raw;
 | 
			
		||||
    Core::g_app_core->SetReg(1, (u32)param_1);
 | 
			
		||||
    FuncReturn(retval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO(bunnei): Is this correct? Probably not - Last parameter looks wrong for ArbitrateAddress
 | 
			
		||||
template<s32 func(u32, u32, u32, u32, s64)> void Wrap() {
 | 
			
		||||
    FuncReturn(func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), (((s64)PARAM(5) << 32) | PARAM(4))));
 | 
			
		||||
template<ResultCode func(u32, u32, u32, u32, s64)> void Wrap() {
 | 
			
		||||
    FuncReturn(func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), (((s64)PARAM(5) << 32) | PARAM(4))).raw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(u32*)> void Wrap(){
 | 
			
		||||
template<ResultCode func(u32*)> void Wrap(){
 | 
			
		||||
    u32 param_1 = 0;
 | 
			
		||||
    u32 retval = func(¶m_1);
 | 
			
		||||
    u32 retval = func(¶m_1).raw;
 | 
			
		||||
    Core::g_app_core->SetReg(1, param_1);
 | 
			
		||||
    FuncReturn(retval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(u32, s64)> void Wrap() {
 | 
			
		||||
    FuncReturn(func(PARAM(0), (((s64)PARAM(3) << 32) | PARAM(2))));
 | 
			
		||||
template<ResultCode func(u32, s64)> void Wrap() {
 | 
			
		||||
    FuncReturn(func(PARAM(0), (((s64)PARAM(3) << 32) | PARAM(2))).raw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(void*, void*, u32)> void Wrap(){
 | 
			
		||||
    FuncReturn(func(Memory::GetPointer(PARAM(0)), Memory::GetPointer(PARAM(1)), PARAM(2)));
 | 
			
		||||
template<ResultCode func(void*, void*, u32)> void Wrap(){
 | 
			
		||||
    FuncReturn(func(Memory::GetPointer(PARAM(0)), Memory::GetPointer(PARAM(1)), PARAM(2)).raw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(s32*, u32)> void Wrap(){
 | 
			
		||||
template<ResultCode func(s32*, u32)> void Wrap(){
 | 
			
		||||
    s32 param_1 = 0;
 | 
			
		||||
    u32 retval = func(¶m_1, PARAM(1));
 | 
			
		||||
    u32 retval = func(¶m_1, PARAM(1)).raw;
 | 
			
		||||
    Core::g_app_core->SetReg(1, param_1);
 | 
			
		||||
    FuncReturn(retval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(u32, s32)> void Wrap() {
 | 
			
		||||
    FuncReturn(func(PARAM(0), (s32)PARAM(1)));
 | 
			
		||||
template<ResultCode func(u32, s32)> void Wrap() {
 | 
			
		||||
    FuncReturn(func(PARAM(0), (s32)PARAM(1)).raw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(u32*, u32)> void Wrap(){
 | 
			
		||||
template<ResultCode func(u32*, u32)> void Wrap(){
 | 
			
		||||
    u32 param_1 = 0;
 | 
			
		||||
    u32 retval = func(¶m_1, PARAM(1));
 | 
			
		||||
    u32 retval = func(¶m_1, PARAM(1)).raw;
 | 
			
		||||
    Core::g_app_core->SetReg(1, param_1);
 | 
			
		||||
    FuncReturn(retval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(u32)> void Wrap() {
 | 
			
		||||
    FuncReturn(func(PARAM(0)));
 | 
			
		||||
template<ResultCode func(u32)> void Wrap() {
 | 
			
		||||
    FuncReturn(func(PARAM(0)).raw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(void*)> void Wrap() {
 | 
			
		||||
    FuncReturn(func(Memory::GetPointer(PARAM(0))));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(s64*, u32, void*, s32)> void Wrap(){
 | 
			
		||||
template<ResultCode func(s64*, u32, void*, s32)> void Wrap(){
 | 
			
		||||
    FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1), Memory::GetPointer(PARAM(2)),
 | 
			
		||||
        (s32)PARAM(3)));
 | 
			
		||||
        (s32)PARAM(3)).raw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(u32*, const char*)> void Wrap() {
 | 
			
		||||
template<ResultCode func(u32*, const char*)> void Wrap() {
 | 
			
		||||
    u32 param_1 = 0;
 | 
			
		||||
    u32 retval = func(¶m_1, Memory::GetCharPointer(PARAM(1)));
 | 
			
		||||
    u32 retval = func(¶m_1, Memory::GetCharPointer(PARAM(1))).raw;
 | 
			
		||||
    Core::g_app_core->SetReg(1, param_1);
 | 
			
		||||
    FuncReturn(retval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(u32*, s32, s32)> void Wrap() {
 | 
			
		||||
template<ResultCode func(u32*, s32, s32)> void Wrap() {
 | 
			
		||||
    u32 param_1 = 0;
 | 
			
		||||
    u32 retval = func(¶m_1, PARAM(1), PARAM(2));
 | 
			
		||||
    u32 retval = func(¶m_1, PARAM(1), PARAM(2)).raw;
 | 
			
		||||
    Core::g_app_core->SetReg(1, param_1);
 | 
			
		||||
    FuncReturn(retval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(s32*, u32, s32)> void Wrap() {
 | 
			
		||||
template<ResultCode func(s32*, u32, s32)> void Wrap() {
 | 
			
		||||
    s32 param_1 = 0;
 | 
			
		||||
    u32 retval = func(¶m_1, PARAM(1), PARAM(2));
 | 
			
		||||
    u32 retval = func(¶m_1, PARAM(1), PARAM(2)).raw;
 | 
			
		||||
    Core::g_app_core->SetReg(1, param_1);
 | 
			
		||||
    FuncReturn(retval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(u32*, u32, u32, u32, u32)> void Wrap() {
 | 
			
		||||
template<ResultCode func(u32*, u32, u32, u32, u32)> void Wrap() {
 | 
			
		||||
    u32 param_1 = 0;
 | 
			
		||||
    u32 retval = func(¶m_1, PARAM(1), PARAM(2), PARAM(3), PARAM(4));
 | 
			
		||||
    u32 retval = func(¶m_1, PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw;
 | 
			
		||||
    Core::g_app_core->SetReg(1, param_1);
 | 
			
		||||
    FuncReturn(retval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<s32 func(u32, s64, s64)> void Wrap() {
 | 
			
		||||
template<ResultCode func(u32, s64, s64)> void Wrap() {
 | 
			
		||||
    s64 param1 = ((u64)PARAM(3) << 32) | PARAM(2);
 | 
			
		||||
    s64 param2 = ((u64)PARAM(4) << 32) | PARAM(1);
 | 
			
		||||
    FuncReturn(func(PARAM(0), param1, param2));
 | 
			
		||||
    FuncReturn(func(PARAM(0), param1, param2).raw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,7 @@ enum ControlMemoryOperation {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Map application or GSP heap memory
 | 
			
		||||
static Result ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissions) {
 | 
			
		||||
static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissions) {
 | 
			
		||||
    LOG_TRACE(Kernel_SVC,"called operation=0x%08X, addr0=0x%08X, addr1=0x%08X, size=%08X, permissions=0x%08X",
 | 
			
		||||
        operation, addr0, addr1, size, permissions);
 | 
			
		||||
 | 
			
		||||
@@ -58,11 +58,11 @@ static Result ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 addr1,
 | 
			
		||||
    default:
 | 
			
		||||
        LOG_ERROR(Kernel_SVC, "unknown operation=0x%08X", operation);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Maps a memory block to specified address
 | 
			
		||||
static Result MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 other_permissions) {
 | 
			
		||||
static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 other_permissions) {
 | 
			
		||||
    using Kernel::SharedMemory;
 | 
			
		||||
    using Kernel::MemoryPermission;
 | 
			
		||||
 | 
			
		||||
@@ -71,7 +71,7 @@ static Result MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 other
 | 
			
		||||
 | 
			
		||||
    SharedPtr<SharedMemory> shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle);
 | 
			
		||||
    if (shared_memory == nullptr)
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
 | 
			
		||||
    MemoryPermission permissions_type = static_cast<MemoryPermission>(permissions);
 | 
			
		||||
    switch (permissions_type) {
 | 
			
		||||
@@ -89,11 +89,11 @@ static Result MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 other
 | 
			
		||||
    default:
 | 
			
		||||
        LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Connect to an OS service given the port name, returns the handle to the port to out
 | 
			
		||||
static Result ConnectToPort(Handle* out, const char* port_name) {
 | 
			
		||||
static ResultCode ConnectToPort(Handle* out, const char* port_name) {
 | 
			
		||||
    Service::Interface* service = Service::g_manager->FetchFromPortName(port_name);
 | 
			
		||||
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name);
 | 
			
		||||
@@ -101,33 +101,33 @@ static Result ConnectToPort(Handle* out, const char* port_name) {
 | 
			
		||||
 | 
			
		||||
    *out = service->GetHandle();
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Synchronize to an OS service
 | 
			
		||||
static Result SendSyncRequest(Handle handle) {
 | 
			
		||||
static ResultCode SendSyncRequest(Handle handle) {
 | 
			
		||||
    SharedPtr<Kernel::Session> session = Kernel::g_handle_table.Get<Kernel::Session>(handle);
 | 
			
		||||
    if (session == nullptr) {
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s)", handle, session->GetName().c_str());
 | 
			
		||||
 | 
			
		||||
    return session->SyncRequest().Code().raw;
 | 
			
		||||
    return session->SyncRequest().Code();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Close a handle
 | 
			
		||||
static Result CloseHandle(Handle handle) {
 | 
			
		||||
static ResultCode CloseHandle(Handle handle) {
 | 
			
		||||
    // ImplementMe
 | 
			
		||||
    LOG_ERROR(Kernel_SVC, "(UNIMPLEMENTED) called handle=0x%08X", handle);
 | 
			
		||||
    return 0;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Wait for a handle to synchronize, timeout after the specified nanoseconds
 | 
			
		||||
static Result WaitSynchronization1(Handle handle, s64 nano_seconds) {
 | 
			
		||||
static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) {
 | 
			
		||||
    auto object = Kernel::g_handle_table.GetWaitObject(handle);
 | 
			
		||||
    if (object == nullptr)
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle,
 | 
			
		||||
            object->GetTypeName().c_str(), object->GetName().c_str(), nano_seconds);
 | 
			
		||||
@@ -144,22 +144,22 @@ static Result WaitSynchronization1(Handle handle, s64 nano_seconds) {
 | 
			
		||||
        HLE::Reschedule(__func__);
 | 
			
		||||
 | 
			
		||||
        // NOTE: output of this SVC will be set later depending on how the thread resumes
 | 
			
		||||
        return RESULT_INVALID.raw;
 | 
			
		||||
        return RESULT_INVALID;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    object->Acquire();
 | 
			
		||||
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
 | 
			
		||||
static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, bool wait_all, s64 nano_seconds) {
 | 
			
		||||
static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, bool wait_all, s64 nano_seconds) {
 | 
			
		||||
    bool wait_thread = !wait_all;
 | 
			
		||||
    int handle_index = 0;
 | 
			
		||||
 | 
			
		||||
    // Check if 'handles' is invalid
 | 
			
		||||
    if (handles == nullptr)
 | 
			
		||||
        return ResultCode(ErrorDescription::InvalidPointer, ErrorModule::Kernel, ErrorSummary::InvalidArgument, ErrorLevel::Permanent).raw;
 | 
			
		||||
        return ResultCode(ErrorDescription::InvalidPointer, ErrorModule::Kernel, ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
 | 
			
		||||
 | 
			
		||||
    // NOTE: on real hardware, there is no nullptr check for 'out' (tested with firmware 4.4). If
 | 
			
		||||
    // this happens, the running application will crash.
 | 
			
		||||
@@ -167,7 +167,7 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count,
 | 
			
		||||
 | 
			
		||||
    // Check if 'handle_count' is invalid
 | 
			
		||||
    if (handle_count < 0)
 | 
			
		||||
        return ResultCode(ErrorDescription::OutOfRange, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage).raw;
 | 
			
		||||
        return ResultCode(ErrorDescription::OutOfRange, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage);
 | 
			
		||||
 | 
			
		||||
    // If 'handle_count' is non-zero, iterate through each handle and wait the current thread if
 | 
			
		||||
    // necessary
 | 
			
		||||
@@ -176,7 +176,7 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count,
 | 
			
		||||
        for (int i = 0; i < handle_count; ++i) {
 | 
			
		||||
            auto object = Kernel::g_handle_table.GetWaitObject(handles[i]);
 | 
			
		||||
            if (object == nullptr)
 | 
			
		||||
                return InvalidHandle(ErrorModule::Kernel).raw;
 | 
			
		||||
                return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
 | 
			
		||||
            // Check if the current thread should wait on this object...
 | 
			
		||||
            if (object->ShouldWait()) {
 | 
			
		||||
@@ -220,7 +220,7 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count,
 | 
			
		||||
        HLE::Reschedule(__func__);
 | 
			
		||||
 | 
			
		||||
        // NOTE: output of this SVC will be set later depending on how the thread resumes
 | 
			
		||||
        return RESULT_INVALID.raw;
 | 
			
		||||
        return RESULT_INVALID;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Acquire objects if we did not wait...
 | 
			
		||||
@@ -242,29 +242,29 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count,
 | 
			
		||||
    // not seem to set it to any meaningful value.
 | 
			
		||||
    *out = wait_all ? 0 : handle_index;
 | 
			
		||||
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Create an address arbiter (to allocate access to shared resources)
 | 
			
		||||
static Result CreateAddressArbiter(u32* arbiter) {
 | 
			
		||||
static ResultCode CreateAddressArbiter(u32* arbiter) {
 | 
			
		||||
    using Kernel::AddressArbiter;
 | 
			
		||||
 | 
			
		||||
    ResultVal<SharedPtr<AddressArbiter>> arbiter_res = AddressArbiter::Create();
 | 
			
		||||
    if (arbiter_res.Failed())
 | 
			
		||||
        return arbiter_res.Code().raw;
 | 
			
		||||
        return arbiter_res.Code();
 | 
			
		||||
 | 
			
		||||
    ResultVal<Handle> handle_res = Kernel::g_handle_table.Create(*arbiter_res);
 | 
			
		||||
    if (handle_res.Failed())
 | 
			
		||||
        return handle_res.Code().raw;
 | 
			
		||||
        return handle_res.Code();
 | 
			
		||||
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "returned handle=0x%08X", *handle_res);
 | 
			
		||||
 | 
			
		||||
    *arbiter = *handle_res;
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Arbitrate address
 | 
			
		||||
static Result ArbitrateAddress(Handle handle, u32 address, u32 type, u32 value, s64 nanoseconds) {
 | 
			
		||||
static ResultCode ArbitrateAddress(Handle handle, u32 address, u32 type, u32 value, s64 nanoseconds) {
 | 
			
		||||
    using Kernel::AddressArbiter;
 | 
			
		||||
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called handle=0x%08X, address=0x%08X, type=0x%08X, value=0x%08X", handle,
 | 
			
		||||
@@ -272,10 +272,10 @@ static Result ArbitrateAddress(Handle handle, u32 address, u32 type, u32 value,
 | 
			
		||||
 | 
			
		||||
    SharedPtr<AddressArbiter> arbiter = Kernel::g_handle_table.Get<AddressArbiter>(handle);
 | 
			
		||||
    if (arbiter == nullptr)
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
 | 
			
		||||
    return arbiter->ArbitrateAddress(static_cast<Kernel::ArbitrationType>(type),
 | 
			
		||||
            address, value, nanoseconds).raw;
 | 
			
		||||
            address, value, nanoseconds);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Used to output a message on a debug hardware unit - does nothing on a retail unit
 | 
			
		||||
@@ -284,26 +284,26 @@ static void OutputDebugString(const char* string) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get resource limit
 | 
			
		||||
static Result GetResourceLimit(Handle* resource_limit, Handle process) {
 | 
			
		||||
static ResultCode GetResourceLimit(Handle* resource_limit, Handle process) {
 | 
			
		||||
    // With regards to proceess values:
 | 
			
		||||
    // 0xFFFF8001 is a handle alias for the current KProcess, and 0xFFFF8000 is a handle alias for
 | 
			
		||||
    // the current KThread.
 | 
			
		||||
    *resource_limit = 0xDEADBEEF;
 | 
			
		||||
    LOG_ERROR(Kernel_SVC, "(UNIMPLEMENTED) called process=0x%08X", process);
 | 
			
		||||
    return 0;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get resource limit current values
 | 
			
		||||
static Result GetResourceLimitCurrentValues(s64* values, Handle resource_limit, void* names,
 | 
			
		||||
static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit, void* names,
 | 
			
		||||
    s32 name_count) {
 | 
			
		||||
    LOG_ERROR(Kernel_SVC, "(UNIMPLEMENTED) called resource_limit=%08X, names=%s, name_count=%d",
 | 
			
		||||
        resource_limit, names, name_count);
 | 
			
		||||
    Memory::Write32(Core::g_app_core->GetReg(0), 0); // Normmatt: Set used memory to 0 for now
 | 
			
		||||
    return 0;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Creates a new thread
 | 
			
		||||
static Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top, u32 processor_id) {
 | 
			
		||||
static ResultCode CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top, u32 processor_id) {
 | 
			
		||||
    using Kernel::Thread;
 | 
			
		||||
 | 
			
		||||
    std::string name;
 | 
			
		||||
@@ -317,7 +317,7 @@ static Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top
 | 
			
		||||
    ResultVal<SharedPtr<Thread>> thread_res = Kernel::Thread::Create(
 | 
			
		||||
            name, entry_point, priority, arg, processor_id, stack_top, Kernel::DEFAULT_STACK_SIZE);
 | 
			
		||||
    if (thread_res.Failed())
 | 
			
		||||
        return thread_res.Code().raw;
 | 
			
		||||
        return thread_res.Code();
 | 
			
		||||
    SharedPtr<Thread> thread = std::move(*thread_res);
 | 
			
		||||
 | 
			
		||||
    // TODO(yuriks): Create new handle instead of using built-in
 | 
			
		||||
@@ -332,7 +332,7 @@ static Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top
 | 
			
		||||
            "thread designated for system CPU core (UNIMPLEMENTED) will be run with app core scheduling");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Called when a thread exits
 | 
			
		||||
@@ -344,214 +344,214 @@ static void ExitThread() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Gets the priority for the specified thread
 | 
			
		||||
static Result GetThreadPriority(s32* priority, Handle handle) {
 | 
			
		||||
static ResultCode GetThreadPriority(s32* priority, Handle handle) {
 | 
			
		||||
    const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
 | 
			
		||||
    if (thread == nullptr)
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
 | 
			
		||||
    *priority = thread->GetPriority();
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Sets the priority for the specified thread
 | 
			
		||||
static Result SetThreadPriority(Handle handle, s32 priority) {
 | 
			
		||||
static ResultCode SetThreadPriority(Handle handle, s32 priority) {
 | 
			
		||||
    SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
 | 
			
		||||
    if (thread == nullptr)
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
 | 
			
		||||
    thread->SetPriority(priority);
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Create a mutex
 | 
			
		||||
static Result CreateMutex(Handle* handle, u32 initial_locked) {
 | 
			
		||||
static ResultCode CreateMutex(Handle* handle, u32 initial_locked) {
 | 
			
		||||
    using Kernel::Mutex;
 | 
			
		||||
 | 
			
		||||
    auto mutex_res = Mutex::Create(initial_locked != 0);
 | 
			
		||||
    if (mutex_res.Failed())
 | 
			
		||||
        return mutex_res.Code().raw;
 | 
			
		||||
        return mutex_res.Code();
 | 
			
		||||
    SharedPtr<Mutex> mutex = mutex_res.MoveFrom();
 | 
			
		||||
 | 
			
		||||
    *handle = Kernel::g_handle_table.Create(mutex).MoveFrom();
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called initial_locked=%s : created handle=0x%08X",
 | 
			
		||||
        initial_locked ? "true" : "false", *handle);
 | 
			
		||||
    return 0;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Release a mutex
 | 
			
		||||
static Result ReleaseMutex(Handle handle) {
 | 
			
		||||
static ResultCode ReleaseMutex(Handle handle) {
 | 
			
		||||
    using Kernel::Mutex;
 | 
			
		||||
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called handle=0x%08X", handle);
 | 
			
		||||
 | 
			
		||||
    SharedPtr<Mutex> mutex = Kernel::g_handle_table.Get<Mutex>(handle);
 | 
			
		||||
    if (mutex == nullptr)
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
 | 
			
		||||
    mutex->Release();
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get the ID for the specified thread.
 | 
			
		||||
static Result GetThreadId(u32* thread_id, Handle handle) {
 | 
			
		||||
static ResultCode GetThreadId(u32* thread_id, Handle handle) {
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called thread=0x%08X", handle);
 | 
			
		||||
 | 
			
		||||
    const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
 | 
			
		||||
    if (thread == nullptr)
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
 | 
			
		||||
    *thread_id = thread->GetThreadId();
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Creates a semaphore
 | 
			
		||||
static Result CreateSemaphore(Handle* semaphore, s32 initial_count, s32 max_count) {
 | 
			
		||||
static ResultCode CreateSemaphore(Handle* semaphore, s32 initial_count, s32 max_count) {
 | 
			
		||||
    using Kernel::Semaphore;
 | 
			
		||||
 | 
			
		||||
    ResultVal<SharedPtr<Semaphore>> semaphore_res = Semaphore::Create(initial_count, max_count);
 | 
			
		||||
    if (semaphore_res.Failed())
 | 
			
		||||
        return semaphore_res.Code().raw;
 | 
			
		||||
        return semaphore_res.Code();
 | 
			
		||||
 | 
			
		||||
    ResultVal<Handle> handle_res = Kernel::g_handle_table.Create(*semaphore_res);
 | 
			
		||||
    if (handle_res.Failed())
 | 
			
		||||
        return handle_res.Code().raw;
 | 
			
		||||
        return handle_res.Code();
 | 
			
		||||
 | 
			
		||||
    *semaphore = *handle_res;
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called initial_count=%d, max_count=%d, created handle=0x%08X",
 | 
			
		||||
        initial_count, max_count, *semaphore);
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Releases a certain number of slots in a semaphore
 | 
			
		||||
static Result ReleaseSemaphore(s32* count, Handle handle, s32 release_count) {
 | 
			
		||||
static ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) {
 | 
			
		||||
    using Kernel::Semaphore;
 | 
			
		||||
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called release_count=%d, handle=0x%08X", release_count, handle);
 | 
			
		||||
 | 
			
		||||
    SharedPtr<Semaphore> semaphore = Kernel::g_handle_table.Get<Semaphore>(handle);
 | 
			
		||||
    if (semaphore == nullptr)
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
 | 
			
		||||
    ResultVal<s32> release_res = semaphore->Release(release_count);
 | 
			
		||||
    if (release_res.Failed())
 | 
			
		||||
        return release_res.Code().raw;
 | 
			
		||||
        return release_res.Code();
 | 
			
		||||
 | 
			
		||||
    *count = *release_res;
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Query memory
 | 
			
		||||
static Result QueryMemory(void* info, void* out, u32 addr) {
 | 
			
		||||
static ResultCode QueryMemory(void* info, void* out, u32 addr) {
 | 
			
		||||
    LOG_ERROR(Kernel_SVC, "(UNIMPLEMENTED) called addr=0x%08X", addr);
 | 
			
		||||
    return 0;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Create an event
 | 
			
		||||
static Result CreateEvent(Handle* handle, u32 reset_type) {
 | 
			
		||||
static ResultCode CreateEvent(Handle* handle, u32 reset_type) {
 | 
			
		||||
    auto evt_res = Kernel::Event::Create(static_cast<ResetType>(reset_type));
 | 
			
		||||
    if (evt_res.Failed())
 | 
			
		||||
        return evt_res.Code().raw;
 | 
			
		||||
        return evt_res.Code();
 | 
			
		||||
    auto handle_res = Kernel::g_handle_table.Create(evt_res.MoveFrom());
 | 
			
		||||
    if (handle_res.Failed())
 | 
			
		||||
        return handle_res.Code().raw;
 | 
			
		||||
        return handle_res.Code();
 | 
			
		||||
    *handle = handle_res.MoveFrom();
 | 
			
		||||
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", reset_type, *handle);
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Duplicates a kernel handle
 | 
			
		||||
static Result DuplicateHandle(Handle* out, Handle handle) {
 | 
			
		||||
static ResultCode DuplicateHandle(Handle* out, Handle handle) {
 | 
			
		||||
    ResultVal<Handle> out_h = Kernel::g_handle_table.Duplicate(handle);
 | 
			
		||||
    if (out_h.Succeeded()) {
 | 
			
		||||
        *out = *out_h;
 | 
			
		||||
        LOG_TRACE(Kernel_SVC, "duplicated 0x%08X to 0x%08X", handle, *out);
 | 
			
		||||
    }
 | 
			
		||||
    return out_h.Code().raw;
 | 
			
		||||
    return out_h.Code();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Signals an event
 | 
			
		||||
static Result SignalEvent(Handle handle) {
 | 
			
		||||
static ResultCode SignalEvent(Handle handle) {
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle);
 | 
			
		||||
 | 
			
		||||
    auto evt = Kernel::g_handle_table.Get<Kernel::Event>(handle);
 | 
			
		||||
    if (evt == nullptr)
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
 | 
			
		||||
    evt->Signal();
 | 
			
		||||
    HLE::Reschedule(__func__);
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Clears an event
 | 
			
		||||
static Result ClearEvent(Handle handle) {
 | 
			
		||||
static ResultCode ClearEvent(Handle handle) {
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle);
 | 
			
		||||
 | 
			
		||||
    auto evt = Kernel::g_handle_table.Get<Kernel::Event>(handle);
 | 
			
		||||
    if (evt == nullptr)
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
 | 
			
		||||
    evt->Clear();
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Creates a timer
 | 
			
		||||
static Result CreateTimer(Handle* handle, u32 reset_type) {
 | 
			
		||||
static ResultCode CreateTimer(Handle* handle, u32 reset_type) {
 | 
			
		||||
    using Kernel::Timer;
 | 
			
		||||
 | 
			
		||||
    auto timer_res = Timer::Create(static_cast<ResetType>(reset_type));
 | 
			
		||||
    if (timer_res.Failed())
 | 
			
		||||
        return timer_res.Code().raw;
 | 
			
		||||
        return timer_res.Code();
 | 
			
		||||
 | 
			
		||||
    auto handle_res = Kernel::g_handle_table.Create(timer_res.MoveFrom());
 | 
			
		||||
    if (handle_res.Failed())
 | 
			
		||||
        return handle_res.Code().raw;
 | 
			
		||||
        return handle_res.Code();
 | 
			
		||||
    *handle = handle_res.MoveFrom();
 | 
			
		||||
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", reset_type, *handle);
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Clears a timer
 | 
			
		||||
static Result ClearTimer(Handle handle) {
 | 
			
		||||
static ResultCode ClearTimer(Handle handle) {
 | 
			
		||||
    using Kernel::Timer;
 | 
			
		||||
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called timer=0x%08X", handle);
 | 
			
		||||
 | 
			
		||||
    SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle);
 | 
			
		||||
    if (timer == nullptr)
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
 | 
			
		||||
    timer->Clear();
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Starts a timer
 | 
			
		||||
static Result SetTimer(Handle handle, s64 initial, s64 interval) {
 | 
			
		||||
static ResultCode SetTimer(Handle handle, s64 initial, s64 interval) {
 | 
			
		||||
    using Kernel::Timer;
 | 
			
		||||
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called timer=0x%08X", handle);
 | 
			
		||||
 | 
			
		||||
    SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle);
 | 
			
		||||
    if (timer == nullptr)
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
 | 
			
		||||
    timer->Set(initial, interval);
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Cancels a timer
 | 
			
		||||
static Result CancelTimer(Handle handle) {
 | 
			
		||||
static ResultCode CancelTimer(Handle handle) {
 | 
			
		||||
    using Kernel::Timer;
 | 
			
		||||
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called timer=0x%08X", handle);
 | 
			
		||||
 | 
			
		||||
    SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle);
 | 
			
		||||
    if (timer == nullptr)
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
 | 
			
		||||
    timer->Cancel();
 | 
			
		||||
    return RESULT_SUCCESS.raw;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Sleep the current thread
 | 
			
		||||
@@ -573,22 +573,22 @@ static s64 GetSystemTick() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Creates a memory block at the specified address with the specified permissions and size
 | 
			
		||||
static Result CreateMemoryBlock(Handle* memblock, u32 addr, u32 size, u32 my_permission,
 | 
			
		||||
static ResultCode CreateMemoryBlock(Handle* memblock, u32 addr, u32 size, u32 my_permission,
 | 
			
		||||
        u32 other_permission) {
 | 
			
		||||
    using Kernel::SharedMemory;
 | 
			
		||||
    // TODO(Subv): Implement this function
 | 
			
		||||
 | 
			
		||||
    ResultVal<SharedPtr<SharedMemory>> shared_memory_res = SharedMemory::Create();
 | 
			
		||||
    if (shared_memory_res.Failed())
 | 
			
		||||
        return shared_memory_res.Code().raw;
 | 
			
		||||
        return shared_memory_res.Code();
 | 
			
		||||
 | 
			
		||||
    ResultVal<Handle> handle_res = Kernel::g_handle_table.Create(*shared_memory_res);
 | 
			
		||||
    if (handle_res.Failed())
 | 
			
		||||
        return handle_res.Code().raw;
 | 
			
		||||
        return handle_res.Code();
 | 
			
		||||
 | 
			
		||||
    *memblock = *handle_res;
 | 
			
		||||
    LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%08X", addr);
 | 
			
		||||
    return 0;
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const HLE::FunctionDef SVC_Table[] = {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user