kernel: make handle table per-process
This commit is contained in:
parent
fda2a5cf54
commit
eb285c33fd
|
@ -5,7 +5,6 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/core.h" // TODO: for current_process. Remove this later
|
|
||||||
#include "core/hle/kernel/errors.h"
|
#include "core/hle/kernel/errors.h"
|
||||||
#include "core/hle/kernel/handle_table.h"
|
#include "core/hle/kernel/handle_table.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
|
@ -13,9 +12,7 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
HandleTable g_handle_table;
|
HandleTable::HandleTable(KernelSystem& kernel) : kernel(kernel) {
|
||||||
|
|
||||||
HandleTable::HandleTable() {
|
|
||||||
next_generation = 1;
|
next_generation = 1;
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
@ -77,9 +74,7 @@ SharedPtr<Object> HandleTable::GetGeneric(Handle handle) const {
|
||||||
if (handle == CurrentThread) {
|
if (handle == CurrentThread) {
|
||||||
return GetCurrentThread();
|
return GetCurrentThread();
|
||||||
} else if (handle == CurrentProcess) {
|
} else if (handle == CurrentProcess) {
|
||||||
// TODO: should this return HandleTable's parent process, or kernel's current process?
|
return kernel.GetCurrentProcess();
|
||||||
// Should change this either way
|
|
||||||
return Core::System::GetInstance().Kernel().GetCurrentProcess();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsValid(handle)) {
|
if (!IsValid(handle)) {
|
||||||
|
|
|
@ -42,7 +42,7 @@ enum KernelHandle : Handle {
|
||||||
*/
|
*/
|
||||||
class HandleTable final : NonCopyable {
|
class HandleTable final : NonCopyable {
|
||||||
public:
|
public:
|
||||||
HandleTable();
|
explicit HandleTable(KernelSystem& kernel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates a handle for the given object.
|
* Allocates a handle for the given object.
|
||||||
|
@ -119,8 +119,8 @@ private:
|
||||||
|
|
||||||
/// Head of the free slots linked list.
|
/// Head of the free slots linked list.
|
||||||
u16 next_free_slot;
|
u16 next_free_slot;
|
||||||
|
|
||||||
|
KernelSystem& kernel;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern HandleTable g_handle_table;
|
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -50,7 +50,7 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
|
||||||
std::array<u32_le, IPC::COMMAND_BUFFER_LENGTH + 2 * IPC::MAX_STATIC_BUFFERS> cmd_buff;
|
std::array<u32_le, IPC::COMMAND_BUFFER_LENGTH + 2 * IPC::MAX_STATIC_BUFFERS> cmd_buff;
|
||||||
Memory::ReadBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(),
|
Memory::ReadBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(),
|
||||||
cmd_buff.size() * sizeof(u32));
|
cmd_buff.size() * sizeof(u32));
|
||||||
context.WriteToOutgoingCommandBuffer(cmd_buff.data(), *process, Kernel::g_handle_table);
|
context.WriteToOutgoingCommandBuffer(cmd_buff.data(), *process);
|
||||||
// Copy the translated command buffer back into the thread's command buffer area.
|
// Copy the translated command buffer back into the thread's command buffer area.
|
||||||
Memory::WriteBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(),
|
Memory::WriteBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(),
|
||||||
cmd_buff.size() * sizeof(u32));
|
cmd_buff.size() * sizeof(u32));
|
||||||
|
@ -98,8 +98,7 @@ void HLERequestContext::AddStaticBuffer(u8 buffer_id, std::vector<u8> data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf,
|
ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf,
|
||||||
Process& src_process,
|
Process& src_process) {
|
||||||
HandleTable& src_table) {
|
|
||||||
IPC::Header header{src_cmdbuf[0]};
|
IPC::Header header{src_cmdbuf[0]};
|
||||||
|
|
||||||
std::size_t untranslated_size = 1u + header.normal_params_size;
|
std::size_t untranslated_size = 1u + header.normal_params_size;
|
||||||
|
@ -122,10 +121,10 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr
|
||||||
Handle handle = src_cmdbuf[i];
|
Handle handle = src_cmdbuf[i];
|
||||||
SharedPtr<Object> object = nullptr;
|
SharedPtr<Object> object = nullptr;
|
||||||
if (handle != 0) {
|
if (handle != 0) {
|
||||||
object = src_table.GetGeneric(handle);
|
object = src_process.handle_table.GetGeneric(handle);
|
||||||
ASSERT(object != nullptr); // TODO(yuriks): Return error
|
ASSERT(object != nullptr); // TODO(yuriks): Return error
|
||||||
if (descriptor == IPC::DescriptorType::MoveHandle) {
|
if (descriptor == IPC::DescriptorType::MoveHandle) {
|
||||||
src_table.Close(handle);
|
src_process.handle_table.Close(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,8 +162,8 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process,
|
ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf,
|
||||||
HandleTable& dst_table) const {
|
Process& dst_process) const {
|
||||||
IPC::Header header{cmd_buf[0]};
|
IPC::Header header{cmd_buf[0]};
|
||||||
|
|
||||||
std::size_t untranslated_size = 1u + header.normal_params_size;
|
std::size_t untranslated_size = 1u + header.normal_params_size;
|
||||||
|
@ -189,7 +188,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P
|
||||||
Handle handle = 0;
|
Handle handle = 0;
|
||||||
if (object != nullptr) {
|
if (object != nullptr) {
|
||||||
// TODO(yuriks): Figure out the proper error handling for if this fails
|
// TODO(yuriks): Figure out the proper error handling for if this fails
|
||||||
handle = dst_table.Create(object).Unwrap();
|
handle = dst_process.handle_table.Create(object).Unwrap();
|
||||||
}
|
}
|
||||||
dst_cmdbuf[i++] = handle;
|
dst_cmdbuf[i++] = handle;
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,11 +226,9 @@ public:
|
||||||
MappedBuffer& GetMappedBuffer(u32 id_from_cmdbuf);
|
MappedBuffer& GetMappedBuffer(u32 id_from_cmdbuf);
|
||||||
|
|
||||||
/// Populates this context with data from the requesting process/thread.
|
/// Populates this context with data from the requesting process/thread.
|
||||||
ResultCode PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, Process& src_process,
|
ResultCode PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, Process& src_process);
|
||||||
HandleTable& src_table);
|
|
||||||
/// Writes data from this context back to the requesting process/thread.
|
/// Writes data from this context back to the requesting process/thread.
|
||||||
ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process,
|
ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process) const;
|
||||||
HandleTable& dst_table) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
|
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
|
||||||
|
|
|
@ -60,9 +60,9 @@ ResultCode TranslateCommandBuffer(SharedPtr<Thread> src_thread, SharedPtr<Thread
|
||||||
} else if (handle == CurrentProcess) {
|
} else if (handle == CurrentProcess) {
|
||||||
object = src_process;
|
object = src_process;
|
||||||
} else if (handle != 0) {
|
} else if (handle != 0) {
|
||||||
object = g_handle_table.GetGeneric(handle);
|
object = src_process->handle_table.GetGeneric(handle);
|
||||||
if (descriptor == IPC::DescriptorType::MoveHandle) {
|
if (descriptor == IPC::DescriptorType::MoveHandle) {
|
||||||
g_handle_table.Close(handle);
|
src_process->handle_table.Close(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ ResultCode TranslateCommandBuffer(SharedPtr<Thread> src_thread, SharedPtr<Thread
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = g_handle_table.Create(std::move(object));
|
auto result = dst_process->handle_table.Create(std::move(object));
|
||||||
cmd_buf[i++] = result.ValueOr(0);
|
cmd_buf[i++] = result.ValueOr(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -27,8 +27,6 @@ KernelSystem::KernelSystem(u32 system_mode) {
|
||||||
|
|
||||||
/// Shutdown the kernel
|
/// Shutdown the kernel
|
||||||
KernelSystem::~KernelSystem() {
|
KernelSystem::~KernelSystem() {
|
||||||
g_handle_table.Clear(); // Free all kernel objects
|
|
||||||
|
|
||||||
Kernel::ThreadingShutdown();
|
Kernel::ThreadingShutdown();
|
||||||
|
|
||||||
Kernel::TimersShutdown();
|
Kernel::TimersShutdown();
|
||||||
|
|
|
@ -300,7 +300,8 @@ ResultCode Process::LinearFree(VAddr target, u32 size) {
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::Process::Process(KernelSystem& kernel) : Object(kernel), kernel(kernel) {}
|
Kernel::Process::Process(KernelSystem& kernel)
|
||||||
|
: Object(kernel), handle_table(kernel), kernel(kernel) {}
|
||||||
Kernel::Process::~Process() {}
|
Kernel::Process::~Process() {}
|
||||||
|
|
||||||
SharedPtr<Process> KernelSystem::GetProcessById(u32 process_id) const {
|
SharedPtr<Process> KernelSystem::GetProcessById(u32 process_id) const {
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <boost/container/static_vector.hpp>
|
#include <boost/container/static_vector.hpp>
|
||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "core/hle/kernel/handle_table.h"
|
||||||
#include "core/hle/kernel/object.h"
|
#include "core/hle/kernel/object.h"
|
||||||
#include "core/hle/kernel/vm_manager.h"
|
#include "core/hle/kernel/vm_manager.h"
|
||||||
|
|
||||||
|
@ -123,6 +124,8 @@ public:
|
||||||
return HANDLE_TYPE;
|
return HANDLE_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HandleTable handle_table;
|
||||||
|
|
||||||
SharedPtr<CodeSet> codeset;
|
SharedPtr<CodeSet> codeset;
|
||||||
/// Resource limit descriptor for this process
|
/// Resource limit descriptor for this process
|
||||||
SharedPtr<ResourceLimit> resource_limit;
|
SharedPtr<ResourceLimit> resource_limit;
|
||||||
|
|
|
@ -182,7 +182,9 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o
|
||||||
"otherpermission={}",
|
"otherpermission={}",
|
||||||
handle, addr, permissions, other_permissions);
|
handle, addr, permissions, other_permissions);
|
||||||
|
|
||||||
SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(handle);
|
SharedPtr<SharedMemory> shared_memory =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<SharedMemory>(
|
||||||
|
handle);
|
||||||
if (shared_memory == nullptr)
|
if (shared_memory == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -211,12 +213,12 @@ static ResultCode UnmapMemoryBlock(Handle handle, u32 addr) {
|
||||||
|
|
||||||
// TODO(Subv): Return E0A01BF5 if the address is not in the application's heap
|
// TODO(Subv): Return E0A01BF5 if the address is not in the application's heap
|
||||||
|
|
||||||
SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(handle);
|
SharedPtr<Process> current_process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||||
|
SharedPtr<SharedMemory> shared_memory = current_process->handle_table.Get<SharedMemory>(handle);
|
||||||
if (shared_memory == nullptr)
|
if (shared_memory == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
return shared_memory->Unmap(Core::System::GetInstance().Kernel().GetCurrentProcess().get(),
|
return shared_memory->Unmap(current_process.get(), addr);
|
||||||
addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Connect to an OS service given the port name, returns the handle to the port to out
|
/// Connect to an OS service given the port name, returns the handle to the port to out
|
||||||
|
@ -244,13 +246,17 @@ static ResultCode ConnectToPort(Handle* out_handle, VAddr port_name_address) {
|
||||||
CASCADE_RESULT(client_session, client_port->Connect());
|
CASCADE_RESULT(client_session, client_port->Connect());
|
||||||
|
|
||||||
// Return the client session
|
// Return the client session
|
||||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(client_session));
|
CASCADE_RESULT(*out_handle,
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Create(
|
||||||
|
client_session));
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes a blocking IPC call to an OS service.
|
/// Makes a blocking IPC call to an OS service.
|
||||||
static ResultCode SendSyncRequest(Handle handle) {
|
static ResultCode SendSyncRequest(Handle handle) {
|
||||||
SharedPtr<ClientSession> session = g_handle_table.Get<ClientSession>(handle);
|
SharedPtr<ClientSession> session =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<ClientSession>(
|
||||||
|
handle);
|
||||||
if (session == nullptr) {
|
if (session == nullptr) {
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
@ -265,12 +271,14 @@ static ResultCode SendSyncRequest(Handle handle) {
|
||||||
/// Close a handle
|
/// Close a handle
|
||||||
static ResultCode CloseHandle(Handle handle) {
|
static ResultCode CloseHandle(Handle handle) {
|
||||||
LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle);
|
LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle);
|
||||||
return g_handle_table.Close(handle);
|
return Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Close(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wait for a handle to synchronize, timeout after the specified nanoseconds
|
/// Wait for a handle to synchronize, timeout after the specified nanoseconds
|
||||||
static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) {
|
static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) {
|
||||||
auto object = g_handle_table.Get<WaitObject>(handle);
|
auto object =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<WaitObject>(
|
||||||
|
handle);
|
||||||
Thread* thread = GetCurrentThread();
|
Thread* thread = GetCurrentThread();
|
||||||
|
|
||||||
if (object == nullptr)
|
if (object == nullptr)
|
||||||
|
@ -341,7 +349,9 @@ static ResultCode WaitSynchronizationN(s32* out, VAddr handles_address, s32 hand
|
||||||
|
|
||||||
for (int i = 0; i < handle_count; ++i) {
|
for (int i = 0; i < handle_count; ++i) {
|
||||||
Handle handle = Memory::Read32(handles_address + i * sizeof(Handle));
|
Handle handle = Memory::Read32(handles_address + i * sizeof(Handle));
|
||||||
auto object = g_handle_table.Get<WaitObject>(handle);
|
auto object =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<WaitObject>(
|
||||||
|
handle);
|
||||||
if (object == nullptr)
|
if (object == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
objects[i] = object;
|
objects[i] = object;
|
||||||
|
@ -505,9 +515,11 @@ static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_
|
||||||
using ObjectPtr = SharedPtr<WaitObject>;
|
using ObjectPtr = SharedPtr<WaitObject>;
|
||||||
std::vector<ObjectPtr> objects(handle_count);
|
std::vector<ObjectPtr> objects(handle_count);
|
||||||
|
|
||||||
|
SharedPtr<Process> current_process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||||
|
|
||||||
for (int i = 0; i < handle_count; ++i) {
|
for (int i = 0; i < handle_count; ++i) {
|
||||||
Handle handle = Memory::Read32(handles_address + i * sizeof(Handle));
|
Handle handle = Memory::Read32(handles_address + i * sizeof(Handle));
|
||||||
auto object = g_handle_table.Get<WaitObject>(handle);
|
auto object = current_process->handle_table.Get<WaitObject>(handle);
|
||||||
if (object == nullptr)
|
if (object == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
objects[i] = object;
|
objects[i] = object;
|
||||||
|
@ -518,7 +530,7 @@ static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_
|
||||||
u32* cmd_buff = GetCommandBuffer();
|
u32* cmd_buff = GetCommandBuffer();
|
||||||
IPC::Header header{cmd_buff[0]};
|
IPC::Header header{cmd_buff[0]};
|
||||||
if (reply_target != 0 && header.command_id != 0xFFFF) {
|
if (reply_target != 0 && header.command_id != 0xFFFF) {
|
||||||
auto session = g_handle_table.Get<ServerSession>(reply_target);
|
auto session = current_process->handle_table.Get<ServerSession>(reply_target);
|
||||||
if (session == nullptr)
|
if (session == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -618,8 +630,10 @@ static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_
|
||||||
|
|
||||||
/// Create an address arbiter (to allocate access to shared resources)
|
/// Create an address arbiter (to allocate access to shared resources)
|
||||||
static ResultCode CreateAddressArbiter(Handle* out_handle) {
|
static ResultCode CreateAddressArbiter(Handle* out_handle) {
|
||||||
SharedPtr<AddressArbiter> arbiter = Core::System::GetInstance().Kernel().CreateAddressArbiter();
|
KernelSystem& kernel = Core::System::GetInstance().Kernel();
|
||||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(arbiter)));
|
SharedPtr<AddressArbiter> arbiter = kernel.CreateAddressArbiter();
|
||||||
|
CASCADE_RESULT(*out_handle,
|
||||||
|
kernel.GetCurrentProcess()->handle_table.Create(std::move(arbiter)));
|
||||||
LOG_TRACE(Kernel_SVC, "returned handle=0x{:08X}", *out_handle);
|
LOG_TRACE(Kernel_SVC, "returned handle=0x{:08X}", *out_handle);
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -630,7 +644,9 @@ static ResultCode ArbitrateAddress(Handle handle, u32 address, u32 type, u32 val
|
||||||
LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}, address=0x{:08X}, type=0x{:08X}, value=0x{:08X}",
|
LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}, address=0x{:08X}, type=0x{:08X}, value=0x{:08X}",
|
||||||
handle, address, type, value);
|
handle, address, type, value);
|
||||||
|
|
||||||
SharedPtr<AddressArbiter> arbiter = g_handle_table.Get<AddressArbiter>(handle);
|
SharedPtr<AddressArbiter> arbiter =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<AddressArbiter>(
|
||||||
|
handle);
|
||||||
if (arbiter == nullptr)
|
if (arbiter == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -678,11 +694,12 @@ static void OutputDebugString(VAddr address, int len) {
|
||||||
static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle) {
|
static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle) {
|
||||||
LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle);
|
LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle);
|
||||||
|
|
||||||
SharedPtr<Process> process = g_handle_table.Get<Process>(process_handle);
|
SharedPtr<Process> current_process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||||
|
SharedPtr<Process> process = current_process->handle_table.Get<Process>(process_handle);
|
||||||
if (process == nullptr)
|
if (process == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
CASCADE_RESULT(*resource_limit, g_handle_table.Create(process->resource_limit));
|
CASCADE_RESULT(*resource_limit, current_process->handle_table.Create(process->resource_limit));
|
||||||
|
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -694,7 +711,8 @@ static ResultCode GetResourceLimitCurrentValues(VAddr values, Handle resource_li
|
||||||
resource_limit_handle, names, name_count);
|
resource_limit_handle, names, name_count);
|
||||||
|
|
||||||
SharedPtr<ResourceLimit> resource_limit =
|
SharedPtr<ResourceLimit> resource_limit =
|
||||||
g_handle_table.Get<ResourceLimit>(resource_limit_handle);
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<ResourceLimit>(
|
||||||
|
resource_limit_handle);
|
||||||
if (resource_limit == nullptr)
|
if (resource_limit == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -714,7 +732,8 @@ static ResultCode GetResourceLimitLimitValues(VAddr values, Handle resource_limi
|
||||||
resource_limit_handle, names, name_count);
|
resource_limit_handle, names, name_count);
|
||||||
|
|
||||||
SharedPtr<ResourceLimit> resource_limit =
|
SharedPtr<ResourceLimit> resource_limit =
|
||||||
g_handle_table.Get<ResourceLimit>(resource_limit_handle);
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<ResourceLimit>(
|
||||||
|
resource_limit_handle);
|
||||||
if (resource_limit == nullptr)
|
if (resource_limit == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -773,7 +792,7 @@ static ResultCode CreateThread(Handle* out_handle, u32 priority, u32 entry_point
|
||||||
thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO |
|
thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO |
|
||||||
FPSCR_ROUND_TOZERO); // 0x03C00000
|
FPSCR_ROUND_TOZERO); // 0x03C00000
|
||||||
|
|
||||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(thread)));
|
CASCADE_RESULT(*out_handle, current_process->handle_table.Create(std::move(thread)));
|
||||||
|
|
||||||
Core::System::GetInstance().PrepareReschedule();
|
Core::System::GetInstance().PrepareReschedule();
|
||||||
|
|
||||||
|
@ -795,7 +814,8 @@ static void ExitThread() {
|
||||||
|
|
||||||
/// Gets the priority for the specified thread
|
/// Gets the priority for the specified thread
|
||||||
static ResultCode GetThreadPriority(u32* priority, Handle handle) {
|
static ResultCode GetThreadPriority(u32* priority, Handle handle) {
|
||||||
const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(handle);
|
const SharedPtr<Thread> thread =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<Thread>(handle);
|
||||||
if (thread == nullptr)
|
if (thread == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -809,7 +829,8 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
|
||||||
return ERR_OUT_OF_RANGE;
|
return ERR_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<Thread> thread = g_handle_table.Get<Thread>(handle);
|
SharedPtr<Thread> thread =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<Thread>(handle);
|
||||||
if (thread == nullptr)
|
if (thread == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -834,9 +855,10 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
|
||||||
|
|
||||||
/// Create a mutex
|
/// Create a mutex
|
||||||
static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) {
|
static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) {
|
||||||
SharedPtr<Mutex> mutex = Core::System::GetInstance().Kernel().CreateMutex(initial_locked != 0);
|
KernelSystem& kernel = Core::System::GetInstance().Kernel();
|
||||||
|
SharedPtr<Mutex> mutex = kernel.CreateMutex(initial_locked != 0);
|
||||||
mutex->name = fmt::format("mutex-{:08x}", Core::CPU().GetReg(14));
|
mutex->name = fmt::format("mutex-{:08x}", Core::CPU().GetReg(14));
|
||||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(mutex)));
|
CASCADE_RESULT(*out_handle, kernel.GetCurrentProcess()->handle_table.Create(std::move(mutex)));
|
||||||
|
|
||||||
LOG_TRACE(Kernel_SVC, "called initial_locked={} : created handle=0x{:08X}",
|
LOG_TRACE(Kernel_SVC, "called initial_locked={} : created handle=0x{:08X}",
|
||||||
initial_locked ? "true" : "false", *out_handle);
|
initial_locked ? "true" : "false", *out_handle);
|
||||||
|
@ -848,7 +870,8 @@ static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) {
|
||||||
static ResultCode ReleaseMutex(Handle handle) {
|
static ResultCode ReleaseMutex(Handle handle) {
|
||||||
LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}", handle);
|
LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}", handle);
|
||||||
|
|
||||||
SharedPtr<Mutex> mutex = g_handle_table.Get<Mutex>(handle);
|
SharedPtr<Mutex> mutex =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<Mutex>(handle);
|
||||||
if (mutex == nullptr)
|
if (mutex == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -859,7 +882,9 @@ static ResultCode ReleaseMutex(Handle handle) {
|
||||||
static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
|
static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
|
||||||
LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle);
|
LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle);
|
||||||
|
|
||||||
const SharedPtr<Process> process = g_handle_table.Get<Process>(process_handle);
|
const SharedPtr<Process> process =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<Process>(
|
||||||
|
process_handle);
|
||||||
if (process == nullptr)
|
if (process == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -871,7 +896,9 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
|
||||||
static ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle) {
|
static ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle) {
|
||||||
LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
|
LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
|
||||||
|
|
||||||
const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
|
const SharedPtr<Thread> thread =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<Thread>(
|
||||||
|
thread_handle);
|
||||||
if (thread == nullptr)
|
if (thread == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -887,7 +914,8 @@ static ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle) {
|
||||||
static ResultCode GetThreadId(u32* thread_id, Handle handle) {
|
static ResultCode GetThreadId(u32* thread_id, Handle handle) {
|
||||||
LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", handle);
|
LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", handle);
|
||||||
|
|
||||||
const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(handle);
|
const SharedPtr<Thread> thread =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<Thread>(handle);
|
||||||
if (thread == nullptr)
|
if (thread == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -897,10 +925,12 @@ static ResultCode GetThreadId(u32* thread_id, Handle handle) {
|
||||||
|
|
||||||
/// Creates a semaphore
|
/// Creates a semaphore
|
||||||
static ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max_count) {
|
static ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max_count) {
|
||||||
|
KernelSystem& kernel = Core::System::GetInstance().Kernel();
|
||||||
CASCADE_RESULT(SharedPtr<Semaphore> semaphore,
|
CASCADE_RESULT(SharedPtr<Semaphore> semaphore,
|
||||||
Core::System::GetInstance().Kernel().CreateSemaphore(initial_count, max_count));
|
kernel.CreateSemaphore(initial_count, max_count));
|
||||||
semaphore->name = fmt::format("semaphore-{:08x}", Core::CPU().GetReg(14));
|
semaphore->name = fmt::format("semaphore-{:08x}", Core::CPU().GetReg(14));
|
||||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(semaphore)));
|
CASCADE_RESULT(*out_handle,
|
||||||
|
kernel.GetCurrentProcess()->handle_table.Create(std::move(semaphore)));
|
||||||
|
|
||||||
LOG_TRACE(Kernel_SVC, "called initial_count={}, max_count={}, created handle=0x{:08X}",
|
LOG_TRACE(Kernel_SVC, "called initial_count={}, max_count={}, created handle=0x{:08X}",
|
||||||
initial_count, max_count, *out_handle);
|
initial_count, max_count, *out_handle);
|
||||||
|
@ -911,7 +941,9 @@ static ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max
|
||||||
static ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) {
|
static ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) {
|
||||||
LOG_TRACE(Kernel_SVC, "called release_count={}, handle=0x{:08X}", release_count, handle);
|
LOG_TRACE(Kernel_SVC, "called release_count={}, handle=0x{:08X}", release_count, handle);
|
||||||
|
|
||||||
SharedPtr<Semaphore> semaphore = g_handle_table.Get<Semaphore>(handle);
|
SharedPtr<Semaphore> semaphore =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<Semaphore>(
|
||||||
|
handle);
|
||||||
if (semaphore == nullptr)
|
if (semaphore == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -923,7 +955,9 @@ static ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count)
|
||||||
/// Query process memory
|
/// Query process memory
|
||||||
static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* page_info,
|
static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* page_info,
|
||||||
Handle process_handle, u32 addr) {
|
Handle process_handle, u32 addr) {
|
||||||
SharedPtr<Process> process = g_handle_table.Get<Process>(process_handle);
|
SharedPtr<Process> process =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<Process>(
|
||||||
|
process_handle);
|
||||||
if (process == nullptr)
|
if (process == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -949,9 +983,10 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, u32
|
||||||
|
|
||||||
/// Create an event
|
/// Create an event
|
||||||
static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) {
|
static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) {
|
||||||
SharedPtr<Event> evt = Core::System::GetInstance().Kernel().CreateEvent(
|
KernelSystem& kernel = Core::System::GetInstance().Kernel();
|
||||||
static_cast<ResetType>(reset_type), fmt::format("event-{:08x}", Core::CPU().GetReg(14)));
|
SharedPtr<Event> evt = kernel.CreateEvent(static_cast<ResetType>(reset_type),
|
||||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(evt)));
|
fmt::format("event-{:08x}", Core::CPU().GetReg(14)));
|
||||||
|
CASCADE_RESULT(*out_handle, kernel.GetCurrentProcess()->handle_table.Create(std::move(evt)));
|
||||||
|
|
||||||
LOG_TRACE(Kernel_SVC, "called reset_type=0x{:08X} : created handle=0x{:08X}", reset_type,
|
LOG_TRACE(Kernel_SVC, "called reset_type=0x{:08X} : created handle=0x{:08X}", reset_type,
|
||||||
*out_handle);
|
*out_handle);
|
||||||
|
@ -960,7 +995,9 @@ static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) {
|
||||||
|
|
||||||
/// Duplicates a kernel handle
|
/// Duplicates a kernel handle
|
||||||
static ResultCode DuplicateHandle(Handle* out, Handle handle) {
|
static ResultCode DuplicateHandle(Handle* out, Handle handle) {
|
||||||
CASCADE_RESULT(*out, g_handle_table.Duplicate(handle));
|
CASCADE_RESULT(
|
||||||
|
*out,
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Duplicate(handle));
|
||||||
LOG_TRACE(Kernel_SVC, "duplicated 0x{:08X} to 0x{:08X}", handle, *out);
|
LOG_TRACE(Kernel_SVC, "duplicated 0x{:08X} to 0x{:08X}", handle, *out);
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -969,7 +1006,8 @@ static ResultCode DuplicateHandle(Handle* out, Handle handle) {
|
||||||
static ResultCode SignalEvent(Handle handle) {
|
static ResultCode SignalEvent(Handle handle) {
|
||||||
LOG_TRACE(Kernel_SVC, "called event=0x{:08X}", handle);
|
LOG_TRACE(Kernel_SVC, "called event=0x{:08X}", handle);
|
||||||
|
|
||||||
SharedPtr<Event> evt = g_handle_table.Get<Event>(handle);
|
SharedPtr<Event> evt =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<Event>(handle);
|
||||||
if (evt == nullptr)
|
if (evt == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -982,7 +1020,8 @@ static ResultCode SignalEvent(Handle handle) {
|
||||||
static ResultCode ClearEvent(Handle handle) {
|
static ResultCode ClearEvent(Handle handle) {
|
||||||
LOG_TRACE(Kernel_SVC, "called event=0x{:08X}", handle);
|
LOG_TRACE(Kernel_SVC, "called event=0x{:08X}", handle);
|
||||||
|
|
||||||
SharedPtr<Event> evt = g_handle_table.Get<Event>(handle);
|
SharedPtr<Event> evt =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<Event>(handle);
|
||||||
if (evt == nullptr)
|
if (evt == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -992,9 +1031,10 @@ static ResultCode ClearEvent(Handle handle) {
|
||||||
|
|
||||||
/// Creates a timer
|
/// Creates a timer
|
||||||
static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) {
|
static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) {
|
||||||
SharedPtr<Timer> timer = Core::System::GetInstance().Kernel().CreateTimer(
|
KernelSystem& kernel = Core::System::GetInstance().Kernel();
|
||||||
|
SharedPtr<Timer> timer = kernel.CreateTimer(
|
||||||
static_cast<ResetType>(reset_type), fmt ::format("timer-{:08x}", Core::CPU().GetReg(14)));
|
static_cast<ResetType>(reset_type), fmt ::format("timer-{:08x}", Core::CPU().GetReg(14)));
|
||||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(timer)));
|
CASCADE_RESULT(*out_handle, kernel.GetCurrentProcess()->handle_table.Create(std::move(timer)));
|
||||||
|
|
||||||
LOG_TRACE(Kernel_SVC, "called reset_type=0x{:08X} : created handle=0x{:08X}", reset_type,
|
LOG_TRACE(Kernel_SVC, "called reset_type=0x{:08X} : created handle=0x{:08X}", reset_type,
|
||||||
*out_handle);
|
*out_handle);
|
||||||
|
@ -1005,7 +1045,8 @@ static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) {
|
||||||
static ResultCode ClearTimer(Handle handle) {
|
static ResultCode ClearTimer(Handle handle) {
|
||||||
LOG_TRACE(Kernel_SVC, "called timer=0x{:08X}", handle);
|
LOG_TRACE(Kernel_SVC, "called timer=0x{:08X}", handle);
|
||||||
|
|
||||||
SharedPtr<Timer> timer = g_handle_table.Get<Timer>(handle);
|
SharedPtr<Timer> timer =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<Timer>(handle);
|
||||||
if (timer == nullptr)
|
if (timer == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -1021,7 +1062,8 @@ static ResultCode SetTimer(Handle handle, s64 initial, s64 interval) {
|
||||||
return ERR_OUT_OF_RANGE_KERNEL;
|
return ERR_OUT_OF_RANGE_KERNEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<Timer> timer = g_handle_table.Get<Timer>(handle);
|
SharedPtr<Timer> timer =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<Timer>(handle);
|
||||||
if (timer == nullptr)
|
if (timer == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -1034,7 +1076,8 @@ static ResultCode SetTimer(Handle handle, s64 initial, s64 interval) {
|
||||||
static ResultCode CancelTimer(Handle handle) {
|
static ResultCode CancelTimer(Handle handle) {
|
||||||
LOG_TRACE(Kernel_SVC, "called timer=0x{:08X}", handle);
|
LOG_TRACE(Kernel_SVC, "called timer=0x{:08X}", handle);
|
||||||
|
|
||||||
SharedPtr<Timer> timer = g_handle_table.Get<Timer>(handle);
|
SharedPtr<Timer> timer =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<Timer>(handle);
|
||||||
if (timer == nullptr)
|
if (timer == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
@ -1116,7 +1159,7 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32
|
||||||
shared_memory = Core::System::GetInstance().Kernel().CreateSharedMemory(
|
shared_memory = Core::System::GetInstance().Kernel().CreateSharedMemory(
|
||||||
current_process, size, static_cast<MemoryPermission>(my_permission),
|
current_process, size, static_cast<MemoryPermission>(my_permission),
|
||||||
static_cast<MemoryPermission>(other_permission), addr, region);
|
static_cast<MemoryPermission>(other_permission), addr, region);
|
||||||
CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(shared_memory)));
|
CASCADE_RESULT(*out_handle, current_process->handle_table.Create(std::move(shared_memory)));
|
||||||
|
|
||||||
LOG_WARNING(Kernel_SVC, "called addr=0x{:08X}", addr);
|
LOG_WARNING(Kernel_SVC, "called addr=0x{:08X}", addr);
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
|
@ -1127,48 +1170,58 @@ static ResultCode CreatePort(Handle* server_port, Handle* client_port, VAddr nam
|
||||||
// TODO(Subv): Implement named ports.
|
// TODO(Subv): Implement named ports.
|
||||||
ASSERT_MSG(name_address == 0, "Named ports are currently unimplemented");
|
ASSERT_MSG(name_address == 0, "Named ports are currently unimplemented");
|
||||||
|
|
||||||
auto ports = Core::System::GetInstance().Kernel().CreatePortPair(max_sessions);
|
KernelSystem& kernel = Core::System::GetInstance().Kernel();
|
||||||
CASCADE_RESULT(*client_port,
|
SharedPtr<Process> current_process = kernel.GetCurrentProcess();
|
||||||
g_handle_table.Create(std::move(std::get<SharedPtr<ClientPort>>(ports))));
|
|
||||||
|
auto ports = kernel.CreatePortPair(max_sessions);
|
||||||
|
CASCADE_RESULT(*client_port, current_process->handle_table.Create(
|
||||||
|
std::move(std::get<SharedPtr<ClientPort>>(ports))));
|
||||||
// Note: The 3DS kernel also leaks the client port handle if the server port handle fails to be
|
// Note: The 3DS kernel also leaks the client port handle if the server port handle fails to be
|
||||||
// created.
|
// created.
|
||||||
CASCADE_RESULT(*server_port,
|
CASCADE_RESULT(*server_port, current_process->handle_table.Create(
|
||||||
g_handle_table.Create(std::move(std::get<SharedPtr<ServerPort>>(ports))));
|
std::move(std::get<SharedPtr<ServerPort>>(ports))));
|
||||||
|
|
||||||
LOG_TRACE(Kernel_SVC, "called max_sessions={}", max_sessions);
|
LOG_TRACE(Kernel_SVC, "called max_sessions={}", max_sessions);
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ResultCode CreateSessionToPort(Handle* out_client_session, Handle client_port_handle) {
|
static ResultCode CreateSessionToPort(Handle* out_client_session, Handle client_port_handle) {
|
||||||
SharedPtr<ClientPort> client_port = g_handle_table.Get<ClientPort>(client_port_handle);
|
SharedPtr<Process> current_process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||||
|
SharedPtr<ClientPort> client_port =
|
||||||
|
current_process->handle_table.Get<ClientPort>(client_port_handle);
|
||||||
if (client_port == nullptr)
|
if (client_port == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
CASCADE_RESULT(auto session, client_port->Connect());
|
CASCADE_RESULT(auto session, client_port->Connect());
|
||||||
CASCADE_RESULT(*out_client_session, g_handle_table.Create(std::move(session)));
|
CASCADE_RESULT(*out_client_session, current_process->handle_table.Create(std::move(session)));
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ResultCode CreateSession(Handle* server_session, Handle* client_session) {
|
static ResultCode CreateSession(Handle* server_session, Handle* client_session) {
|
||||||
auto sessions = Core::System::GetInstance().Kernel().CreateSessionPair();
|
KernelSystem& kernel = Core::System::GetInstance().Kernel();
|
||||||
|
auto sessions = kernel.CreateSessionPair();
|
||||||
|
|
||||||
|
SharedPtr<Process> current_process = kernel.GetCurrentProcess();
|
||||||
|
|
||||||
auto& server = std::get<SharedPtr<ServerSession>>(sessions);
|
auto& server = std::get<SharedPtr<ServerSession>>(sessions);
|
||||||
CASCADE_RESULT(*server_session, g_handle_table.Create(std::move(server)));
|
CASCADE_RESULT(*server_session, current_process->handle_table.Create(std::move(server)));
|
||||||
|
|
||||||
auto& client = std::get<SharedPtr<ClientSession>>(sessions);
|
auto& client = std::get<SharedPtr<ClientSession>>(sessions);
|
||||||
CASCADE_RESULT(*client_session, g_handle_table.Create(std::move(client)));
|
CASCADE_RESULT(*client_session, current_process->handle_table.Create(std::move(client)));
|
||||||
|
|
||||||
LOG_TRACE(Kernel_SVC, "called");
|
LOG_TRACE(Kernel_SVC, "called");
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ResultCode AcceptSession(Handle* out_server_session, Handle server_port_handle) {
|
static ResultCode AcceptSession(Handle* out_server_session, Handle server_port_handle) {
|
||||||
SharedPtr<ServerPort> server_port = g_handle_table.Get<ServerPort>(server_port_handle);
|
SharedPtr<Process> current_process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||||
|
SharedPtr<ServerPort> server_port =
|
||||||
|
current_process->handle_table.Get<ServerPort>(server_port_handle);
|
||||||
if (server_port == nullptr)
|
if (server_port == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
CASCADE_RESULT(auto session, server_port->Accept());
|
CASCADE_RESULT(auto session, server_port->Accept());
|
||||||
CASCADE_RESULT(*out_server_session, g_handle_table.Create(std::move(session)));
|
CASCADE_RESULT(*out_server_session, current_process->handle_table.Create(std::move(session)));
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1218,7 +1271,9 @@ static ResultCode GetSystemInfo(s64* out, u32 type, s32 param) {
|
||||||
static ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type) {
|
static ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type) {
|
||||||
LOG_TRACE(Kernel_SVC, "called process=0x{:08X} type={}", process_handle, type);
|
LOG_TRACE(Kernel_SVC, "called process=0x{:08X} type={}", process_handle, type);
|
||||||
|
|
||||||
SharedPtr<Process> process = g_handle_table.Get<Process>(process_handle);
|
SharedPtr<Process> process =
|
||||||
|
Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get<Process>(
|
||||||
|
process_handle);
|
||||||
if (process == nullptr)
|
if (process == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@ void ServiceFrameworkBase::HandleSyncRequest(SharedPtr<ServerSession> server_ses
|
||||||
// TODO(yuriks): The kernel should be the one handling this as part of translation after
|
// TODO(yuriks): The kernel should be the one handling this as part of translation after
|
||||||
// everything else is migrated
|
// everything else is migrated
|
||||||
Kernel::HLERequestContext context(std::move(server_session));
|
Kernel::HLERequestContext context(std::move(server_session));
|
||||||
context.PopulateFromIncomingCommandBuffer(cmd_buf, *current_process, Kernel::g_handle_table);
|
context.PopulateFromIncomingCommandBuffer(cmd_buf, *current_process);
|
||||||
|
|
||||||
LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName().c_str(), cmd_buf));
|
LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName().c_str(), cmd_buf));
|
||||||
handler_invoker(this, info->handler_callback, context);
|
handler_invoker(this, info->handler_callback, context);
|
||||||
|
@ -206,7 +206,7 @@ void ServiceFrameworkBase::HandleSyncRequest(SharedPtr<ServerSession> server_ses
|
||||||
// the thread to sleep then the writing of the command buffer will be deferred to the wakeup
|
// the thread to sleep then the writing of the command buffer will be deferred to the wakeup
|
||||||
// callback.
|
// callback.
|
||||||
if (thread->status == Kernel::ThreadStatus::Running) {
|
if (thread->status == Kernel::ThreadStatus::Running) {
|
||||||
context.WriteToOutgoingCommandBuffer(cmd_buf, *current_process, Kernel::g_handle_table);
|
context.WriteToOutgoingCommandBuffer(cmd_buf, *current_process);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,14 +26,13 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
HLERequestContext context(std::move(session));
|
HLERequestContext context(std::move(session));
|
||||||
|
|
||||||
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
||||||
HandleTable handle_table;
|
|
||||||
|
|
||||||
SECTION("works with empty cmdbuf") {
|
SECTION("works with empty cmdbuf") {
|
||||||
const u32_le input[]{
|
const u32_le input[]{
|
||||||
IPC::MakeHeader(0x1234, 0, 0),
|
IPC::MakeHeader(0x1234, 0, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
context.PopulateFromIncomingCommandBuffer(input, *process, handle_table);
|
context.PopulateFromIncomingCommandBuffer(input, *process);
|
||||||
|
|
||||||
REQUIRE(context.CommandBuffer()[0] == 0x12340000);
|
REQUIRE(context.CommandBuffer()[0] == 0x12340000);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +45,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
0xAABBCCDD,
|
0xAABBCCDD,
|
||||||
};
|
};
|
||||||
|
|
||||||
context.PopulateFromIncomingCommandBuffer(input, *process, handle_table);
|
context.PopulateFromIncomingCommandBuffer(input, *process);
|
||||||
|
|
||||||
auto* output = context.CommandBuffer();
|
auto* output = context.CommandBuffer();
|
||||||
REQUIRE(output[1] == 0x12345678);
|
REQUIRE(output[1] == 0x12345678);
|
||||||
|
@ -56,34 +55,34 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
|
|
||||||
SECTION("translates move handles") {
|
SECTION("translates move handles") {
|
||||||
auto a = MakeObject(kernel);
|
auto a = MakeObject(kernel);
|
||||||
Handle a_handle = handle_table.Create(a).Unwrap();
|
Handle a_handle = process->handle_table.Create(a).Unwrap();
|
||||||
const u32_le input[]{
|
const u32_le input[]{
|
||||||
IPC::MakeHeader(0, 0, 2),
|
IPC::MakeHeader(0, 0, 2),
|
||||||
IPC::MoveHandleDesc(1),
|
IPC::MoveHandleDesc(1),
|
||||||
a_handle,
|
a_handle,
|
||||||
};
|
};
|
||||||
|
|
||||||
context.PopulateFromIncomingCommandBuffer(input, *process, handle_table);
|
context.PopulateFromIncomingCommandBuffer(input, *process);
|
||||||
|
|
||||||
auto* output = context.CommandBuffer();
|
auto* output = context.CommandBuffer();
|
||||||
REQUIRE(context.GetIncomingHandle(output[2]) == a);
|
REQUIRE(context.GetIncomingHandle(output[2]) == a);
|
||||||
REQUIRE(handle_table.GetGeneric(a_handle) == nullptr);
|
REQUIRE(process->handle_table.GetGeneric(a_handle) == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("translates copy handles") {
|
SECTION("translates copy handles") {
|
||||||
auto a = MakeObject(kernel);
|
auto a = MakeObject(kernel);
|
||||||
Handle a_handle = handle_table.Create(a).Unwrap();
|
Handle a_handle = process->handle_table.Create(a).Unwrap();
|
||||||
const u32_le input[]{
|
const u32_le input[]{
|
||||||
IPC::MakeHeader(0, 0, 2),
|
IPC::MakeHeader(0, 0, 2),
|
||||||
IPC::CopyHandleDesc(1),
|
IPC::CopyHandleDesc(1),
|
||||||
a_handle,
|
a_handle,
|
||||||
};
|
};
|
||||||
|
|
||||||
context.PopulateFromIncomingCommandBuffer(input, *process, handle_table);
|
context.PopulateFromIncomingCommandBuffer(input, *process);
|
||||||
|
|
||||||
auto* output = context.CommandBuffer();
|
auto* output = context.CommandBuffer();
|
||||||
REQUIRE(context.GetIncomingHandle(output[2]) == a);
|
REQUIRE(context.GetIncomingHandle(output[2]) == a);
|
||||||
REQUIRE(handle_table.GetGeneric(a_handle) == a);
|
REQUIRE(process->handle_table.GetGeneric(a_handle) == a);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("translates multi-handle descriptors") {
|
SECTION("translates multi-handle descriptors") {
|
||||||
|
@ -91,12 +90,15 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
auto b = MakeObject(kernel);
|
auto b = MakeObject(kernel);
|
||||||
auto c = MakeObject(kernel);
|
auto c = MakeObject(kernel);
|
||||||
const u32_le input[]{
|
const u32_le input[]{
|
||||||
IPC::MakeHeader(0, 0, 5), IPC::MoveHandleDesc(2),
|
IPC::MakeHeader(0, 0, 5),
|
||||||
handle_table.Create(a).Unwrap(), handle_table.Create(b).Unwrap(),
|
IPC::MoveHandleDesc(2),
|
||||||
IPC::MoveHandleDesc(1), handle_table.Create(c).Unwrap(),
|
process->handle_table.Create(a).Unwrap(),
|
||||||
|
process->handle_table.Create(b).Unwrap(),
|
||||||
|
IPC::MoveHandleDesc(1),
|
||||||
|
process->handle_table.Create(c).Unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
context.PopulateFromIncomingCommandBuffer(input, *process, handle_table);
|
context.PopulateFromIncomingCommandBuffer(input, *process);
|
||||||
|
|
||||||
auto* output = context.CommandBuffer();
|
auto* output = context.CommandBuffer();
|
||||||
REQUIRE(context.GetIncomingHandle(output[2]) == a);
|
REQUIRE(context.GetIncomingHandle(output[2]) == a);
|
||||||
|
@ -111,7 +113,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
auto result = context.PopulateFromIncomingCommandBuffer(input, *process, handle_table);
|
auto result = context.PopulateFromIncomingCommandBuffer(input, *process);
|
||||||
|
|
||||||
REQUIRE(result == RESULT_SUCCESS);
|
REQUIRE(result == RESULT_SUCCESS);
|
||||||
auto* output = context.CommandBuffer();
|
auto* output = context.CommandBuffer();
|
||||||
|
@ -125,7 +127,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
0x98989898,
|
0x98989898,
|
||||||
};
|
};
|
||||||
|
|
||||||
context.PopulateFromIncomingCommandBuffer(input, *process, handle_table);
|
context.PopulateFromIncomingCommandBuffer(input, *process);
|
||||||
|
|
||||||
REQUIRE(context.CommandBuffer()[2] == process->process_id);
|
REQUIRE(context.CommandBuffer()[2] == process->process_id);
|
||||||
}
|
}
|
||||||
|
@ -145,7 +147,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
target_address,
|
target_address,
|
||||||
};
|
};
|
||||||
|
|
||||||
context.PopulateFromIncomingCommandBuffer(input, *process, handle_table);
|
context.PopulateFromIncomingCommandBuffer(input, *process);
|
||||||
|
|
||||||
CHECK(context.GetStaticBuffer(0) == *buffer);
|
CHECK(context.GetStaticBuffer(0) == *buffer);
|
||||||
|
|
||||||
|
@ -166,7 +168,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
target_address,
|
target_address,
|
||||||
};
|
};
|
||||||
|
|
||||||
context.PopulateFromIncomingCommandBuffer(input, *process, handle_table);
|
context.PopulateFromIncomingCommandBuffer(input, *process);
|
||||||
|
|
||||||
std::vector<u8> other_buffer(buffer->size());
|
std::vector<u8> other_buffer(buffer->size());
|
||||||
context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer->size());
|
context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer->size());
|
||||||
|
@ -199,7 +201,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
0x12345678,
|
0x12345678,
|
||||||
0xABCDEF00,
|
0xABCDEF00,
|
||||||
IPC::MoveHandleDesc(1),
|
IPC::MoveHandleDesc(1),
|
||||||
handle_table.Create(a).Unwrap(),
|
process->handle_table.Create(a).Unwrap(),
|
||||||
IPC::CallingPidDesc(),
|
IPC::CallingPidDesc(),
|
||||||
0,
|
0,
|
||||||
IPC::StaticBufferDesc(buffer_static->size(), 0),
|
IPC::StaticBufferDesc(buffer_static->size(), 0),
|
||||||
|
@ -208,7 +210,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
target_address_mapped,
|
target_address_mapped,
|
||||||
};
|
};
|
||||||
|
|
||||||
context.PopulateFromIncomingCommandBuffer(input, *process, handle_table);
|
context.PopulateFromIncomingCommandBuffer(input, *process);
|
||||||
|
|
||||||
auto* output = context.CommandBuffer();
|
auto* output = context.CommandBuffer();
|
||||||
CHECK(output[1] == 0x12345678);
|
CHECK(output[1] == 0x12345678);
|
||||||
|
@ -236,14 +238,13 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
||||||
HLERequestContext context(std::move(session));
|
HLERequestContext context(std::move(session));
|
||||||
|
|
||||||
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
|
||||||
HandleTable handle_table;
|
|
||||||
auto* input = context.CommandBuffer();
|
auto* input = context.CommandBuffer();
|
||||||
u32_le output[IPC::COMMAND_BUFFER_LENGTH];
|
u32_le output[IPC::COMMAND_BUFFER_LENGTH];
|
||||||
|
|
||||||
SECTION("works with empty cmdbuf") {
|
SECTION("works with empty cmdbuf") {
|
||||||
input[0] = IPC::MakeHeader(0x1234, 0, 0);
|
input[0] = IPC::MakeHeader(0x1234, 0, 0);
|
||||||
|
|
||||||
context.WriteToOutgoingCommandBuffer(output, *process, handle_table);
|
context.WriteToOutgoingCommandBuffer(output, *process);
|
||||||
|
|
||||||
REQUIRE(output[0] == 0x12340000);
|
REQUIRE(output[0] == 0x12340000);
|
||||||
}
|
}
|
||||||
|
@ -254,7 +255,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
||||||
input[2] = 0x21122112;
|
input[2] = 0x21122112;
|
||||||
input[3] = 0xAABBCCDD;
|
input[3] = 0xAABBCCDD;
|
||||||
|
|
||||||
context.WriteToOutgoingCommandBuffer(output, *process, handle_table);
|
context.WriteToOutgoingCommandBuffer(output, *process);
|
||||||
|
|
||||||
REQUIRE(output[1] == 0x12345678);
|
REQUIRE(output[1] == 0x12345678);
|
||||||
REQUIRE(output[2] == 0x21122112);
|
REQUIRE(output[2] == 0x21122112);
|
||||||
|
@ -270,10 +271,10 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
||||||
input[3] = IPC::CopyHandleDesc(1);
|
input[3] = IPC::CopyHandleDesc(1);
|
||||||
input[4] = context.AddOutgoingHandle(b);
|
input[4] = context.AddOutgoingHandle(b);
|
||||||
|
|
||||||
context.WriteToOutgoingCommandBuffer(output, *process, handle_table);
|
context.WriteToOutgoingCommandBuffer(output, *process);
|
||||||
|
|
||||||
REQUIRE(handle_table.GetGeneric(output[2]) == a);
|
REQUIRE(process->handle_table.GetGeneric(output[2]) == a);
|
||||||
REQUIRE(handle_table.GetGeneric(output[4]) == b);
|
REQUIRE(process->handle_table.GetGeneric(output[4]) == b);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("translates null handles") {
|
SECTION("translates null handles") {
|
||||||
|
@ -281,7 +282,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
||||||
input[1] = IPC::MoveHandleDesc(1);
|
input[1] = IPC::MoveHandleDesc(1);
|
||||||
input[2] = context.AddOutgoingHandle(nullptr);
|
input[2] = context.AddOutgoingHandle(nullptr);
|
||||||
|
|
||||||
auto result = context.WriteToOutgoingCommandBuffer(output, *process, handle_table);
|
auto result = context.WriteToOutgoingCommandBuffer(output, *process);
|
||||||
|
|
||||||
REQUIRE(result == RESULT_SUCCESS);
|
REQUIRE(result == RESULT_SUCCESS);
|
||||||
REQUIRE(output[2] == 0);
|
REQUIRE(output[2] == 0);
|
||||||
|
@ -298,11 +299,11 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
||||||
input[4] = IPC::CopyHandleDesc(1);
|
input[4] = IPC::CopyHandleDesc(1);
|
||||||
input[5] = context.AddOutgoingHandle(c);
|
input[5] = context.AddOutgoingHandle(c);
|
||||||
|
|
||||||
context.WriteToOutgoingCommandBuffer(output, *process, handle_table);
|
context.WriteToOutgoingCommandBuffer(output, *process);
|
||||||
|
|
||||||
REQUIRE(handle_table.GetGeneric(output[2]) == a);
|
REQUIRE(process->handle_table.GetGeneric(output[2]) == a);
|
||||||
REQUIRE(handle_table.GetGeneric(output[3]) == b);
|
REQUIRE(process->handle_table.GetGeneric(output[3]) == b);
|
||||||
REQUIRE(handle_table.GetGeneric(output[5]) == c);
|
REQUIRE(process->handle_table.GetGeneric(output[5]) == c);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("translates StaticBuffer descriptors") {
|
SECTION("translates StaticBuffer descriptors") {
|
||||||
|
@ -329,7 +330,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
||||||
IPC::StaticBufferDesc(output_buffer->size(), 0);
|
IPC::StaticBufferDesc(output_buffer->size(), 0);
|
||||||
output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH + 1] = target_address;
|
output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH + 1] = target_address;
|
||||||
|
|
||||||
context.WriteToOutgoingCommandBuffer(output_cmdbuff.data(), *process, handle_table);
|
context.WriteToOutgoingCommandBuffer(output_cmdbuff.data(), *process);
|
||||||
|
|
||||||
CHECK(*output_buffer == input_buffer);
|
CHECK(*output_buffer == input_buffer);
|
||||||
REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer->size()) ==
|
REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer->size()) ==
|
||||||
|
@ -352,7 +353,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
||||||
target_address,
|
target_address,
|
||||||
};
|
};
|
||||||
|
|
||||||
context.PopulateFromIncomingCommandBuffer(input_cmdbuff, *process, handle_table);
|
context.PopulateFromIncomingCommandBuffer(input_cmdbuff, *process);
|
||||||
|
|
||||||
context.GetMappedBuffer(0).Write(input_buffer.data(), 0, input_buffer.size());
|
context.GetMappedBuffer(0).Write(input_buffer.data(), 0, input_buffer.size());
|
||||||
|
|
||||||
|
@ -360,7 +361,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
||||||
input[1] = IPC::MappedBufferDesc(output_buffer->size(), IPC::W);
|
input[1] = IPC::MappedBufferDesc(output_buffer->size(), IPC::W);
|
||||||
input[2] = 0;
|
input[2] = 0;
|
||||||
|
|
||||||
context.WriteToOutgoingCommandBuffer(output, *process, handle_table);
|
context.WriteToOutgoingCommandBuffer(output, *process);
|
||||||
|
|
||||||
CHECK(output[1] == IPC::MappedBufferDesc(output_buffer->size(), IPC::W));
|
CHECK(output[1] == IPC::MappedBufferDesc(output_buffer->size(), IPC::W));
|
||||||
CHECK(output[2] == target_address);
|
CHECK(output[2] == target_address);
|
||||||
|
|
Reference in New Issue