mirror of
https://github.com/mikage-emu/mikage-dev.git
synced 2025-01-08 14:30:59 +01:00
154 lines
5.7 KiB
C++
154 lines
5.7 KiB
C++
#include "ipc.hpp"
|
|
#include "os.hpp"
|
|
|
|
namespace HLE {
|
|
|
|
namespace IPC {
|
|
|
|
TLSReader::TLSReader(OS::Thread& thread) : thread(thread) {
|
|
}
|
|
|
|
OS::Handle TLSReader::ParseHandle() {
|
|
// TODO: Read the number of handles from the descriptor at "offset" rather
|
|
// than assuming we should only read a single one!
|
|
auto ret = thread.ReadTLS(offset);
|
|
offset += 4;
|
|
return {ret};
|
|
}
|
|
|
|
OS::Result TLSReader::operator()(const IPC::CommandTags::result_tag& /* unused */) {
|
|
uint32_t data = thread.ReadTLS(offset);
|
|
offset += 4;
|
|
return data;
|
|
}
|
|
|
|
uint32_t TLSReader::operator()(const IPC::CommandTags::uint32_tag& /* unused */) {
|
|
uint32_t data = thread.ReadTLS(offset);
|
|
offset += 4;
|
|
return data;
|
|
}
|
|
|
|
uint64_t TLSReader::operator()(const IPC::CommandTags::uint64_tag& /* unused */) {
|
|
uint64_t data = (static_cast<uint64_t>(thread.ReadTLS(offset + 4)) << 32) | thread.ReadTLS(offset);
|
|
offset += 8;
|
|
return data;
|
|
}
|
|
|
|
IPC::StaticBuffer TLSReader::operator()(const IPC::CommandTags::static_buffer_tag& /* unused */) {
|
|
// TLS@offset stores the translation descriptor, which is only relevant for the kernel
|
|
IPC::TranslationDescriptor descriptor = { thread.ReadTLS(offset) };
|
|
uint32_t buffer_addr = thread.ReadTLS(offset + 4);
|
|
offset += 8;
|
|
return { buffer_addr, descriptor.static_buffer.size.Value(), descriptor.static_buffer.id.Value() };
|
|
}
|
|
|
|
IPC::StaticBuffer TLSReader::operator()(const IPC::CommandTags::pxi_buffer_tag<false>& /* unused */) {
|
|
// TLS@offset stores the translation descriptor, which is only relevant for the kernel
|
|
IPC::TranslationDescriptor descriptor = { thread.ReadTLS(offset) };
|
|
uint32_t buffer_addr = thread.ReadTLS(offset + 4);
|
|
offset += 8;
|
|
// TODO: DONT DO THIS. Instead use the commented-out version.
|
|
return { buffer_addr, descriptor.static_buffer.size.Value(), descriptor.static_buffer.id.Value() };
|
|
// return { buffer_addr, descriptor.pxi_buffer.size.Value(), descriptor.pxi_buffer.id.Value() };
|
|
}
|
|
|
|
IPC::StaticBuffer TLSReader::operator()(const IPC::CommandTags::pxi_buffer_tag<true>& /* unused */) {
|
|
// TLS@offset stores the translation descriptor, which is only relevant for the kernel
|
|
IPC::TranslationDescriptor descriptor = { thread.ReadTLS(offset) };
|
|
uint32_t buffer_addr = thread.ReadTLS(offset + 4);
|
|
offset += 8;
|
|
// TODO: DONT DO THIS. Instead use the commented-out version.
|
|
return { buffer_addr, descriptor.static_buffer.size.Value(), descriptor.static_buffer.id.Value() };
|
|
// return { buffer_addr, descriptor.pxi_buffer.size.Value(), descriptor.pxi_buffer.id.Value() };
|
|
}
|
|
|
|
OS::ProcessId TLSReader::operator()(const IPC::CommandTags::process_id_tag& /* unused */) {
|
|
uint32_t process_id = thread.ReadTLS(offset + 4);
|
|
offset += 8;
|
|
return process_id;
|
|
}
|
|
|
|
MappedBuffer TLSReader::operator()(const IPC::CommandTags::map_buffer_r_tag& /* unused */) {
|
|
MappedBuffer ret;
|
|
ret.size = TranslationDescriptor{thread.ReadTLS(offset)}.map_buffer.size;
|
|
ret.addr = thread.ReadTLS(offset + 4);
|
|
offset += 8;
|
|
return ret;
|
|
}
|
|
|
|
MappedBuffer TLSReader::operator()(const IPC::CommandTags::map_buffer_w_tag& /* unused */) {
|
|
MappedBuffer ret;
|
|
ret.size = TranslationDescriptor{thread.ReadTLS(offset)}.map_buffer.size;
|
|
ret.addr = thread.ReadTLS(offset + 4);
|
|
offset += 8;
|
|
return ret;
|
|
}
|
|
|
|
|
|
TLSWriter::TLSWriter(OS::Thread& thread) : thread(thread) {
|
|
}
|
|
|
|
void TLSWriter::WriteHandleDescriptor(const OS::Handle* data, size_t num, bool close) {
|
|
thread.WriteTLS(offset, IPC::TranslationDescriptor::MakeHandles(num, close).raw);
|
|
offset += 4;
|
|
for (auto data_ptr = data; data_ptr != data + num; ++data_ptr) {
|
|
thread.WriteTLS(offset, data_ptr->value);
|
|
offset += 4;
|
|
}
|
|
}
|
|
|
|
void TLSWriter::operator()(IPC::CommandTags::result_tag, OS::Result data) {
|
|
thread.WriteTLS(offset, data);
|
|
offset += 4;
|
|
}
|
|
|
|
void TLSWriter::operator()(IPC::CommandTags::uint32_tag, uint32_t data) {
|
|
thread.WriteTLS(offset, data);
|
|
offset += 4;
|
|
}
|
|
|
|
void TLSWriter::operator()(IPC::CommandTags::uint64_tag, uint64_t data) {
|
|
thread.WriteTLS(offset , data & 0xFFFFFFFF);
|
|
thread.WriteTLS(offset + 4, data >> 32);
|
|
offset += 8;
|
|
}
|
|
|
|
void TLSWriter::operator()(IPC::CommandTags::map_buffer_r_tag, const MappedBuffer& buffer) {
|
|
thread.WriteTLS(offset, IPC::TranslationDescriptor::MapBuffer(buffer.size, TranslationDescriptor::Read).raw);
|
|
thread.WriteTLS(offset + 4, buffer.addr);
|
|
offset += 8;
|
|
}
|
|
|
|
void TLSWriter::operator()(IPC::CommandTags::map_buffer_w_tag, const MappedBuffer& buffer) {
|
|
thread.WriteTLS(offset, IPC::TranslationDescriptor::MapBuffer(buffer.size, TranslationDescriptor::Write).raw);
|
|
thread.WriteTLS(offset + 4, buffer.addr);
|
|
offset += 8;
|
|
}
|
|
|
|
void TLSWriter::operator()(IPC::CommandTags::static_buffer_tag, const StaticBuffer& buffer) {
|
|
thread.WriteTLS(offset, IPC::TranslationDescriptor::MakeStaticBuffer(buffer.id, buffer.size).raw);
|
|
thread.WriteTLS(offset + 4, buffer.addr);
|
|
offset += 8;
|
|
}
|
|
|
|
void TLSWriter::operator()(IPC::CommandTags::process_id_tag, const EmptyValue&) {
|
|
thread.WriteTLS(offset, IPC::TranslationDescriptor::MakeProcessHandle().raw);
|
|
thread.WriteTLS(offset + 4, 0);
|
|
offset += 8;
|
|
}
|
|
|
|
void TLSWriter::operator()(IPC::CommandTags::pxi_buffer_tag<false>, const StaticBuffer& buffer) {
|
|
thread.WriteTLS(offset, IPC::TranslationDescriptor::MakePXIBuffer(buffer.id, buffer.size).raw);
|
|
thread.WriteTLS(offset + 4, buffer.addr);
|
|
offset += 8;
|
|
}
|
|
|
|
void TLSWriter::operator()(IPC::CommandTags::pxi_buffer_tag<true>, const StaticBuffer& buffer) {
|
|
thread.WriteTLS(offset, IPC::TranslationDescriptor::MakePXIConstBuffer(buffer.id, buffer.size).raw);
|
|
thread.WriteTLS(offset + 4, buffer.addr);
|
|
offset += 8;
|
|
}
|
|
|
|
} // namespace IPC
|
|
|
|
} // namespace HLE
|