mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-03 03:09:13 +00:00
[video_core, hle] remove redundant parent references in system structs (#3908)
reworked a bit to remove references of parent objects and instead pass as arguments to methods to prevent useless reloads Signed-off-by: lizzie <lizzie@eden-emu.dev> Co-authored-by: maufeat <sahyno1996@gmail.com> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3908 Reviewed-by: Maufeat <sahyno1996@gmail.com> Reviewed-by: crueter <crueter@eden-emu.dev>
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -22,17 +25,15 @@ Result SetThreadActivity(Core::System& system, Handle thread_handle,
|
||||
R_UNLESS(IsValidThreadActivity(thread_activity), ResultInvalidEnumValue);
|
||||
|
||||
// Get the thread from its handle.
|
||||
KScopedAutoObject thread =
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
|
||||
KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(system.Kernel(), thread_handle);
|
||||
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Check that the activity is being set on a non-current thread for the current process.
|
||||
R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(system.Kernel()),
|
||||
ResultInvalidHandle);
|
||||
R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(system.Kernel()), ResultInvalidHandle);
|
||||
R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(system.Kernel()), ResultBusy);
|
||||
|
||||
// Set the activity.
|
||||
R_TRY(thread->SetActivity(thread_activity));
|
||||
R_TRY(thread->SetActivity(system.Kernel(), thread_activity));
|
||||
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -37,8 +40,7 @@ Result FlushProcessDataCache(Core::System& system, Handle process_handle, u64 ad
|
||||
R_UNLESS(size == static_cast<uint64_t>(size), ResultInvalidCurrentMemory);
|
||||
|
||||
// Get the process from its handle.
|
||||
KScopedAutoObject process =
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
|
||||
KScopedAutoObject process = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(system.Kernel(), process_handle);
|
||||
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Verify the region is within range.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
@@ -35,9 +35,6 @@ constexpr bool IsValidUnmapFromOwnerCodeMemoryPermission(MemoryPermission perm)
|
||||
Result CreateCodeMemory(Core::System& system, Handle* out, u64 address, uint64_t size) {
|
||||
LOG_TRACE(Kernel_SVC, "called, address={:#X}, size=0x{:X}", address, size);
|
||||
|
||||
// Get kernel instance.
|
||||
auto& kernel = system.Kernel();
|
||||
|
||||
// Validate address / size.
|
||||
R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress);
|
||||
R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
|
||||
@@ -46,24 +43,23 @@ Result CreateCodeMemory(Core::System& system, Handle* out, u64 address, uint64_t
|
||||
|
||||
// Create the code memory.
|
||||
|
||||
KCodeMemory* code_mem = KCodeMemory::Create(kernel);
|
||||
KCodeMemory* code_mem = KCodeMemory::Create(system.Kernel());
|
||||
R_UNLESS(code_mem != nullptr, ResultOutOfResource);
|
||||
SCOPE_EXIT {
|
||||
code_mem->Close();
|
||||
code_mem->Close(system.Kernel());
|
||||
};
|
||||
|
||||
// Verify that the region is in range.
|
||||
R_UNLESS(GetCurrentProcess(system.Kernel()).GetPageTable().Contains(address, size),
|
||||
ResultInvalidCurrentMemory);
|
||||
R_UNLESS(GetCurrentProcess(system.Kernel()).GetPageTable().Contains(address, size), ResultInvalidCurrentMemory);
|
||||
|
||||
// Initialize the code memory.
|
||||
R_TRY(code_mem->Initialize(system.DeviceMemory(), address, size));
|
||||
R_TRY(code_mem->Initialize(system.Kernel(), system.DeviceMemory(), address, size));
|
||||
|
||||
// Register the code memory.
|
||||
KCodeMemory::Register(kernel, code_mem);
|
||||
KCodeMemory::Register(system.Kernel(), code_mem);
|
||||
|
||||
// Add the code memory to the handle table.
|
||||
R_TRY(GetCurrentProcess(system.Kernel()).GetHandleTable().Add(out, code_mem));
|
||||
R_TRY(GetCurrentProcess(system.Kernel()).GetHandleTable().Add(system.Kernel(), out, code_mem));
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
@@ -85,8 +81,8 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
|
||||
|
||||
// Get the code memory from its handle.
|
||||
KScopedAutoObject code_mem = GetCurrentProcess(system.Kernel())
|
||||
.GetHandleTable()
|
||||
.GetObject<KCodeMemory>(code_memory_handle);
|
||||
.GetHandleTable()
|
||||
.GetObject<KCodeMemory>(system.Kernel(), code_memory_handle);
|
||||
R_UNLESS(code_mem.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// NOTE: Here, Atmosphere extends the SVC to allow code memory operations on one's own process.
|
||||
@@ -96,29 +92,23 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
|
||||
switch (operation) {
|
||||
case CodeMemoryOperation::Map: {
|
||||
// Check that the region is in range.
|
||||
R_UNLESS(GetCurrentProcess(system.Kernel())
|
||||
.GetPageTable()
|
||||
.CanContain(address, size, KMemoryState::CodeOut),
|
||||
ResultInvalidMemoryRegion);
|
||||
R_UNLESS(GetCurrentProcess(system.Kernel()).GetPageTable().CanContain(address, size, KMemoryState::CodeOut), ResultInvalidMemoryRegion);
|
||||
|
||||
// Check the memory permission.
|
||||
R_UNLESS(IsValidMapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);
|
||||
|
||||
// Map the memory.
|
||||
R_TRY(code_mem->Map(address, size));
|
||||
R_TRY(code_mem->Map(system.Kernel(), address, size));
|
||||
} break;
|
||||
case CodeMemoryOperation::Unmap: {
|
||||
// Check that the region is in range.
|
||||
R_UNLESS(GetCurrentProcess(system.Kernel())
|
||||
.GetPageTable()
|
||||
.CanContain(address, size, KMemoryState::CodeOut),
|
||||
ResultInvalidMemoryRegion);
|
||||
R_UNLESS(GetCurrentProcess(system.Kernel()).GetPageTable().CanContain(address, size, KMemoryState::CodeOut), ResultInvalidMemoryRegion);
|
||||
|
||||
// Check the memory permission.
|
||||
R_UNLESS(IsValidUnmapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);
|
||||
|
||||
// Unmap the memory.
|
||||
R_TRY(code_mem->Unmap(address, size));
|
||||
R_TRY(code_mem->Unmap(system.Kernel(), address, size));
|
||||
} break;
|
||||
case CodeMemoryOperation::MapToOwner: {
|
||||
// Check that the region is in range.
|
||||
@@ -130,7 +120,7 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
|
||||
R_UNLESS(IsValidMapToOwnerCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);
|
||||
|
||||
// Map the memory to its owner.
|
||||
R_TRY(code_mem->MapToOwner(address, size, perm));
|
||||
R_TRY(code_mem->MapToOwner(system.Kernel(), address, size, perm));
|
||||
} break;
|
||||
case CodeMemoryOperation::UnmapFromOwner: {
|
||||
// Check that the region is in range.
|
||||
@@ -142,7 +132,7 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
|
||||
R_UNLESS(IsValidUnmapFromOwnerCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);
|
||||
|
||||
// Unmap the memory from its owner.
|
||||
R_TRY(code_mem->UnmapFromOwner(address, size));
|
||||
R_TRY(code_mem->UnmapFromOwner(system.Kernel(), address, size));
|
||||
} break;
|
||||
default:
|
||||
R_THROW(ResultInvalidEnumValue);
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -29,17 +32,17 @@ Result CreateDeviceAddressSpace(Core::System& system, Handle* out, uint64_t das_
|
||||
KDeviceAddressSpace* das = KDeviceAddressSpace::Create(system.Kernel());
|
||||
R_UNLESS(das != nullptr, ResultOutOfResource);
|
||||
SCOPE_EXIT {
|
||||
das->Close();
|
||||
das->Close(system.Kernel());
|
||||
};
|
||||
|
||||
// Initialize the device address space.
|
||||
R_TRY(das->Initialize(das_address, das_size));
|
||||
R_TRY(das->Initialize(system.Kernel(), das_address, das_size));
|
||||
|
||||
// Register the device address space.
|
||||
KDeviceAddressSpace::Register(system.Kernel(), das);
|
||||
|
||||
// Add to the handle table.
|
||||
R_TRY(GetCurrentProcess(system.Kernel()).GetHandleTable().Add(out, das));
|
||||
R_TRY(GetCurrentProcess(system.Kernel()).GetHandleTable().Add(system.Kernel(), out, das));
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
@@ -47,8 +50,8 @@ Result CreateDeviceAddressSpace(Core::System& system, Handle* out, uint64_t das_
|
||||
Result AttachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle) {
|
||||
// Get the device address space.
|
||||
KScopedAutoObject das = GetCurrentProcess(system.Kernel())
|
||||
.GetHandleTable()
|
||||
.GetObject<KDeviceAddressSpace>(das_handle);
|
||||
.GetHandleTable()
|
||||
.GetObject<KDeviceAddressSpace>(system.Kernel(), das_handle);
|
||||
R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Attach.
|
||||
@@ -58,8 +61,8 @@ Result AttachDeviceAddressSpace(Core::System& system, DeviceName device_name, Ha
|
||||
Result DetachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle) {
|
||||
// Get the device address space.
|
||||
KScopedAutoObject das = GetCurrentProcess(system.Kernel())
|
||||
.GetHandleTable()
|
||||
.GetObject<KDeviceAddressSpace>(das_handle);
|
||||
.GetHandleTable()
|
||||
.GetObject<KDeviceAddressSpace>(system.Kernel(), das_handle);
|
||||
R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Detach.
|
||||
@@ -99,13 +102,13 @@ Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Han
|
||||
|
||||
// Get the device address space.
|
||||
KScopedAutoObject das = GetCurrentProcess(system.Kernel())
|
||||
.GetHandleTable()
|
||||
.GetObject<KDeviceAddressSpace>(das_handle);
|
||||
.GetHandleTable()
|
||||
.GetObject<KDeviceAddressSpace>(system.Kernel(), das_handle);
|
||||
R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Get the process.
|
||||
KScopedAutoObject process =
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(system.Kernel(), process_handle);
|
||||
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Validate that the process address is within range.
|
||||
@@ -140,13 +143,13 @@ Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Han
|
||||
|
||||
// Get the device address space.
|
||||
KScopedAutoObject das = GetCurrentProcess(system.Kernel())
|
||||
.GetHandleTable()
|
||||
.GetObject<KDeviceAddressSpace>(das_handle);
|
||||
.GetHandleTable()
|
||||
.GetObject<KDeviceAddressSpace>(system.Kernel(), das_handle);
|
||||
R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Get the process.
|
||||
KScopedAutoObject process =
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(system.Kernel(), process_handle);
|
||||
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Validate that the process address is within range.
|
||||
@@ -172,13 +175,12 @@ Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle p
|
||||
|
||||
// Get the device address space.
|
||||
KScopedAutoObject das = GetCurrentProcess(system.Kernel())
|
||||
.GetHandleTable()
|
||||
.GetObject<KDeviceAddressSpace>(das_handle);
|
||||
.GetHandleTable()
|
||||
.GetObject<KDeviceAddressSpace>(system.Kernel(), das_handle);
|
||||
R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Get the process.
|
||||
KScopedAutoObject process =
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
|
||||
KScopedAutoObject process = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(system.Kernel(), process_handle);
|
||||
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Validate that the process address is within range.
|
||||
|
||||
@@ -22,9 +22,9 @@ Result SignalEvent(Core::System& system, Handle event_handle) {
|
||||
// Fail-safe for system applets
|
||||
const auto program_id = GetCurrentProcess(system.Kernel()).GetProgramId();
|
||||
if ((program_id & 0xFFFFFFFFFFFFFF00ull) == 0x0100000000001000ull) {
|
||||
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
|
||||
KScopedAutoObject event = handle_table.GetObject<KEvent>(system.Kernel(), event_handle);
|
||||
if (event.IsNotNull()) {
|
||||
event->Signal();
|
||||
event->Signal(system.Kernel());
|
||||
} else {
|
||||
LOG_WARNING(Kernel_SVC, "SignalEvent best-effort unknown handle=0x{:08X} (ignored)",
|
||||
event_handle);
|
||||
@@ -34,10 +34,10 @@ Result SignalEvent(Core::System& system, Handle event_handle) {
|
||||
|
||||
|
||||
// Get the event.
|
||||
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
|
||||
KScopedAutoObject event = handle_table.GetObject<KEvent>(system.Kernel(), event_handle);
|
||||
R_UNLESS(event.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
R_RETURN(event->Signal());
|
||||
R_RETURN(event->Signal(system.Kernel()));
|
||||
}
|
||||
|
||||
Result ClearEvent(Core::System& system, Handle event_handle) {
|
||||
@@ -48,18 +48,18 @@ Result ClearEvent(Core::System& system, Handle event_handle) {
|
||||
|
||||
// Try to clear the writable event.
|
||||
{
|
||||
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
|
||||
KScopedAutoObject event = handle_table.GetObject<KEvent>(system.Kernel(), event_handle);
|
||||
if (event.IsNotNull()) {
|
||||
event->Clear();
|
||||
event->Clear(system.Kernel());
|
||||
R_SUCCEED();
|
||||
}
|
||||
}
|
||||
|
||||
// Try to clear the readable event.
|
||||
{
|
||||
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(event_handle);
|
||||
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(system.Kernel(), event_handle);
|
||||
if (readable_event.IsNotNull()) {
|
||||
readable_event->Clear();
|
||||
readable_event->Clear(system.Kernel());
|
||||
R_SUCCEED();
|
||||
}
|
||||
}
|
||||
@@ -71,43 +71,42 @@ Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) {
|
||||
LOG_DEBUG(Kernel_SVC, "called");
|
||||
|
||||
// Get the kernel reference and handle table.
|
||||
auto& kernel = system.Kernel();
|
||||
auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
|
||||
auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
|
||||
|
||||
// Reserve a new event from the process resource limit
|
||||
KScopedResourceReservation event_reservation(GetCurrentProcessPointer(kernel),
|
||||
KScopedResourceReservation event_reservation(system.Kernel(), GetCurrentProcessPointer(system.Kernel()),
|
||||
LimitableResource::EventCountMax);
|
||||
R_UNLESS(event_reservation.Succeeded(), ResultLimitReached);
|
||||
|
||||
// Create a new event.
|
||||
KEvent* event = KEvent::Create(kernel);
|
||||
KEvent* event = KEvent::Create(system.Kernel());
|
||||
R_UNLESS(event != nullptr, ResultOutOfResource);
|
||||
|
||||
// Initialize the event.
|
||||
event->Initialize(GetCurrentProcessPointer(kernel));
|
||||
event->Initialize(system.Kernel(), GetCurrentProcessPointer(system.Kernel()));
|
||||
|
||||
// Commit the thread reservation.
|
||||
event_reservation.Commit();
|
||||
|
||||
// Ensure that we clean up the event (and its only references are handle table) on function end.
|
||||
SCOPE_EXIT {
|
||||
event->GetReadableEvent().Close();
|
||||
event->Close();
|
||||
event->GetReadableEvent().Close(system.Kernel());
|
||||
event->Close(system.Kernel());
|
||||
};
|
||||
|
||||
// Register the event.
|
||||
KEvent::Register(kernel, event);
|
||||
KEvent::Register(system.Kernel(), event);
|
||||
|
||||
// Add the event to the handle table.
|
||||
R_TRY(handle_table.Add(out_write, event));
|
||||
R_TRY(handle_table.Add(system.Kernel(), out_write, event));
|
||||
|
||||
// Ensure that we maintain a clean handle state on exit.
|
||||
ON_RESULT_FAILURE {
|
||||
handle_table.Remove(*out_write);
|
||||
handle_table.Remove(system.Kernel(), *out_write);
|
||||
};
|
||||
|
||||
// Add the readable event to the handle table.
|
||||
R_RETURN(handle_table.Add(out_read, std::addressof(event->GetReadableEvent())));
|
||||
R_RETURN(handle_table.Add(system.Kernel(), out_read, std::addressof(event->GetReadableEvent())));
|
||||
}
|
||||
|
||||
Result SignalEvent64(Core::System& system, Handle event_handle) {
|
||||
|
||||
@@ -106,14 +106,14 @@ void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) {
|
||||
|
||||
handle_debug_buffer(info1, info2);
|
||||
|
||||
system.CurrentPhysicalCore().LogBacktrace();
|
||||
system.CurrentPhysicalCore().LogBacktrace(system.Kernel());
|
||||
}
|
||||
|
||||
const bool should_break = !notification_only;
|
||||
if (system.DebuggerEnabled() && should_break) {
|
||||
auto* thread = system.Kernel().GetCurrentEmuThread();
|
||||
system.GetDebugger().NotifyThreadStopped(thread);
|
||||
thread->RequestSuspend(Kernel::SuspendType::Debug);
|
||||
thread->RequestSuspend(system.Kernel(), Kernel::SuspendType::Debug);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
@@ -46,7 +46,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
|
||||
R_UNLESS(info_sub_id == 0, ResultInvalidEnumValue);
|
||||
|
||||
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
|
||||
KScopedAutoObject process = handle_table.GetObject<KProcess>(handle);
|
||||
KScopedAutoObject process = handle_table.GetObject<KProcess>(system.Kernel(), handle);
|
||||
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
switch (info_id_type) {
|
||||
@@ -90,11 +90,11 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::TotalMemorySize:
|
||||
*result = process->GetTotalUserPhysicalMemorySize();
|
||||
*result = process->GetTotalUserPhysicalMemorySize(system.Kernel());
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::UsedMemorySize:
|
||||
*result = process->GetUsedUserPhysicalMemorySize();
|
||||
*result = process->GetUsedUserPhysicalMemorySize(system.Kernel());
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::SystemResourceSizeTotal:
|
||||
@@ -114,11 +114,11 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::TotalNonSystemMemorySize:
|
||||
*result = process->GetTotalNonSystemUserPhysicalMemorySize();
|
||||
*result = process->GetTotalNonSystemUserPhysicalMemorySize(system.Kernel());
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::UsedNonSystemMemorySize:
|
||||
*result = process->GetUsedNonSystemUserPhysicalMemorySize();
|
||||
*result = process->GetUsedNonSystemUserPhysicalMemorySize(system.Kernel());
|
||||
R_SUCCEED();
|
||||
|
||||
case InfoType::IsApplication:
|
||||
@@ -175,7 +175,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
|
||||
}
|
||||
|
||||
Handle resource_handle{};
|
||||
R_TRY(handle_table.Add(std::addressof(resource_handle), resource_limit));
|
||||
R_TRY(handle_table.Add(system.Kernel(), std::addressof(resource_handle), resource_limit));
|
||||
|
||||
*result = resource_handle;
|
||||
R_SUCCEED();
|
||||
@@ -203,8 +203,8 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
|
||||
}
|
||||
|
||||
KScopedAutoObject thread = GetCurrentProcess(system.Kernel())
|
||||
.GetHandleTable()
|
||||
.GetObject<KThread>(static_cast<Handle>(handle));
|
||||
.GetHandleTable()
|
||||
.GetObject<KThread>(system.Kernel(), Handle(handle));
|
||||
if (thread.IsNull()) {
|
||||
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}",
|
||||
static_cast<Handle>(handle));
|
||||
@@ -256,7 +256,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
|
||||
|
||||
// Get a new handle for the current process.
|
||||
Handle tmp;
|
||||
R_TRY(handle_table.Add(std::addressof(tmp), current_process));
|
||||
R_TRY(handle_table.Add(system.Kernel(), std::addressof(tmp), current_process));
|
||||
|
||||
// Set the output.
|
||||
*result = tmp;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
@@ -20,19 +20,17 @@ namespace Kernel::Svc {
|
||||
|
||||
namespace {
|
||||
|
||||
Result SendSyncRequestImpl(KernelCore& kernel, uintptr_t message, size_t buffer_size,
|
||||
Handle session_handle) {
|
||||
Result SendSyncRequestImpl(KernelCore& kernel, uintptr_t message, size_t buffer_size, Handle session_handle) {
|
||||
// Get the client session.
|
||||
KScopedAutoObject session =
|
||||
GetCurrentProcess(kernel).GetHandleTable().GetObject<KClientSession>(session_handle);
|
||||
KScopedAutoObject session = GetCurrentProcess(kernel).GetHandleTable().GetObject<KClientSession>(kernel, session_handle);
|
||||
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Get the parent, and persist a reference to it until we're done.
|
||||
KScopedAutoObject parent = session->GetParent();
|
||||
KScopedAutoObject parent = {kernel, session->GetParent()};
|
||||
ASSERT(parent.IsNotNull());
|
||||
|
||||
// Send the request.
|
||||
R_RETURN(session->SendSyncRequest(message, buffer_size));
|
||||
R_RETURN(session->SendSyncRequest(kernel, message, buffer_size));
|
||||
}
|
||||
|
||||
Result ReplyAndReceiveImpl(KernelCore& kernel, int32_t* out_index, uintptr_t message,
|
||||
@@ -41,8 +39,7 @@ Result ReplyAndReceiveImpl(KernelCore& kernel, int32_t* out_index, uintptr_t mes
|
||||
int64_t timeout_ns) {
|
||||
// Reply to the target, if one is specified.
|
||||
if (reply_target != InvalidHandle) {
|
||||
KScopedAutoObject session =
|
||||
GetCurrentProcess(kernel).GetHandleTable().GetObject<KServerSession>(reply_target);
|
||||
KScopedAutoObject session = GetCurrentProcess(kernel).GetHandleTable().GetObject<KServerSession>(kernel, reply_target);
|
||||
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// If we fail to reply, we want to set the output index to -1.
|
||||
@@ -51,7 +48,7 @@ Result ReplyAndReceiveImpl(KernelCore& kernel, int32_t* out_index, uintptr_t mes
|
||||
};
|
||||
|
||||
// Send the reply.
|
||||
R_TRY(session->SendReply(message, buffer_size, message_paddr));
|
||||
R_TRY(session->SendReply(kernel, message, buffer_size, message_paddr));
|
||||
}
|
||||
|
||||
// Receive a message.
|
||||
@@ -77,8 +74,7 @@ Result ReplyAndReceiveImpl(KernelCore& kernel, int32_t* out_index, uintptr_t mes
|
||||
while (true) {
|
||||
// Wait for an object.
|
||||
s32 index;
|
||||
Result result = KSynchronizationObject::Wait(kernel, std::addressof(index), objs,
|
||||
num_objects, timeout);
|
||||
Result result = KSynchronizationObject::Wait(kernel, std::addressof(index), objs, num_objects, timeout);
|
||||
if (ResultTimedOut == result) {
|
||||
R_THROW(result);
|
||||
}
|
||||
@@ -87,7 +83,7 @@ Result ReplyAndReceiveImpl(KernelCore& kernel, int32_t* out_index, uintptr_t mes
|
||||
if (R_SUCCEEDED(result)) {
|
||||
KServerSession* session = objs[index]->DynamicCast<KServerSession*>();
|
||||
if (session != nullptr) {
|
||||
result = session->ReceiveRequest(message, buffer_size, message_paddr);
|
||||
result = session->ReceiveRequest(kernel, message, buffer_size, message_paddr);
|
||||
if (ResultNotFound == result) {
|
||||
continue;
|
||||
}
|
||||
@@ -127,14 +123,14 @@ Result ReplyAndReceiveImpl(KernelCore& kernel, int32_t* out_index, uintptr_t mes
|
||||
|
||||
// Convert the handles to objects.
|
||||
R_UNLESS(
|
||||
handle_table.GetMultipleObjects<KSynchronizationObject>(objs, handles, num_handles),
|
||||
handle_table.GetMultipleObjects<KSynchronizationObject>(kernel, objs, handles, num_handles),
|
||||
ResultInvalidHandle);
|
||||
}
|
||||
|
||||
// Ensure handles are closed when we're done.
|
||||
SCOPE_EXIT {
|
||||
for (auto i = 0; i < num_handles; ++i) {
|
||||
objs[i]->Close();
|
||||
objs[i]->Close(kernel);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -188,16 +184,15 @@ Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_ha
|
||||
auto& handle_table = process.GetHandleTable();
|
||||
|
||||
// Reserve a new event from the process resource limit.
|
||||
KScopedResourceReservation event_reservation(std::addressof(process),
|
||||
Svc::LimitableResource::EventCountMax);
|
||||
KScopedResourceReservation event_reservation(system.Kernel(), std::addressof(process), Svc::LimitableResource::EventCountMax);
|
||||
R_UNLESS(event_reservation.Succeeded(), ResultLimitReached);
|
||||
|
||||
// Get the client session.
|
||||
KScopedAutoObject session = process.GetHandleTable().GetObject<KClientSession>(session_handle);
|
||||
KScopedAutoObject session = process.GetHandleTable().GetObject<KClientSession>(system.Kernel(), session_handle);
|
||||
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Get the parent, and persist a reference to it until we're done.
|
||||
KScopedAutoObject parent = session->GetParent();
|
||||
KScopedAutoObject parent = {system.Kernel(), session->GetParent()};
|
||||
ASSERT(parent.IsNotNull());
|
||||
|
||||
// Create a new event.
|
||||
@@ -205,30 +200,30 @@ Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_ha
|
||||
R_UNLESS(event != nullptr, ResultOutOfResource);
|
||||
|
||||
// Initialize the event.
|
||||
event->Initialize(std::addressof(process));
|
||||
event->Initialize(system.Kernel(), std::addressof(process));
|
||||
|
||||
// Commit our reservation.
|
||||
event_reservation.Commit();
|
||||
|
||||
// At end of scope, kill the standing references to the sub events.
|
||||
SCOPE_EXIT {
|
||||
event->GetReadableEvent().Close();
|
||||
event->Close();
|
||||
event->GetReadableEvent().Close(system.Kernel());
|
||||
event->Close(system.Kernel());
|
||||
};
|
||||
|
||||
// Register the event.
|
||||
KEvent::Register(system.Kernel(), event);
|
||||
|
||||
// Add the readable event to the handle table.
|
||||
R_TRY(handle_table.Add(out_event_handle, std::addressof(event->GetReadableEvent())));
|
||||
R_TRY(handle_table.Add(system.Kernel(), out_event_handle, std::addressof(event->GetReadableEvent())));
|
||||
|
||||
// Ensure that if we fail to send the request, we close the readable handle.
|
||||
ON_RESULT_FAILURE {
|
||||
handle_table.Remove(*out_event_handle);
|
||||
handle_table.Remove(system.Kernel(), *out_event_handle);
|
||||
};
|
||||
|
||||
// Send the async request.
|
||||
R_RETURN(session->SendAsyncRequest(event, message, buffer_size));
|
||||
R_RETURN(session->SendAsyncRequest(system.Kernel(), event, message, buffer_size));
|
||||
}
|
||||
|
||||
Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles, s32 num_handles,
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -14,12 +17,12 @@ namespace Kernel::Svc {
|
||||
Result SendSyncRequestLight(Core::System& system, Handle session_handle, u32* args) {
|
||||
// Get the light client session from its handle.
|
||||
KScopedAutoObject session = GetCurrentProcess(system.Kernel())
|
||||
.GetHandleTable()
|
||||
.GetObject<KLightClientSession>(session_handle);
|
||||
.GetHandleTable()
|
||||
.GetObject<KLightClientSession>(system.Kernel(), session_handle);
|
||||
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Send the request.
|
||||
R_TRY(session->SendSyncRequest(args));
|
||||
R_TRY(session->SendSyncRequest(system.Kernel(), args));
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
@@ -27,12 +30,12 @@ Result SendSyncRequestLight(Core::System& system, Handle session_handle, u32* ar
|
||||
Result ReplyAndReceiveLight(Core::System& system, Handle session_handle, u32* args) {
|
||||
// Get the light server session from its handle.
|
||||
KScopedAutoObject session = GetCurrentProcess(system.Kernel())
|
||||
.GetHandleTable()
|
||||
.GetObject<KLightServerSession>(session_handle);
|
||||
.GetHandleTable()
|
||||
.GetObject<KLightServerSession>(system.Kernel(), session_handle);
|
||||
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Handle the request.
|
||||
R_TRY(session->ReplyAndReceive(args));
|
||||
R_TRY(session->ReplyAndReceive(system.Kernel(), args));
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -33,18 +36,18 @@ Result ConnectToNamedPort(Core::System& system, Handle* out, u64 user_name) {
|
||||
|
||||
// Reserve a handle for the port.
|
||||
// NOTE: Nintendo really does write directly to the output handle here.
|
||||
R_TRY(handle_table.Reserve(out));
|
||||
R_TRY(handle_table.Reserve(system.Kernel(), out));
|
||||
ON_RESULT_FAILURE {
|
||||
handle_table.Unreserve(*out);
|
||||
handle_table.Unreserve(system.Kernel(), *out);
|
||||
};
|
||||
|
||||
// Create a session.
|
||||
KClientSession* session;
|
||||
R_TRY(port->CreateSession(std::addressof(session)));
|
||||
R_TRY(port->CreateSession(system.Kernel(), std::addressof(session)));
|
||||
|
||||
// Register the session in the table, close the extra reference.
|
||||
handle_table.Register(*out, session);
|
||||
session->Close();
|
||||
handle_table.Register(system.Kernel(), *out, session);
|
||||
session->Close(system.Kernel());
|
||||
|
||||
// We succeeded.
|
||||
R_SUCCEED();
|
||||
@@ -65,27 +68,27 @@ Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client,
|
||||
R_UNLESS(port != nullptr, ResultOutOfResource);
|
||||
|
||||
// Initialize the port.
|
||||
port->Initialize(max_sessions, is_light, name);
|
||||
port->Initialize(system.Kernel(), max_sessions, is_light, name);
|
||||
|
||||
// Ensure that we clean up the port (and its only references are handle table) on function end.
|
||||
SCOPE_EXIT {
|
||||
port->GetServerPort().Close();
|
||||
port->GetClientPort().Close();
|
||||
port->GetServerPort().Close(system.Kernel());
|
||||
port->GetClientPort().Close(system.Kernel());
|
||||
};
|
||||
|
||||
// Register the port.
|
||||
KPort::Register(kernel, port);
|
||||
|
||||
// Add the client to the handle table.
|
||||
R_TRY(handle_table.Add(out_client, std::addressof(port->GetClientPort())));
|
||||
R_TRY(handle_table.Add(system.Kernel(), out_client, std::addressof(port->GetClientPort())));
|
||||
|
||||
// Ensure that we maintain a clean handle state on exit.
|
||||
ON_RESULT_FAILURE {
|
||||
handle_table.Remove(*out_client);
|
||||
handle_table.Remove(system.Kernel(), *out_client);
|
||||
};
|
||||
|
||||
// Add the server to the handle table.
|
||||
R_RETURN(handle_table.Add(out_server, std::addressof(port->GetServerPort())));
|
||||
R_RETURN(handle_table.Add(system.Kernel(), out_server, std::addressof(port->GetServerPort())));
|
||||
}
|
||||
|
||||
Result ConnectToPort(Core::System& system, Handle* out, Handle port) {
|
||||
@@ -93,36 +96,33 @@ Result ConnectToPort(Core::System& system, Handle* out, Handle port) {
|
||||
auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
|
||||
|
||||
// Get the client port.
|
||||
KScopedAutoObject client_port = handle_table.GetObject<KClientPort>(port);
|
||||
KScopedAutoObject client_port = handle_table.GetObject<KClientPort>(system.Kernel(), port);
|
||||
R_UNLESS(client_port.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Reserve a handle for the port.
|
||||
// NOTE: Nintendo really does write directly to the output handle here.
|
||||
R_TRY(handle_table.Reserve(out));
|
||||
R_TRY(handle_table.Reserve(system.Kernel(), out));
|
||||
ON_RESULT_FAILURE {
|
||||
handle_table.Unreserve(*out);
|
||||
handle_table.Unreserve(system.Kernel(), *out);
|
||||
};
|
||||
|
||||
// Create the session.
|
||||
KAutoObject* session;
|
||||
if (client_port->IsLight()) {
|
||||
R_TRY(client_port->CreateLightSession(
|
||||
reinterpret_cast<KLightClientSession**>(std::addressof(session))));
|
||||
if (client_port->IsLight(system.Kernel())) {
|
||||
R_TRY(client_port->CreateLightSession(system.Kernel(), reinterpret_cast<KLightClientSession**>(std::addressof(session))));
|
||||
} else {
|
||||
R_TRY(client_port->CreateSession(
|
||||
reinterpret_cast<KClientSession**>(std::addressof(session))));
|
||||
R_TRY(client_port->CreateSession(system.Kernel(), reinterpret_cast<KClientSession**>(std::addressof(session))));
|
||||
}
|
||||
|
||||
// Register the session.
|
||||
handle_table.Register(*out, session);
|
||||
session->Close();
|
||||
handle_table.Register(system.Kernel(), *out, session);
|
||||
session->Close(system.Kernel());
|
||||
|
||||
// We succeeded.
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name,
|
||||
int32_t max_sessions) {
|
||||
Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name, int32_t max_sessions) {
|
||||
// Copy the provided name from user memory to kernel memory.
|
||||
auto string_name =
|
||||
GetCurrentMemory(system.Kernel()).ReadCString(user_name, KObjectName::NameLengthMax);
|
||||
@@ -144,21 +144,21 @@ Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t
|
||||
R_UNLESS(port != nullptr, ResultOutOfResource);
|
||||
|
||||
// Initialize the new port.
|
||||
port->Initialize(max_sessions, false, 0);
|
||||
port->Initialize(system.Kernel(), max_sessions, false, 0);
|
||||
|
||||
// Register the port.
|
||||
KPort::Register(system.Kernel(), port);
|
||||
|
||||
// Ensure that our only reference to the port is in the handle table when we're done.
|
||||
SCOPE_EXIT {
|
||||
port->GetClientPort().Close();
|
||||
port->GetServerPort().Close();
|
||||
port->GetClientPort().Close(system.Kernel());
|
||||
port->GetServerPort().Close(system.Kernel());
|
||||
};
|
||||
|
||||
// Register the handle in the table.
|
||||
R_TRY(handle_table.Add(out_server_handle, std::addressof(port->GetServerPort())));
|
||||
R_TRY(handle_table.Add(system.Kernel(), out_server_handle, std::addressof(port->GetServerPort())));
|
||||
ON_RESULT_FAILURE {
|
||||
handle_table.Remove(*out_server_handle);
|
||||
handle_table.Remove(system.Kernel(), *out_server_handle);
|
||||
};
|
||||
|
||||
// Create a new object name.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
@@ -27,8 +27,8 @@ Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle) {
|
||||
|
||||
// Get the object from the handle table.
|
||||
KScopedAutoObject obj = GetCurrentProcess(system.Kernel())
|
||||
.GetHandleTable()
|
||||
.GetObject<KAutoObject>(static_cast<Handle>(handle));
|
||||
.GetHandleTable()
|
||||
.GetObject<KAutoObject>(system.Kernel(), Handle(handle));
|
||||
R_UNLESS(obj.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Get the process from the object.
|
||||
@@ -98,7 +98,7 @@ Result GetProcessInfo(Core::System& system, s64* out, Handle process_handle,
|
||||
LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type={:#X}", process_handle, info_type);
|
||||
|
||||
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
|
||||
KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
|
||||
KScopedAutoObject process = handle_table.GetObject<KProcess>(system.Kernel(), process_handle);
|
||||
if (process.IsNull()) {
|
||||
LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
|
||||
process_handle);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
@@ -48,7 +48,7 @@ Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, u
|
||||
|
||||
// Get the process from its handle.
|
||||
KScopedAutoObject process =
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(system.Kernel(), process_handle);
|
||||
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Validate that the address is in range.
|
||||
@@ -76,7 +76,7 @@ Result MapProcessMemory(Core::System& system, u64 dst_address, Handle process_ha
|
||||
// Get the processes.
|
||||
KProcess* dst_process = GetCurrentProcessPointer(system.Kernel());
|
||||
KScopedAutoObject src_process =
|
||||
dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(process_handle);
|
||||
dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(system.Kernel(), process_handle);
|
||||
R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Get the page tables.
|
||||
@@ -117,7 +117,7 @@ Result UnmapProcessMemory(Core::System& system, u64 dst_address, Handle process_
|
||||
// Get the processes.
|
||||
KProcess* dst_process = GetCurrentProcessPointer(system.Kernel());
|
||||
KScopedAutoObject src_process =
|
||||
dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(process_handle);
|
||||
dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(system.Kernel(), process_handle);
|
||||
R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Get the page tables.
|
||||
@@ -174,7 +174,7 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst
|
||||
}
|
||||
|
||||
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
|
||||
KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
|
||||
KScopedAutoObject process = handle_table.GetObject<KProcess>(system.Kernel(), process_handle);
|
||||
if (process.IsNull()) {
|
||||
LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).",
|
||||
process_handle);
|
||||
@@ -234,7 +234,7 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d
|
||||
}
|
||||
|
||||
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
|
||||
KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
|
||||
KScopedAutoObject process = handle_table.GetObject<KProcess>(system.Kernel(), process_handle);
|
||||
if (process.IsNull()) {
|
||||
LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).",
|
||||
process_handle);
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -23,7 +26,7 @@ Result QueryProcessMemory(Core::System& system, uint64_t out_memory_info, PageIn
|
||||
Handle process_handle, uint64_t address) {
|
||||
LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address);
|
||||
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
|
||||
KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
|
||||
KScopedAutoObject process = handle_table.GetObject<KProcess>(system.Kernel(), process_handle);
|
||||
if (process.IsNull()) {
|
||||
LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
|
||||
process_handle);
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -19,7 +22,7 @@ Result CreateResourceLimit(Core::System& system, Handle* out_handle) {
|
||||
|
||||
// Ensure we don't leak a reference to the limit.
|
||||
SCOPE_EXIT {
|
||||
resource_limit->Close();
|
||||
resource_limit->Close(system.Kernel());
|
||||
};
|
||||
|
||||
// Initialize the resource limit.
|
||||
@@ -29,7 +32,7 @@ Result CreateResourceLimit(Core::System& system, Handle* out_handle) {
|
||||
KResourceLimit::Register(kernel, resource_limit);
|
||||
|
||||
// Add the limit to the handle table.
|
||||
R_RETURN(GetCurrentProcess(kernel).GetHandleTable().Add(out_handle, resource_limit));
|
||||
R_RETURN(GetCurrentProcess(kernel).GetHandleTable().Add(system.Kernel(), out_handle, resource_limit));
|
||||
}
|
||||
|
||||
Result GetResourceLimitLimitValue(Core::System& system, s64* out_limit_value,
|
||||
@@ -42,8 +45,8 @@ Result GetResourceLimitLimitValue(Core::System& system, s64* out_limit_value,
|
||||
|
||||
// Get the resource limit.
|
||||
KScopedAutoObject resource_limit = GetCurrentProcess(system.Kernel())
|
||||
.GetHandleTable()
|
||||
.GetObject<KResourceLimit>(resource_limit_handle);
|
||||
.GetHandleTable()
|
||||
.GetObject<KResourceLimit>(system.Kernel(), resource_limit_handle);
|
||||
R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Get the limit value.
|
||||
@@ -62,8 +65,8 @@ Result GetResourceLimitCurrentValue(Core::System& system, s64* out_current_value
|
||||
|
||||
// Get the resource limit.
|
||||
KScopedAutoObject resource_limit = GetCurrentProcess(system.Kernel())
|
||||
.GetHandleTable()
|
||||
.GetObject<KResourceLimit>(resource_limit_handle);
|
||||
.GetHandleTable()
|
||||
.GetObject<KResourceLimit>(system.Kernel(), resource_limit_handle);
|
||||
R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Get the current value.
|
||||
@@ -83,7 +86,7 @@ Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_ha
|
||||
// Get the resource limit.
|
||||
KScopedAutoObject resource_limit = GetCurrentProcess(system.Kernel())
|
||||
.GetHandleTable()
|
||||
.GetObject<KResourceLimit>(resource_limit_handle);
|
||||
.GetObject<KResourceLimit>(system.Kernel(), resource_limit_handle);
|
||||
R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Set the limit value.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -23,7 +26,7 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien
|
||||
|
||||
// Reserve a new session from the process resource limit.
|
||||
// TODO: Dynamic resource limits
|
||||
KScopedResourceReservation session_reservation(std::addressof(process),
|
||||
KScopedResourceReservation session_reservation(system.Kernel(), std::addressof(process),
|
||||
LimitableResource::SessionCountMax);
|
||||
if (session_reservation.Succeeded()) {
|
||||
session = T::Create(system.Kernel());
|
||||
@@ -62,7 +65,7 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien
|
||||
R_UNLESS(session != nullptr, ResultOutOfResource);
|
||||
|
||||
// Initialize the session.
|
||||
session->Initialize(nullptr, name);
|
||||
session->Initialize(system.Kernel(), nullptr, name);
|
||||
|
||||
// Commit the session reservation.
|
||||
session_reservation.Commit();
|
||||
@@ -70,23 +73,23 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien
|
||||
// Ensure that we clean up the session (and its only references are handle table) on function
|
||||
// end.
|
||||
SCOPE_EXIT {
|
||||
session->GetClientSession().Close();
|
||||
session->GetServerSession().Close();
|
||||
session->GetClientSession().Close(system.Kernel());
|
||||
session->GetServerSession().Close(system.Kernel());
|
||||
};
|
||||
|
||||
// Register the session.
|
||||
T::Register(system.Kernel(), session);
|
||||
|
||||
// Add the server session to the handle table.
|
||||
R_TRY(handle_table.Add(out_server, std::addressof(session->GetServerSession())));
|
||||
R_TRY(handle_table.Add(system.Kernel(), out_server, std::addressof(session->GetServerSession())));
|
||||
|
||||
// Ensure that we maintain a clean handle state on exit.
|
||||
ON_RESULT_FAILURE {
|
||||
handle_table.Remove(*out_server);
|
||||
handle_table.Remove(system.Kernel(), *out_server);
|
||||
};
|
||||
|
||||
// Add the client session to the handle table.
|
||||
R_RETURN(handle_table.Add(out_client, std::addressof(session->GetClientSession())));
|
||||
R_RETURN(handle_table.Add(system.Kernel(), out_client, std::addressof(session->GetClientSession())));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -105,29 +108,29 @@ Result AcceptSession(Core::System& system, Handle* out, Handle port_handle) {
|
||||
auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
|
||||
|
||||
// Get the server port.
|
||||
KScopedAutoObject port = handle_table.GetObject<KServerPort>(port_handle);
|
||||
KScopedAutoObject port = handle_table.GetObject<KServerPort>(system.Kernel(), port_handle);
|
||||
R_UNLESS(port.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Reserve an entry for the new session.
|
||||
R_TRY(handle_table.Reserve(out));
|
||||
R_TRY(handle_table.Reserve(system.Kernel(), out));
|
||||
ON_RESULT_FAILURE {
|
||||
handle_table.Unreserve(*out);
|
||||
handle_table.Unreserve(system.Kernel(), *out);
|
||||
};
|
||||
|
||||
// Accept the session.
|
||||
KAutoObject* session;
|
||||
if (port->IsLight()) {
|
||||
session = port->AcceptLightSession();
|
||||
if (port->IsLight(system.Kernel())) {
|
||||
session = port->AcceptLightSession(system.Kernel());
|
||||
} else {
|
||||
session = port->AcceptSession();
|
||||
session = port->AcceptSession(system.Kernel());
|
||||
}
|
||||
|
||||
// Ensure we accepted successfully.
|
||||
R_UNLESS(session != nullptr, ResultNotFound);
|
||||
|
||||
// Register the session.
|
||||
handle_table.Register(*out, session);
|
||||
session->Close();
|
||||
handle_table.Register(system.Kernel(), *out, session);
|
||||
session->Close(system.Kernel());
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
@@ -49,18 +49,18 @@ Result MapSharedMemory(Core::System& system, Handle shmem_handle, u64 address, u
|
||||
auto& page_table = process.GetPageTable();
|
||||
|
||||
// Get the shared memory.
|
||||
KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(shmem_handle);
|
||||
KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(system.Kernel(), shmem_handle);
|
||||
R_UNLESS(shmem.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Verify that the mapping is in range.
|
||||
R_UNLESS(page_table.CanContain(address, size, KMemoryState::Shared), ResultInvalidMemoryRegion);
|
||||
|
||||
// Add the shared memory to the process.
|
||||
R_TRY(process.AddSharedMemory(shmem.GetPointerUnsafe(), address, size));
|
||||
R_TRY(process.AddSharedMemory(system.Kernel(), shmem.GetPointerUnsafe(), address, size));
|
||||
|
||||
// Ensure that we clean up the shared memory if we fail to map it.
|
||||
ON_RESULT_FAILURE {
|
||||
process.RemoveSharedMemory(shmem.GetPointerUnsafe(), address, size);
|
||||
process.RemoveSharedMemory(system.Kernel(), shmem.GetPointerUnsafe(), address, size);
|
||||
};
|
||||
|
||||
// Map the shared memory.
|
||||
@@ -79,7 +79,7 @@ Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, u64 address,
|
||||
auto& page_table = process.GetPageTable();
|
||||
|
||||
// Get the shared memory.
|
||||
KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(shmem_handle);
|
||||
KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(system.Kernel(), shmem_handle);
|
||||
R_UNLESS(shmem.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Verify that the mapping is in range.
|
||||
@@ -89,7 +89,7 @@ Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, u64 address,
|
||||
R_TRY(shmem->Unmap(process, address, size));
|
||||
|
||||
// Remove the shared memory from the process.
|
||||
process.RemoveSharedMemory(shmem.GetPointerUnsafe(), address, size);
|
||||
process.RemoveSharedMemory(system.Kernel(), shmem.GetPointerUnsafe(), address, size);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
@@ -20,7 +20,7 @@ Result CloseHandle(Core::System& system, Handle handle) {
|
||||
LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle);
|
||||
|
||||
// Remove the handle.
|
||||
R_UNLESS(GetCurrentProcess(system.Kernel()).GetHandleTable().Remove(handle),
|
||||
R_UNLESS(GetCurrentProcess(system.Kernel()).GetHandleTable().Remove(system.Kernel(), handle),
|
||||
ResultInvalidHandle);
|
||||
|
||||
R_SUCCEED();
|
||||
@@ -35,17 +35,17 @@ Result ResetSignal(Core::System& system, Handle handle) {
|
||||
|
||||
// Try to reset as readable event.
|
||||
{
|
||||
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(handle);
|
||||
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(system.Kernel(), handle);
|
||||
if (readable_event.IsNotNull()) {
|
||||
R_RETURN(readable_event->Reset());
|
||||
R_RETURN(readable_event->Reset(system.Kernel()));
|
||||
}
|
||||
}
|
||||
|
||||
// Try to reset as process.
|
||||
{
|
||||
KScopedAutoObject process = handle_table.GetObject<KProcess>(handle);
|
||||
KScopedAutoObject process = handle_table.GetObject<KProcess>(system.Kernel(), handle);
|
||||
if (process.IsNotNull()) {
|
||||
R_RETURN(process->Reset());
|
||||
R_RETURN(process->Reset(system.Kernel()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,35 +62,30 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha
|
||||
R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange);
|
||||
|
||||
// Get the synchronization context.
|
||||
auto& kernel = system.Kernel();
|
||||
auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
|
||||
auto objs = GetCurrentThread(kernel).GetSynchronizationObjectBuffer();
|
||||
auto handles = GetCurrentThread(kernel).GetHandleBuffer();
|
||||
auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
|
||||
auto objs = GetCurrentThread(system.Kernel()).GetSynchronizationObjectBuffer();
|
||||
auto handles = GetCurrentThread(system.Kernel()).GetHandleBuffer();
|
||||
|
||||
// Copy user handles.
|
||||
if (num_handles > 0) {
|
||||
// Get the handles.
|
||||
R_UNLESS(GetCurrentMemory(kernel).ReadBlock(user_handles, handles.data(),
|
||||
sizeof(Handle) * num_handles),
|
||||
ResultInvalidPointer);
|
||||
R_UNLESS(GetCurrentMemory(system.Kernel()).ReadBlock(user_handles, handles.data(), sizeof(Handle) * num_handles), ResultInvalidPointer);
|
||||
|
||||
// Convert the handles to objects.
|
||||
R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(
|
||||
objs.data(), handles.data(), num_handles),
|
||||
ResultInvalidHandle);
|
||||
R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(system.Kernel(), objs.data(), handles.data(), num_handles), ResultInvalidHandle);
|
||||
}
|
||||
|
||||
// Ensure handles are closed when we're done.
|
||||
SCOPE_EXIT {
|
||||
for (auto i = 0; i < num_handles; ++i) {
|
||||
objs[i]->Close();
|
||||
objs[i]->Close(system.Kernel());
|
||||
}
|
||||
};
|
||||
|
||||
// Convert the timeout from nanoseconds to ticks.
|
||||
s64 timeout;
|
||||
if (timeout_ns > 0) {
|
||||
u64 ticks = kernel.HardwareTimer().GetTick();
|
||||
u64 ticks = system.Kernel().HardwareTimer().GetTick();
|
||||
ticks += timeout_ns;
|
||||
ticks += 2;
|
||||
|
||||
@@ -100,7 +95,7 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha
|
||||
}
|
||||
|
||||
// Wait on the objects.
|
||||
Result res = KSynchronizationObject::Wait(kernel, out_index, objs.data(), num_handles, timeout);
|
||||
Result res = KSynchronizationObject::Wait(system.Kernel(), out_index, objs.data(), num_handles, timeout);
|
||||
|
||||
R_SUCCEED_IF(res == ResultSessionClosed);
|
||||
R_RETURN(res);
|
||||
@@ -111,31 +106,28 @@ Result CancelSynchronization(Core::System& system, Handle handle) {
|
||||
LOG_TRACE(Kernel_SVC, "called handle={:#X}", handle);
|
||||
|
||||
// Get the thread from its handle.
|
||||
KScopedAutoObject thread =
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(handle);
|
||||
KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(system.Kernel(), handle);
|
||||
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Cancel the thread's wait.
|
||||
thread->WaitCancel();
|
||||
thread->WaitCancel(system.Kernel());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void SynchronizePreemptionState(Core::System& system) {
|
||||
auto& kernel = system.Kernel();
|
||||
|
||||
// Lock the scheduler.
|
||||
KScopedSchedulerLock sl{kernel};
|
||||
KScopedSchedulerLock sl{system.Kernel()};
|
||||
|
||||
// If the current thread is pinned, unpin it.
|
||||
KProcess* cur_process = GetCurrentProcessPointer(kernel);
|
||||
const auto core_id = GetCurrentCoreId(kernel);
|
||||
KProcess* cur_process = GetCurrentProcessPointer(system.Kernel());
|
||||
const auto core_id = GetCurrentCoreId(system.Kernel());
|
||||
|
||||
if (cur_process->GetPinnedThread(core_id) == GetCurrentThreadPointer(kernel)) {
|
||||
if (cur_process->GetPinnedThread(core_id) == GetCurrentThreadPointer(system.Kernel())) {
|
||||
// Clear the current thread's interrupt flag.
|
||||
GetCurrentThread(kernel).ClearInterruptFlag();
|
||||
GetCurrentThread(system.Kernel()).ClearInterruptFlag(system.Kernel());
|
||||
|
||||
// Unpin the current thread.
|
||||
cur_process->UnpinCurrentThread();
|
||||
cur_process->UnpinCurrentThread(system.Kernel());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u
|
||||
R_UNLESS(process.CheckThreadPriority(priority), ResultInvalidPriority);
|
||||
|
||||
// Reserve a new thread from the process resource limit (waiting up to 100ms).
|
||||
KScopedResourceReservation thread_reservation(std::addressof(process),
|
||||
KScopedResourceReservation thread_reservation(system.Kernel(), std::addressof(process),
|
||||
LimitableResource::ThreadCountMax, 1,
|
||||
kernel.HardwareTimer().GetTick() + 100000000);
|
||||
R_UNLESS(thread_reservation.Succeeded(), ResultLimitReached);
|
||||
@@ -55,7 +55,7 @@ Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u
|
||||
KThread* thread = KThread::Create(kernel);
|
||||
R_UNLESS(thread != nullptr, ResultOutOfResource)
|
||||
SCOPE_EXIT {
|
||||
thread->Close();
|
||||
thread->Close(system.Kernel());
|
||||
};
|
||||
|
||||
// Initialize the thread.
|
||||
@@ -69,13 +69,13 @@ Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u
|
||||
thread_reservation.Commit();
|
||||
|
||||
// Clone the current fpu status to the new thread.
|
||||
thread->CloneFpuStatus();
|
||||
thread->CloneFpuStatus(system.Kernel());
|
||||
|
||||
// Register the new thread.
|
||||
KThread::Register(kernel, thread);
|
||||
|
||||
// Add the thread to the handle table.
|
||||
R_TRY(process.GetHandleTable().Add(out_handle, thread));
|
||||
R_TRY(process.GetHandleTable().Add(system.Kernel(), out_handle, thread));
|
||||
|
||||
// Pass the thread handle to the thread local region.
|
||||
process.GetMemory().Write32(GetInteger(thread->GetTlsAddress()) + 0x110, *out_handle);
|
||||
@@ -88,12 +88,11 @@ Result StartThread(Core::System& system, Handle thread_handle) {
|
||||
LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
|
||||
|
||||
// Get the thread from its handle.
|
||||
KScopedAutoObject thread =
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
|
||||
KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(system.Kernel(), thread_handle);
|
||||
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Try to start the thread.
|
||||
R_TRY(thread->Run());
|
||||
R_TRY(thread->Run(system.Kernel()));
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
@@ -102,7 +101,7 @@ Result StartThread(Core::System& system, Handle thread_handle) {
|
||||
void ExitThread(Core::System& system) {
|
||||
auto* const current_thread = GetCurrentThreadPointer(system.Kernel());
|
||||
system.GlobalSchedulerContext().RemoveThread(current_thread);
|
||||
current_thread->Exit();
|
||||
current_thread->Exit(system.Kernel());
|
||||
}
|
||||
|
||||
/// Sleep the current thread
|
||||
@@ -130,7 +129,7 @@ void SleepThread(Core::System& system, s64 ns) {
|
||||
|
||||
// Sleep.
|
||||
// NOTE: Nintendo does not check the result of this sleep.
|
||||
static_cast<void>(GetCurrentThread(kernel).Sleep(timeout));
|
||||
static_cast<void>(GetCurrentThread(kernel).Sleep(kernel, timeout));
|
||||
} else if (yield_type == Svc::YieldType::WithoutCoreMigration) {
|
||||
KScheduler::YieldWithoutCoreMigration(kernel);
|
||||
} else if (yield_type == Svc::YieldType::WithCoreMigration) {
|
||||
@@ -144,27 +143,23 @@ void SleepThread(Core::System& system, s64 ns) {
|
||||
|
||||
/// Gets the thread context
|
||||
Result GetThreadContext3(Core::System& system, u64 out_context, Handle thread_handle) {
|
||||
LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle={:#X}", out_context,
|
||||
thread_handle);
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle={:#X}", out_context, thread_handle);
|
||||
|
||||
// Get the thread from its handle.
|
||||
KScopedAutoObject thread =
|
||||
GetCurrentProcess(kernel).GetHandleTable().GetObject<KThread>(thread_handle);
|
||||
KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(system.Kernel(), thread_handle);
|
||||
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Require the handle be to a non-current thread in the current process.
|
||||
R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(kernel), ResultInvalidHandle);
|
||||
R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(kernel), ResultBusy);
|
||||
R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(system.Kernel()), ResultInvalidHandle);
|
||||
R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(system.Kernel()), ResultBusy);
|
||||
|
||||
// Get the thread context.
|
||||
Svc::ThreadContext context{};
|
||||
R_TRY(thread->GetThreadContext3(std::addressof(context)));
|
||||
R_TRY(thread->GetThreadContext3(system.Kernel(), std::addressof(context)));
|
||||
|
||||
// Copy the thread context to user space.
|
||||
R_UNLESS(
|
||||
GetCurrentMemory(kernel).WriteBlock(out_context, std::addressof(context), sizeof(context)),
|
||||
GetCurrentMemory(system.Kernel()).WriteBlock(out_context, std::addressof(context), sizeof(context)),
|
||||
ResultInvalidPointer);
|
||||
|
||||
R_SUCCEED();
|
||||
@@ -175,8 +170,7 @@ Result GetThreadPriority(Core::System& system, s32* out_priority, Handle handle)
|
||||
LOG_TRACE(Kernel_SVC, "called");
|
||||
|
||||
// Get the thread from its handle.
|
||||
KScopedAutoObject thread =
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(handle);
|
||||
KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(system.Kernel(), handle);
|
||||
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Get the thread's priority.
|
||||
@@ -195,11 +189,11 @@ Result SetThreadPriority(Core::System& system, Handle thread_handle, s32 priorit
|
||||
R_UNLESS(process.CheckThreadPriority(priority), ResultInvalidPriority);
|
||||
|
||||
// Get the thread from its handle.
|
||||
KScopedAutoObject thread = process.GetHandleTable().GetObject<KThread>(thread_handle);
|
||||
KScopedAutoObject thread = process.GetHandleTable().GetObject<KThread>(system.Kernel(), thread_handle);
|
||||
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Set the thread priority.
|
||||
thread->SetBasePriority(priority);
|
||||
thread->SetBasePriority(system.Kernel(), priority);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@@ -248,12 +242,11 @@ Result GetThreadCoreMask(Core::System& system, s32* out_core_id, u64* out_affini
|
||||
LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle);
|
||||
|
||||
// Get the thread from its handle.
|
||||
KScopedAutoObject thread =
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
|
||||
KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(system.Kernel(), thread_handle);
|
||||
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Get the core mask.
|
||||
R_RETURN(thread->GetCoreMask(out_core_id, out_affinity_mask));
|
||||
R_RETURN(thread->GetCoreMask(system.Kernel(), out_core_id, out_affinity_mask));
|
||||
}
|
||||
|
||||
Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id,
|
||||
@@ -279,18 +272,17 @@ Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id
|
||||
|
||||
// Get the thread from its handle.
|
||||
KScopedAutoObject thread =
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(system.Kernel(), thread_handle);
|
||||
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Set the core mask.
|
||||
R_RETURN(thread->SetCoreMask(core_id, affinity_mask));
|
||||
R_RETURN(thread->SetCoreMask(system.Kernel(), core_id, affinity_mask));
|
||||
}
|
||||
|
||||
/// Get the ID for the specified thread.
|
||||
Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) {
|
||||
// Get the thread from its handle.
|
||||
KScopedAutoObject thread =
|
||||
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
|
||||
KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(system.Kernel(), thread_handle);
|
||||
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Get the thread's id.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -43,8 +46,7 @@ Result CreateTransferMemory(Core::System& system, Handle* out, u64 address, u64
|
||||
auto& handle_table = process.GetHandleTable();
|
||||
|
||||
// Reserve a new transfer memory from the process resource limit.
|
||||
KScopedResourceReservation trmem_reservation(std::addressof(process),
|
||||
LimitableResource::TransferMemoryCountMax);
|
||||
KScopedResourceReservation trmem_reservation(system.Kernel(), std::addressof(process), LimitableResource::TransferMemoryCountMax);
|
||||
R_UNLESS(trmem_reservation.Succeeded(), ResultLimitReached);
|
||||
|
||||
// Create the transfer memory.
|
||||
@@ -53,14 +55,14 @@ Result CreateTransferMemory(Core::System& system, Handle* out, u64 address, u64
|
||||
|
||||
// Ensure the only reference is in the handle table when we're done.
|
||||
SCOPE_EXIT {
|
||||
trmem->Close();
|
||||
trmem->Close(system.Kernel());
|
||||
};
|
||||
|
||||
// Ensure that the region is in range.
|
||||
R_UNLESS(process.GetPageTable().Contains(address, size), ResultInvalidCurrentMemory);
|
||||
|
||||
// Initialize the transfer memory.
|
||||
R_TRY(trmem->Initialize(address, size, map_perm));
|
||||
R_TRY(trmem->Initialize(system.Kernel(), address, size, map_perm));
|
||||
|
||||
// Commit the reservation.
|
||||
trmem_reservation.Commit();
|
||||
@@ -69,7 +71,7 @@ Result CreateTransferMemory(Core::System& system, Handle* out, u64 address, u64
|
||||
KTransferMemory::Register(kernel, trmem);
|
||||
|
||||
// Add the transfer memory to the handle table.
|
||||
R_RETURN(handle_table.Add(out, trmem));
|
||||
R_RETURN(handle_table.Add(system.Kernel(), out, trmem));
|
||||
}
|
||||
|
||||
Result MapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size,
|
||||
@@ -86,7 +88,7 @@ Result MapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t add
|
||||
// Get the transfer memory.
|
||||
KScopedAutoObject trmem = GetCurrentProcess(system.Kernel())
|
||||
.GetHandleTable()
|
||||
.GetObject<KTransferMemory>(trmem_handle);
|
||||
.GetObject<KTransferMemory>(system.Kernel(), trmem_handle);
|
||||
R_UNLESS(trmem.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Verify that the mapping is in range.
|
||||
@@ -96,7 +98,7 @@ Result MapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t add
|
||||
ResultInvalidMemoryRegion);
|
||||
|
||||
// Map the transfer memory.
|
||||
R_TRY(trmem->Map(address, size, map_perm));
|
||||
R_TRY(trmem->Map(system.Kernel(), address, size, map_perm));
|
||||
|
||||
// We succeeded.
|
||||
R_SUCCEED();
|
||||
@@ -113,7 +115,7 @@ Result UnmapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t a
|
||||
// Get the transfer memory.
|
||||
KScopedAutoObject trmem = GetCurrentProcess(system.Kernel())
|
||||
.GetHandleTable()
|
||||
.GetObject<KTransferMemory>(trmem_handle);
|
||||
.GetObject<KTransferMemory>(system.Kernel(), trmem_handle);
|
||||
R_UNLESS(trmem.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
// Verify that the mapping is in range.
|
||||
@@ -123,7 +125,7 @@ Result UnmapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t a
|
||||
ResultInvalidMemoryRegion);
|
||||
|
||||
// Unmap the transfer memory.
|
||||
R_TRY(trmem->Unmap(address, size));
|
||||
R_TRY(trmem->Unmap(system.Kernel(), address, size));
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user