summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/service/am/am.cpp12
-rw-r--r--src/core/hle/service/audio/audren_u.cpp6
-rw-r--r--src/core/hle/service/audio/hwopus.cpp16
-rw-r--r--src/core/hle/service/fatal/fatal.cpp2
-rw-r--r--src/core/hle/service/hid/hid_server.cpp9
-rw-r--r--src/core/hle/service/hid/hidbus.cpp3
-rw-r--r--src/core/hle/service/hid/irs.cpp6
-rw-r--r--src/core/hle/service/hle_ipc.cpp20
-rw-r--r--src/core/hle/service/hle_ipc.h20
-rw-r--r--src/core/hle/service/ipc_helpers.h4
-rw-r--r--src/core/hle/service/jit/jit.cpp69
-rw-r--r--src/core/hle/service/jit/jit_code_memory.cpp54
-rw-r--r--src/core/hle/service/jit/jit_code_memory.h49
-rw-r--r--src/core/hle/service/ro/ro.cpp12
-rw-r--r--src/core/hle/service/server_manager.cpp21
-rw-r--r--src/core/hle/service/service.cpp2
-rw-r--r--src/core/hle/service/set/set_sys.cpp12
-rw-r--r--src/core/hle/service/set/set_sys.h1
-rw-r--r--src/core/hle/service/sm/sm.cpp36
-rw-r--r--src/core/hle/service/sm/sm.h8
-rw-r--r--src/core/hle/service/sm/sm_controller.cpp7
21 files changed, 241 insertions, 128 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index a266d7c21..97eb56ff0 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -1513,8 +1513,7 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(HLERequestContext& ctx)
return;
}
- auto transfer_mem =
- system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(handle);
+ auto transfer_mem = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(handle);
if (transfer_mem.IsNull()) {
LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
@@ -1524,8 +1523,7 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(HLERequestContext& ctx)
}
std::vector<u8> memory(transfer_mem->GetSize());
- system.ApplicationMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(),
- memory.size());
+ ctx.GetMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size());
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
@@ -1547,8 +1545,7 @@ void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) {
return;
}
- auto transfer_mem =
- system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(handle);
+ auto transfer_mem = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(handle);
if (transfer_mem.IsNull()) {
LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
@@ -1558,8 +1555,7 @@ void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) {
}
std::vector<u8> memory(transfer_mem->GetSize());
- system.ApplicationMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(),
- memory.size());
+ ctx.GetMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size());
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 23e56c77a..bd4ca753b 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -454,10 +454,8 @@ void AudRenU::OpenAudioRenderer(HLERequestContext& ctx) {
return;
}
- const auto& handle_table{system.ApplicationProcess()->GetHandleTable()};
- auto process{handle_table.GetObject<Kernel::KProcess>(process_handle)};
- auto transfer_memory{
- process->GetHandleTable().GetObject<Kernel::KTransferMemory>(transfer_memory_handle)};
+ auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(process_handle)};
+ auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)};
const auto session_id{impl->GetSessionId()};
if (session_id == -1) {
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp
index 6a7bf9416..91f33aabd 100644
--- a/src/core/hle/service/audio/hwopus.cpp
+++ b/src/core/hle/service/audio/hwopus.cpp
@@ -278,9 +278,7 @@ void HwOpus::OpenHardwareOpusDecoder(HLERequestContext& ctx) {
auto params = rp.PopRaw<OpusParameters>();
auto transfer_memory_size{rp.Pop<u32>()};
auto transfer_memory_handle{ctx.GetCopyHandle(0)};
- auto transfer_memory{
- system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
- transfer_memory_handle)};
+ auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)};
LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size 0x{:X}",
params.sample_rate, params.channel_count, transfer_memory_size);
@@ -323,9 +321,7 @@ void HwOpus::OpenHardwareOpusDecoderForMultiStream(HLERequestContext& ctx) {
auto transfer_memory_size{rp.Pop<u32>()};
auto transfer_memory_handle{ctx.GetCopyHandle(0)};
- auto transfer_memory{
- system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
- transfer_memory_handle)};
+ auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)};
LOG_DEBUG(Service_Audio,
"sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} "
@@ -374,9 +370,7 @@ void HwOpus::OpenHardwareOpusDecoderEx(HLERequestContext& ctx) {
auto params = rp.PopRaw<OpusParametersEx>();
auto transfer_memory_size{rp.Pop<u32>()};
auto transfer_memory_handle{ctx.GetCopyHandle(0)};
- auto transfer_memory{
- system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
- transfer_memory_handle)};
+ auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)};
LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size 0x{:X}",
params.sample_rate, params.channel_count, transfer_memory_size);
@@ -414,9 +408,7 @@ void HwOpus::OpenHardwareOpusDecoderForMultiStreamEx(HLERequestContext& ctx) {
auto transfer_memory_size{rp.Pop<u32>()};
auto transfer_memory_handle{ctx.GetCopyHandle(0)};
- auto transfer_memory{
- system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
- transfer_memory_handle)};
+ auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)};
LOG_DEBUG(Service_Audio,
"sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} "
diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp
index fe2ed8df8..31da86074 100644
--- a/src/core/hle/service/fatal/fatal.cpp
+++ b/src/core/hle/service/fatal/fatal.cpp
@@ -89,7 +89,7 @@ static void GenerateErrorReport(Core::System& system, Result error_code, const F
crash_report += fmt::format(" ESR: {:016x}\n", info.esr);
crash_report += fmt::format(" FAR: {:016x}\n", info.far);
crash_report += "\nBacktrace:\n";
- for (size_t i = 0; i < info.backtrace_size; i++) {
+ for (u32 i = 0; i < std::min<u32>(info.backtrace_size, 32); i++) {
crash_report +=
fmt::format(" Backtrace[{:02d}]: {:016x}\n", i, info.backtrace[i]);
}
diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp
index 06a01c02c..3174672af 100644
--- a/src/core/hle/service/hid/hid_server.cpp
+++ b/src/core/hle/service/hid/hid_server.cpp
@@ -1850,8 +1850,7 @@ void IHidServer::InitializeSevenSixAxisSensor(HLERequestContext& ctx) {
ASSERT_MSG(t_mem_1_size == 0x1000, "t_mem_1_size is not 0x1000 bytes");
ASSERT_MSG(t_mem_2_size == 0x7F000, "t_mem_2_size is not 0x7F000 bytes");
- auto t_mem_1 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
- t_mem_1_handle);
+ auto t_mem_1 = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(t_mem_1_handle);
if (t_mem_1.IsNull()) {
LOG_ERROR(Service_HID, "t_mem_1 is a nullptr for handle=0x{:08X}", t_mem_1_handle);
@@ -1860,8 +1859,7 @@ void IHidServer::InitializeSevenSixAxisSensor(HLERequestContext& ctx) {
return;
}
- auto t_mem_2 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
- t_mem_2_handle);
+ auto t_mem_2 = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(t_mem_2_handle);
if (t_mem_2.IsNull()) {
LOG_ERROR(Service_HID, "t_mem_2 is a nullptr for handle=0x{:08X}", t_mem_2_handle);
@@ -2142,8 +2140,7 @@ void IHidServer::WritePalmaWaveEntry(HLERequestContext& ctx) {
ASSERT_MSG(t_mem_size == 0x3000, "t_mem_size is not 0x3000 bytes");
- auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
- t_mem_handle);
+ auto t_mem = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(t_mem_handle);
if (t_mem.IsNull()) {
LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle);
diff --git a/src/core/hle/service/hid/hidbus.cpp b/src/core/hle/service/hid/hidbus.cpp
index 854de2fe2..ffa7e144d 100644
--- a/src/core/hle/service/hid/hidbus.cpp
+++ b/src/core/hle/service/hid/hidbus.cpp
@@ -448,8 +448,7 @@ void HidBus::EnableJoyPollingReceiveMode(HLERequestContext& ctx) {
ASSERT_MSG(t_mem_size == 0x1000, "t_mem_size is not 0x1000 bytes");
- auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
- t_mem_handle);
+ auto t_mem = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(t_mem_handle);
if (t_mem.IsNull()) {
LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle);
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index 39b9a4474..008debfd1 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -197,8 +197,7 @@ void IRS::RunImageTransferProcessor(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
const auto t_mem_handle{ctx.GetCopyHandle(0)};
- auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
- t_mem_handle);
+ auto t_mem = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(t_mem_handle);
if (t_mem.IsNull()) {
LOG_ERROR(Service_IRS, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle);
@@ -444,8 +443,7 @@ void IRS::RunImageTransferExProcessor(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
const auto t_mem_handle{ctx.GetCopyHandle(0)};
- auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
- t_mem_handle);
+ auto t_mem = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(t_mem_handle);
LOG_INFO(Service_IRS,
"called, npad_type={}, npad_id={}, transfer_memory_size={}, "
diff --git a/src/core/hle/service/hle_ipc.cpp b/src/core/hle/service/hle_ipc.cpp
index 38955932c..39df77e43 100644
--- a/src/core/hle/service/hle_ipc.cpp
+++ b/src/core/hle/service/hle_ipc.cpp
@@ -146,10 +146,7 @@ HLERequestContext::HLERequestContext(Kernel::KernelCore& kernel_, Core::Memory::
HLERequestContext::~HLERequestContext() = default;
-void HLERequestContext::ParseCommandBuffer(Kernel::KProcess& process, u32_le* src_cmdbuf,
- bool incoming) {
- client_handle_table = &process.GetHandleTable();
-
+void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
IPC::RequestParser rp(src_cmdbuf);
command_header = rp.PopRaw<IPC::CommandHeader>();
@@ -162,7 +159,7 @@ void HLERequestContext::ParseCommandBuffer(Kernel::KProcess& process, u32_le* sr
if (command_header->enable_handle_descriptor) {
handle_descriptor_header = rp.PopRaw<IPC::HandleDescriptorHeader>();
if (handle_descriptor_header->send_current_pid) {
- pid = process.GetProcessId();
+ pid = thread->GetOwnerProcess()->GetProcessId();
rp.Skip(2, false);
}
if (incoming) {
@@ -270,9 +267,10 @@ void HLERequestContext::ParseCommandBuffer(Kernel::KProcess& process, u32_le* sr
rp.Skip(1, false); // The command is actually an u64, but we don't use the high part.
}
-Result HLERequestContext::PopulateFromIncomingCommandBuffer(Kernel::KProcess& process,
- u32_le* src_cmdbuf) {
- ParseCommandBuffer(process, src_cmdbuf, true);
+Result HLERequestContext::PopulateFromIncomingCommandBuffer(u32_le* src_cmdbuf) {
+ client_handle_table = &thread->GetOwnerProcess()->GetHandleTable();
+
+ ParseCommandBuffer(src_cmdbuf, true);
if (command_header->IsCloseCommand()) {
// Close does not populate the rest of the IPC header
@@ -284,9 +282,9 @@ Result HLERequestContext::PopulateFromIncomingCommandBuffer(Kernel::KProcess& pr
return ResultSuccess;
}
-Result HLERequestContext::WriteToOutgoingCommandBuffer(Kernel::KThread& requesting_thread) {
+Result HLERequestContext::WriteToOutgoingCommandBuffer() {
auto current_offset = handles_offset;
- auto& owner_process = *requesting_thread.GetOwnerProcess();
+ auto& owner_process = *thread->GetOwnerProcess();
auto& handle_table = owner_process.GetHandleTable();
for (auto& object : outgoing_copy_objects) {
@@ -319,7 +317,7 @@ Result HLERequestContext::WriteToOutgoingCommandBuffer(Kernel::KThread& requesti
}
// Copy the translated command buffer back into the thread's command buffer area.
- memory.WriteBlock(requesting_thread.GetTlsAddress(), cmd_buf.data(), write_size * sizeof(u32));
+ memory.WriteBlock(thread->GetTlsAddress(), cmd_buf.data(), write_size * sizeof(u32));
return ResultSuccess;
}
diff --git a/src/core/hle/service/hle_ipc.h b/src/core/hle/service/hle_ipc.h
index 18d464c63..40d86943e 100644
--- a/src/core/hle/service/hle_ipc.h
+++ b/src/core/hle/service/hle_ipc.h
@@ -17,6 +17,7 @@
#include "common/concepts.h"
#include "common/swap.h"
#include "core/hle/ipc.h"
+#include "core/hle/kernel/k_handle_table.h"
#include "core/hle/kernel/svc_common.h"
union Result;
@@ -196,10 +197,10 @@ public:
}
/// Populates this context with data from the requesting process/thread.
- Result PopulateFromIncomingCommandBuffer(Kernel::KProcess& process, u32_le* src_cmdbuf);
+ Result PopulateFromIncomingCommandBuffer(u32_le* src_cmdbuf);
/// Writes data from this context back to the requesting process/thread.
- Result WriteToOutgoingCommandBuffer(Kernel::KThread& requesting_thread);
+ Result WriteToOutgoingCommandBuffer();
[[nodiscard]] u32_le GetHipcCommand() const {
return command;
@@ -359,8 +360,17 @@ public:
return *thread;
}
- Kernel::KHandleTable& GetClientHandleTable() {
- return *client_handle_table;
+ [[nodiscard]] Core::Memory::Memory& GetMemory() const {
+ return memory;
+ }
+
+ template <typename T>
+ Kernel::KScopedAutoObject<T> GetObjectFromHandle(u32 handle) {
+ auto obj = client_handle_table->GetObjectForIpc(handle, thread);
+ if (obj.IsNotNull()) {
+ return obj->DynamicCast<T*>();
+ }
+ return nullptr;
}
[[nodiscard]] std::shared_ptr<SessionRequestManager> GetManager() const {
@@ -378,7 +388,7 @@ public:
private:
friend class IPC::ResponseBuilder;
- void ParseCommandBuffer(Kernel::KProcess& process, u32_le* src_cmdbuf, bool incoming);
+ void ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming);
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
Kernel::KServerSession* server_session{};
diff --git a/src/core/hle/service/ipc_helpers.h b/src/core/hle/service/ipc_helpers.h
index 0e222362e..4b02872fb 100644
--- a/src/core/hle/service/ipc_helpers.h
+++ b/src/core/hle/service/ipc_helpers.h
@@ -151,8 +151,8 @@ public:
if (manager->IsDomain()) {
context->AddDomainObject(std::move(iface));
} else {
- kernel.ApplicationProcess()->GetResourceLimit()->Reserve(
- Kernel::LimitableResource::SessionCountMax, 1);
+ ASSERT(Kernel::GetCurrentProcess(kernel).GetResourceLimit()->Reserve(
+ Kernel::LimitableResource::SessionCountMax, 1));
auto* session = Kernel::KSession::Create(kernel);
session->Initialize(nullptr, 0);
diff --git a/src/core/hle/service/jit/jit.cpp b/src/core/hle/service/jit/jit.cpp
index 65851fc05..77aa6d7d1 100644
--- a/src/core/hle/service/jit/jit.cpp
+++ b/src/core/hle/service/jit/jit.cpp
@@ -4,11 +4,11 @@
#include "core/arm/debug.h"
#include "core/arm/symbols.h"
#include "core/core.h"
-#include "core/hle/kernel/k_code_memory.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/result.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/jit/jit.h"
+#include "core/hle/service/jit/jit_code_memory.h"
#include "core/hle/service/jit/jit_context.h"
#include "core/hle/service/server_manager.h"
#include "core/hle/service/service.h"
@@ -23,9 +23,11 @@ struct CodeRange {
class IJitEnvironment final : public ServiceFramework<IJitEnvironment> {
public:
- explicit IJitEnvironment(Core::System& system_, Kernel::KProcess& process_, CodeRange user_rx,
- CodeRange user_ro)
- : ServiceFramework{system_, "IJitEnvironment"}, process{&process_},
+ explicit IJitEnvironment(Core::System& system_,
+ Kernel::KScopedAutoObject<Kernel::KProcess>&& process_,
+ CodeMemory&& user_rx_, CodeMemory&& user_ro_)
+ : ServiceFramework{system_, "IJitEnvironment"}, process{std::move(process_)},
+ user_rx{std::move(user_rx_)}, user_ro{std::move(user_ro_)},
context{system_.ApplicationMemory()} {
// clang-format off
static const FunctionInfo functions[] = {
@@ -39,10 +41,13 @@ public:
RegisterHandlers(functions);
// Identity map user code range into sysmodule context
- configuration.user_ro_memory = user_ro;
- configuration.user_rx_memory = user_rx;
- configuration.sys_ro_memory = user_ro;
- configuration.sys_rx_memory = user_rx;
+ configuration.user_rx_memory.size = user_rx.GetSize();
+ configuration.user_rx_memory.offset = user_rx.GetAddress();
+ configuration.user_ro_memory.size = user_ro.GetSize();
+ configuration.user_ro_memory.offset = user_ro.GetAddress();
+
+ configuration.sys_rx_memory = configuration.user_rx_memory;
+ configuration.sys_ro_memory = configuration.user_ro_memory;
}
void GenerateCode(HLERequestContext& ctx) {
@@ -188,7 +193,7 @@ public:
return;
}
- auto tmem{process->GetHandleTable().GetObject<Kernel::KTransferMemory>(tmem_handle)};
+ auto tmem{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(tmem_handle)};
if (tmem.IsNull()) {
LOG_ERROR(Service_JIT, "attempted to load plugin with invalid transfer memory handle");
IPC::ResponseBuilder rb{ctx, 2};
@@ -318,6 +323,8 @@ private:
}
Kernel::KScopedAutoObject<Kernel::KProcess> process;
+ CodeMemory user_rx;
+ CodeMemory user_ro;
GuestCallbacks callbacks;
JITConfiguration configuration;
JITContext context;
@@ -335,6 +342,7 @@ public:
RegisterHandlers(functions);
}
+private:
void CreateJitEnvironment(HLERequestContext& ctx) {
LOG_DEBUG(Service_JIT, "called");
@@ -356,11 +364,7 @@ public:
return;
}
- // Fetch using the handle table for the application process here,
- // since we are not multiprocess yet.
- const auto& handle_table{system.ApplicationProcess()->GetHandleTable()};
-
- auto process{handle_table.GetObject<Kernel::KProcess>(process_handle)};
+ auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(process_handle)};
if (process.IsNull()) {
LOG_ERROR(Service_JIT, "process is null for handle=0x{:08X}", process_handle);
IPC::ResponseBuilder rb{ctx, 2};
@@ -368,7 +372,7 @@ public:
return;
}
- auto rx_mem{handle_table.GetObject<Kernel::KCodeMemory>(rx_mem_handle)};
+ auto rx_mem{ctx.GetObjectFromHandle<Kernel::KCodeMemory>(rx_mem_handle)};
if (rx_mem.IsNull()) {
LOG_ERROR(Service_JIT, "rx_mem is null for handle=0x{:08X}", rx_mem_handle);
IPC::ResponseBuilder rb{ctx, 2};
@@ -376,7 +380,7 @@ public:
return;
}
- auto ro_mem{handle_table.GetObject<Kernel::KCodeMemory>(ro_mem_handle)};
+ auto ro_mem{ctx.GetObjectFromHandle<Kernel::KCodeMemory>(ro_mem_handle)};
if (ro_mem.IsNull()) {
LOG_ERROR(Service_JIT, "ro_mem is null for handle=0x{:08X}", ro_mem_handle);
IPC::ResponseBuilder rb{ctx, 2};
@@ -384,20 +388,35 @@ public:
return;
}
- const CodeRange user_rx{
- .offset = GetInteger(rx_mem->GetSourceAddress()),
- .size = parameters.rx_size,
- };
+ CodeMemory rx, ro;
+ Result res;
- const CodeRange user_ro{
- .offset = GetInteger(ro_mem->GetSourceAddress()),
- .size = parameters.ro_size,
- };
+ res = rx.Initialize(*process, *rx_mem, parameters.rx_size,
+ Kernel::Svc::MemoryPermission::ReadExecute, generate_random);
+ if (R_FAILED(res)) {
+ LOG_ERROR(Service_JIT, "rx_mem could not be mapped for handle=0x{:08X}", rx_mem_handle);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(res);
+ return;
+ }
+
+ res = ro.Initialize(*process, *ro_mem, parameters.ro_size,
+ Kernel::Svc::MemoryPermission::Read, generate_random);
+ if (R_FAILED(res)) {
+ LOG_ERROR(Service_JIT, "ro_mem could not be mapped for handle=0x{:08X}", ro_mem_handle);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(res);
+ return;
+ }
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
- rb.PushIpcInterface<IJitEnvironment>(system, *process, user_rx, user_ro);
+ rb.PushIpcInterface<IJitEnvironment>(system, std::move(process), std::move(rx),
+ std::move(ro));
}
+
+private:
+ std::mt19937_64 generate_random{};
};
void LoopProcess(Core::System& system) {
diff --git a/src/core/hle/service/jit/jit_code_memory.cpp b/src/core/hle/service/jit/jit_code_memory.cpp
new file mode 100644
index 000000000..2b480488a
--- /dev/null
+++ b/src/core/hle/service/jit/jit_code_memory.cpp
@@ -0,0 +1,54 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/jit/jit_code_memory.h"
+
+namespace Service::JIT {
+
+Result CodeMemory::Initialize(Kernel::KProcess& process, Kernel::KCodeMemory& code_memory,
+ size_t size, Kernel::Svc::MemoryPermission perm,
+ std::mt19937_64& generate_random) {
+ auto& page_table = process.GetPageTable();
+ const u64 alias_code_start =
+ GetInteger(page_table.GetAliasCodeRegionStart()) / Kernel::PageSize;
+ const u64 alias_code_size = page_table.GetAliasCodeRegionSize() / Kernel::PageSize;
+
+ // NOTE: This will retry indefinitely until mapping the code memory succeeds.
+ while (true) {
+ // Generate a new trial address.
+ const u64 mapped_address =
+ (alias_code_start + (generate_random() % alias_code_size)) * Kernel::PageSize;
+
+ // Try to map the address
+ R_TRY_CATCH(code_memory.MapToOwner(mapped_address, size, perm)) {
+ R_CATCH(Kernel::ResultInvalidMemoryRegion) {
+ // If we could not map here, retry.
+ continue;
+ }
+ }
+ R_END_TRY_CATCH;
+
+ // Set members.
+ m_code_memory = std::addressof(code_memory);
+ m_size = size;
+ m_address = mapped_address;
+ m_perm = perm;
+
+ // Open a new reference to the code memory.
+ m_code_memory->Open();
+
+ // We succeeded.
+ R_SUCCEED();
+ }
+}
+
+void CodeMemory::Finalize() {
+ if (m_code_memory) {
+ R_ASSERT(m_code_memory->UnmapFromOwner(m_address, m_size));
+ m_code_memory->Close();
+ }
+
+ m_code_memory = nullptr;
+}
+
+} // namespace Service::JIT
diff --git a/src/core/hle/service/jit/jit_code_memory.h b/src/core/hle/service/jit/jit_code_memory.h
new file mode 100644
index 000000000..6376d4c4e
--- /dev/null
+++ b/src/core/hle/service/jit/jit_code_memory.h
@@ -0,0 +1,49 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <random>
+
+#include "core/hle/kernel/k_code_memory.h"
+
+namespace Service::JIT {
+
+class CodeMemory {
+public:
+ YUZU_NON_COPYABLE(CodeMemory);
+
+ explicit CodeMemory() = default;
+
+ CodeMemory(CodeMemory&& rhs) {
+ std::swap(m_code_memory, rhs.m_code_memory);
+ std::swap(m_size, rhs.m_size);
+ std::swap(m_address, rhs.m_address);
+ std::swap(m_perm, rhs.m_perm);
+ }
+
+ ~CodeMemory() {
+ this->Finalize();
+ }
+
+public:
+ Result Initialize(Kernel::KProcess& process, Kernel::KCodeMemory& code_memory, size_t size,
+ Kernel::Svc::MemoryPermission perm, std::mt19937_64& generate_random);
+ void Finalize();
+
+ size_t GetSize() const {
+ return m_size;
+ }
+
+ u64 GetAddress() const {
+ return m_address;
+ }
+
+private:
+ Kernel::KCodeMemory* m_code_memory{};
+ size_t m_size{};
+ u64 m_address{};
+ Kernel::Svc::MemoryPermission m_perm{};
+};
+
+} // namespace Service::JIT
diff --git a/src/core/hle/service/ro/ro.cpp b/src/core/hle/service/ro/ro.cpp
index 17110d3f1..f0658bb5d 100644
--- a/src/core/hle/service/ro/ro.cpp
+++ b/src/core/hle/service/ro/ro.cpp
@@ -651,10 +651,9 @@ private:
void RegisterProcessHandle(HLERequestContext& ctx) {
LOG_DEBUG(Service_LDR, "(called)");
- auto process_h = ctx.GetClientHandleTable().GetObject(ctx.GetCopyHandle(0));
+ auto process = ctx.GetObjectFromHandle<Kernel::KProcess>(ctx.GetCopyHandle(0));
auto client_pid = ctx.GetPID();
- auto result = interface.RegisterProcessHandle(client_pid,
- process_h->DynamicCast<Kernel::KProcess*>());
+ auto result = interface.RegisterProcessHandle(client_pid, process.GetPointerUnsafe());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
@@ -671,12 +670,11 @@ private:
IPC::RequestParser rp{ctx};
auto params = rp.PopRaw<InputParameters>();
- auto process_h = ctx.GetClientHandleTable().GetObject(ctx.GetCopyHandle(0));
+ auto process = ctx.GetObjectFromHandle<Kernel::KProcess>(ctx.GetCopyHandle(0));
auto client_pid = ctx.GetPID();
- auto result =
- interface.RegisterProcessModuleInfo(client_pid, params.nrr_address, params.nrr_size,
- process_h->DynamicCast<Kernel::KProcess*>());
+ auto result = interface.RegisterProcessModuleInfo(
+ client_pid, params.nrr_address, params.nrr_size, process.GetPointerUnsafe());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
diff --git a/src/core/hle/service/server_manager.cpp b/src/core/hle/service/server_manager.cpp
index 6808247a9..15edb23e0 100644
--- a/src/core/hle/service/server_manager.cpp
+++ b/src/core/hle/service/server_manager.cpp
@@ -47,7 +47,7 @@ ServerManager::~ServerManager() {
m_stopped.Wait();
m_threads.clear();
- // Clean up ports.
+ // Clean up server ports.
for (const auto& [port, handler] : m_ports) {
port->Close();
}
@@ -97,22 +97,15 @@ Result ServerManager::RegisterNamedService(const std::string& service_name,
u32 max_sessions) {
ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects);
- // Add the new server to sm:.
- ASSERT(R_SUCCEEDED(
- m_system.ServiceManager().RegisterService(service_name, max_sessions, handler_factory)));
-
- // Get the registered port.
- Kernel::KPort* port{};
- ASSERT(
- R_SUCCEEDED(m_system.ServiceManager().GetServicePort(std::addressof(port), service_name)));
-
- // Open a new reference to the server port.
- port->GetServerPort().Open();
+ // Add the new server to sm: and get the moved server port.
+ Kernel::KServerPort* server_port{};
+ R_ASSERT(m_system.ServiceManager().RegisterService(std::addressof(server_port), service_name,
+ max_sessions, handler_factory));
// Begin tracking the server port.
{
std::scoped_lock ll{m_list_mutex};
- m_ports.emplace(std::addressof(port->GetServerPort()), std::move(handler_factory));
+ m_ports.emplace(server_port, std::move(handler_factory));
}
// Signal the wakeup event.
@@ -372,7 +365,7 @@ Result ServerManager::OnSessionEvent(Kernel::KServerSession* session,
// Try to receive a message.
std::shared_ptr<HLERequestContext> context;
- rc = session->ReceiveRequest(&context, manager);
+ rc = session->ReceiveRequestHLE(&context, manager);
// If the session has been closed, we're done.
if (rc == Kernel::ResultSessionClosed) {
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 00531b021..39124c5fd 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -203,7 +203,7 @@ Result ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session,
// If emulation was shutdown, we are closing service threads, do not write the response back to
// memory that may be shutting down as well.
if (system.IsPoweredOn()) {
- ctx.WriteToOutgoingCommandBuffer(ctx.GetThread());
+ ctx.WriteToOutgoingCommandBuffer();
}
return result;
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp
index 0653779d5..8e637f963 100644
--- a/src/core/hle/service/set/set_sys.cpp
+++ b/src/core/hle/service/set/set_sys.cpp
@@ -507,6 +507,14 @@ void SET_SYS::SetTvSettings(HLERequestContext& ctx) {
rb.Push(ResultSuccess);
}
+void SET_SYS::GetDebugModeFlag(HLERequestContext& ctx) {
+ LOG_DEBUG(Service_SET, "called");
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push<u32>(0);
+}
+
void SET_SYS::GetQuestFlag(HLERequestContext& ctx) {
LOG_WARNING(Service_SET, "(STUBBED) called");
@@ -926,7 +934,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"},
{59, &SET_SYS::SetNetworkSystemClockContext, "SetNetworkSystemClockContext"},
{60, &SET_SYS::IsUserSystemClockAutomaticCorrectionEnabled, "IsUserSystemClockAutomaticCorrectionEnabled"},
{61, &SET_SYS::SetUserSystemClockAutomaticCorrectionEnabled, "SetUserSystemClockAutomaticCorrectionEnabled"},
- {62, nullptr, "GetDebugModeFlag"},
+ {62, &SET_SYS::GetDebugModeFlag, "GetDebugModeFlag"},
{63, &SET_SYS::GetPrimaryAlbumStorage, "GetPrimaryAlbumStorage"},
{64, nullptr, "SetPrimaryAlbumStorage"},
{65, nullptr, "GetUsb30EnableFlag"},
@@ -1143,6 +1151,8 @@ void SET_SYS::StoreSettings() {
}
void SET_SYS::StoreSettingsThreadFunc(std::stop_token stop_token) {
+ Common::SetCurrentThreadName("SettingsStore");
+
while (Common::StoppableTimedWait(stop_token, std::chrono::minutes(1))) {
std::scoped_lock l{m_save_needed_mutex};
if (!std::exchange(m_save_needed, false)) {
diff --git a/src/core/hle/service/set/set_sys.h b/src/core/hle/service/set/set_sys.h
index 3785d93d8..853f76fce 100644
--- a/src/core/hle/service/set/set_sys.h
+++ b/src/core/hle/service/set/set_sys.h
@@ -98,6 +98,7 @@ private:
void GetSettingsItemValue(HLERequestContext& ctx);
void GetTvSettings(HLERequestContext& ctx);
void SetTvSettings(HLERequestContext& ctx);
+ void GetDebugModeFlag(HLERequestContext& ctx);
void GetQuestFlag(HLERequestContext& ctx);
void GetDeviceTimeZoneLocationName(HLERequestContext& ctx);
void SetDeviceTimeZoneLocationName(HLERequestContext& ctx);
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index 296ee6e89..1095dcf6c 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -29,8 +29,7 @@ ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {
ServiceManager::~ServiceManager() {
for (auto& [name, port] : service_ports) {
- port->GetClientPort().Close();
- port->GetServerPort().Close();
+ port->Close();
}
if (deferral_event) {
@@ -50,8 +49,8 @@ static Result ValidateServiceName(const std::string& name) {
return ResultSuccess;
}
-Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
- SessionRequestHandlerFactory handler) {
+Result ServiceManager::RegisterService(Kernel::KServerPort** out_server_port, std::string name,
+ u32 max_sessions, SessionRequestHandlerFactory handler) {
R_TRY(ValidateServiceName(name));
std::scoped_lock lk{lock};
@@ -66,13 +65,17 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
// Register the port.
Kernel::KPort::Register(kernel, port);
- service_ports.emplace(name, port);
+ service_ports.emplace(name, std::addressof(port->GetClientPort()));
registered_services.emplace(name, handler);
if (deferral_event) {
deferral_event->Signal();
}
- return ResultSuccess;
+ // Set our output.
+ *out_server_port = std::addressof(port->GetServerPort());
+
+ // We succeeded.
+ R_SUCCEED();
}
Result ServiceManager::UnregisterService(const std::string& name) {
@@ -91,7 +94,8 @@ Result ServiceManager::UnregisterService(const std::string& name) {
return ResultSuccess;
}
-Result ServiceManager::GetServicePort(Kernel::KPort** out_port, const std::string& name) {
+Result ServiceManager::GetServicePort(Kernel::KClientPort** out_client_port,
+ const std::string& name) {
R_TRY(ValidateServiceName(name));
std::scoped_lock lk{lock};
@@ -101,7 +105,7 @@ Result ServiceManager::GetServicePort(Kernel::KPort** out_port, const std::strin
return Service::SM::ResultNotRegistered;
}
- *out_port = it->second;
+ *out_client_port = it->second;
return ResultSuccess;
}
@@ -172,8 +176,8 @@ Result SM::GetServiceImpl(Kernel::KClientSession** out_client_session, HLEReques
std::string name(PopServiceName(rp));
// Find the named port.
- Kernel::KPort* port{};
- auto port_result = service_manager.GetServicePort(&port, name);
+ Kernel::KClientPort* client_port{};
+ auto port_result = service_manager.GetServicePort(&client_port, name);
if (port_result == Service::SM::ResultInvalidServiceName) {
LOG_ERROR(Service_SM, "Invalid service name '{}'", name);
return Service::SM::ResultInvalidServiceName;
@@ -187,7 +191,7 @@ Result SM::GetServiceImpl(Kernel::KClientSession** out_client_session, HLEReques
// Create a new session.
Kernel::KClientSession* session{};
- if (const auto result = port->GetClientPort().CreateSession(&session); result.IsError()) {
+ if (const auto result = client_port->CreateSession(&session); result.IsError()) {
LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw);
return result;
}
@@ -221,7 +225,9 @@ void SM::RegisterServiceImpl(HLERequestContext& ctx, std::string name, u32 max_s
LOG_DEBUG(Service_SM, "called with name={}, max_session_count={}, is_light={}", name,
max_session_count, is_light);
- if (const auto result = service_manager.RegisterService(name, max_session_count, nullptr);
+ Kernel::KServerPort* server_port{};
+ if (const auto result = service_manager.RegisterService(std::addressof(server_port), name,
+ max_session_count, nullptr);
result.IsError()) {
LOG_ERROR(Service_SM, "failed to register service with error_code={:08X}", result.raw);
IPC::ResponseBuilder rb{ctx, 2};
@@ -229,13 +235,9 @@ void SM::RegisterServiceImpl(HLERequestContext& ctx, std::string name, u32 max_s
return;
}
- auto* port = Kernel::KPort::Create(kernel);
- port->Initialize(ServerSessionCountMax, is_light, 0);
- SCOPE_EXIT({ port->GetClientPort().Close(); });
-
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
rb.Push(ResultSuccess);
- rb.PushMoveObjects(port->GetServerPort());
+ rb.PushMoveObjects(server_port);
}
void SM::UnregisterService(HLERequestContext& ctx) {
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h
index ff74f588a..4ae32a9c1 100644
--- a/src/core/hle/service/sm/sm.h
+++ b/src/core/hle/service/sm/sm.h
@@ -56,10 +56,10 @@ public:
explicit ServiceManager(Kernel::KernelCore& kernel_);
~ServiceManager();
- Result RegisterService(std::string name, u32 max_sessions,
- SessionRequestHandlerFactory handler_factory);
+ Result RegisterService(Kernel::KServerPort** out_server_port, std::string name,
+ u32 max_sessions, SessionRequestHandlerFactory handler_factory);
Result UnregisterService(const std::string& name);
- Result GetServicePort(Kernel::KPort** out_port, const std::string& name);
+ Result GetServicePort(Kernel::KClientPort** out_client_port, const std::string& name);
template <Common::DerivedFrom<SessionRequestHandler> T>
std::shared_ptr<T> GetService(const std::string& service_name) const {
@@ -84,7 +84,7 @@ private:
/// Map of registered services, retrieved using GetServicePort.
std::mutex lock;
std::unordered_map<std::string, SessionRequestHandlerFactory> registered_services;
- std::unordered_map<std::string, Kernel::KPort*> service_ports;
+ std::unordered_map<std::string, Kernel::KClientPort*> service_ports;
/// Kernel context
Kernel::KernelCore& kernel;
diff --git a/src/core/hle/service/sm/sm_controller.cpp b/src/core/hle/service/sm/sm_controller.cpp
index 7dce28fe0..7f0fb91d0 100644
--- a/src/core/hle/service/sm/sm_controller.cpp
+++ b/src/core/hle/service/sm/sm_controller.cpp
@@ -28,7 +28,6 @@ void Controller::ConvertCurrentObjectToDomain(HLERequestContext& ctx) {
void Controller::CloneCurrentObject(HLERequestContext& ctx) {
LOG_DEBUG(Service, "called");
- auto& process = *ctx.GetThread().GetOwnerProcess();
auto session_manager = ctx.GetManager();
// FIXME: this is duplicated from the SVC, it should just call it instead
@@ -36,11 +35,11 @@ void Controller::CloneCurrentObject(HLERequestContext& ctx) {
// Reserve a new session from the process resource limit.
Kernel::KScopedResourceReservation session_reservation(
- &process, Kernel::LimitableResource::SessionCountMax);
+ Kernel::GetCurrentProcessPointer(kernel), Kernel::LimitableResource::SessionCountMax);
ASSERT(session_reservation.Succeeded());
// Create the session.
- Kernel::KSession* session = Kernel::KSession::Create(system.Kernel());
+ Kernel::KSession* session = Kernel::KSession::Create(kernel);
ASSERT(session != nullptr);
// Initialize the session.
@@ -50,7 +49,7 @@ void Controller::CloneCurrentObject(HLERequestContext& ctx) {
session_reservation.Commit();
// Register the session.
- Kernel::KSession::Register(system.Kernel(), session);
+ Kernel::KSession::Register(kernel, session);
// Register with server manager.
session_manager->GetServerManager().RegisterSession(&session->GetServerSession(),