citra-emu
/
citra
Archived
1
0
Fork 0

HLE/IPC: pass in kernel & memory reference from parent to avoid global state reference

This commit is contained in:
Weiyi Wang 2019-02-02 15:55:45 -05:00
parent 0a424b86d2
commit 3f86be88f0
4 changed files with 26 additions and 21 deletions

View File

@ -48,7 +48,7 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
// the translation might need to read from it in order to retrieve the StaticBuffer // the translation might need to read from it in order to retrieve the StaticBuffer
// target addresses. // target addresses.
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::MemorySystem& memory = Core::System::GetInstance().Memory(); Memory::MemorySystem& memory = context.kernel.memory;
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); context.WriteToOutgoingCommandBuffer(cmd_buff.data(), *process);
@ -57,8 +57,7 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
cmd_buff.size() * sizeof(u32)); cmd_buff.size() * sizeof(u32));
}; };
auto event = Core::System::GetInstance().Kernel().CreateEvent(Kernel::ResetType::OneShot, auto event = kernel.CreateEvent(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason);
"HLE Pause Event: " + reason);
thread->status = ThreadStatus::WaitHleEvent; thread->status = ThreadStatus::WaitHleEvent;
thread->wait_objects = {event}; thread->wait_objects = {event};
event->AddWaitingThread(thread); event->AddWaitingThread(thread);
@ -69,8 +68,8 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
return event; return event;
} }
HLERequestContext::HLERequestContext(SharedPtr<ServerSession> session) HLERequestContext::HLERequestContext(KernelSystem& kernel, SharedPtr<ServerSession> session)
: session(std::move(session)) { : kernel(kernel), session(std::move(session)) {
cmd_buf[0] = 0; cmd_buf[0] = 0;
} }
@ -143,8 +142,7 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr
// Copy the input buffer into our own vector and store it. // Copy the input buffer into our own vector and store it.
std::vector<u8> data(buffer_info.size); std::vector<u8> data(buffer_info.size);
Core::System::GetInstance().Memory().ReadBlock(src_process, source_address, data.data(), kernel.memory.ReadBlock(src_process, source_address, data.data(), data.size());
data.size());
AddStaticBuffer(buffer_info.buffer_id, std::move(data)); AddStaticBuffer(buffer_info.buffer_id, std::move(data));
cmd_buf[i++] = source_address; cmd_buf[i++] = source_address;
@ -152,7 +150,8 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr
} }
case IPC::DescriptorType::MappedBuffer: { case IPC::DescriptorType::MappedBuffer: {
u32 next_id = static_cast<u32>(request_mapped_buffers.size()); u32 next_id = static_cast<u32>(request_mapped_buffers.size());
request_mapped_buffers.emplace_back(src_process, descriptor, src_cmdbuf[i], next_id); request_mapped_buffers.emplace_back(kernel.memory, src_process, descriptor,
src_cmdbuf[i], next_id);
cmd_buf[i++] = next_id; cmd_buf[i++] = next_id;
break; break;
} }
@ -211,8 +210,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf,
ASSERT_MSG(target_descriptor.size >= data.size(), "Static buffer data is too big"); ASSERT_MSG(target_descriptor.size >= data.size(), "Static buffer data is too big");
Core::System::GetInstance().Memory().WriteBlock(dst_process, target_address, kernel.memory.WriteBlock(dst_process, target_address, data.data(), data.size());
data.data(), data.size());
dst_cmdbuf[i++] = target_address; dst_cmdbuf[i++] = target_address;
break; break;
@ -235,8 +233,9 @@ MappedBuffer& HLERequestContext::GetMappedBuffer(u32 id_from_cmdbuf) {
return request_mapped_buffers[id_from_cmdbuf]; return request_mapped_buffers[id_from_cmdbuf];
} }
MappedBuffer::MappedBuffer(const Process& process, u32 descriptor, VAddr address, u32 id) MappedBuffer::MappedBuffer(Memory::MemorySystem& memory, const Process& process, u32 descriptor,
: id(id), address(address), process(&process) { VAddr address, u32 id)
: memory(&memory), id(id), address(address), process(&process) {
IPC::MappedBufferDescInfo desc{descriptor}; IPC::MappedBufferDescInfo desc{descriptor};
size = desc.size; size = desc.size;
perms = desc.perms; perms = desc.perms;
@ -245,15 +244,13 @@ MappedBuffer::MappedBuffer(const Process& process, u32 descriptor, VAddr address
void MappedBuffer::Read(void* dest_buffer, std::size_t offset, std::size_t size) { void MappedBuffer::Read(void* dest_buffer, std::size_t offset, std::size_t size) {
ASSERT(perms & IPC::R); ASSERT(perms & IPC::R);
ASSERT(offset + size <= this->size); ASSERT(offset + size <= this->size);
Core::System::GetInstance().Memory().ReadBlock(*process, address + static_cast<VAddr>(offset), memory->ReadBlock(*process, address + static_cast<VAddr>(offset), dest_buffer, size);
dest_buffer, size);
} }
void MappedBuffer::Write(const void* src_buffer, std::size_t offset, std::size_t size) { void MappedBuffer::Write(const void* src_buffer, std::size_t offset, std::size_t size) {
ASSERT(perms & IPC::W); ASSERT(perms & IPC::W);
ASSERT(offset + size <= this->size); ASSERT(offset + size <= this->size);
Core::System::GetInstance().Memory().WriteBlock(*process, address + static_cast<VAddr>(offset), memory->WriteBlock(*process, address + static_cast<VAddr>(offset), src_buffer, size);
src_buffer, size);
} }
} // namespace Kernel } // namespace Kernel

View File

@ -21,6 +21,10 @@ namespace Service {
class ServiceFrameworkBase; class ServiceFrameworkBase;
} }
namespace Memory {
class MemorySystem;
}
namespace Kernel { namespace Kernel {
class HandleTable; class HandleTable;
@ -28,6 +32,7 @@ class Process;
class Thread; class Thread;
class Event; class Event;
class HLERequestContext; class HLERequestContext;
class KernelSystem;
/** /**
* Interface implemented by HLE Session handlers. * Interface implemented by HLE Session handlers.
@ -93,7 +98,8 @@ protected:
class MappedBuffer { class MappedBuffer {
public: public:
MappedBuffer(const Process& process, u32 descriptor, VAddr address, u32 id); MappedBuffer(Memory::MemorySystem& memory, const Process& process, u32 descriptor,
VAddr address, u32 id);
// interface for service // interface for service
void Read(void* dest_buffer, std::size_t offset, std::size_t size); void Read(void* dest_buffer, std::size_t offset, std::size_t size);
@ -113,6 +119,7 @@ public:
private: private:
friend class HLERequestContext; friend class HLERequestContext;
Memory::MemorySystem* memory;
u32 id; u32 id;
VAddr address; VAddr address;
const Process* process; const Process* process;
@ -151,7 +158,7 @@ private:
*/ */
class HLERequestContext { class HLERequestContext {
public: public:
HLERequestContext(SharedPtr<ServerSession> session); HLERequestContext(KernelSystem& kernel, SharedPtr<ServerSession> session);
~HLERequestContext(); ~HLERequestContext();
/// Returns a pointer to the IPC command buffer for this request. /// Returns a pointer to the IPC command buffer for this request.
@ -228,6 +235,7 @@ public:
ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process) const; ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process) const;
private: private:
KernelSystem& kernel;
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
SharedPtr<ServerSession> session; SharedPtr<ServerSession> session;
// TODO(yuriks): Check common usage of this and optimize size accordingly // TODO(yuriks): Check common usage of this and optimize size accordingly

View File

@ -71,7 +71,7 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
kernel.memory.ReadBlock(*current_process, thread->GetCommandBufferAddress(), cmd_buf.data(), kernel.memory.ReadBlock(*current_process, thread->GetCommandBufferAddress(), cmd_buf.data(),
cmd_buf.size() * sizeof(u32)); cmd_buf.size() * sizeof(u32));
Kernel::HLERequestContext context(this); Kernel::HLERequestContext context(kernel, this);
context.PopulateFromIncomingCommandBuffer(cmd_buf.data(), *current_process); context.PopulateFromIncomingCommandBuffer(cmd_buf.data(), *current_process);
hle_handler->HandleSyncRequest(context); hle_handler->HandleSyncRequest(context);

View File

@ -26,7 +26,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
auto memory = std::make_unique<Memory::MemorySystem>(); auto memory = std::make_unique<Memory::MemorySystem>();
Kernel::KernelSystem kernel(*memory, 0); Kernel::KernelSystem kernel(*memory, 0);
auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair()); auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair());
HLERequestContext context(std::move(session)); HLERequestContext context(kernel, std::move(session));
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
@ -239,7 +239,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
auto memory = std::make_unique<Memory::MemorySystem>(); auto memory = std::make_unique<Memory::MemorySystem>();
Kernel::KernelSystem kernel(*memory, 0); Kernel::KernelSystem kernel(*memory, 0);
auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair()); auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair());
HLERequestContext context(std::move(session)); HLERequestContext context(kernel, std::move(session));
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
auto* input = context.CommandBuffer(); auto* input = context.CommandBuffer();