diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-29 03:39:52 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-29 03:39:52 -0400 |
| commit | e17fd9cef116a088f080ca502951e500864a58b6 (patch) | |
| tree | e7ff65f614622515d6a2e4263521909eea89a5d8 /src/core/hle/kernel/svc.cpp | |
| parent | ea6c1193fbfa95e586bb6d129dc684163a12cb3e (diff) | |
| parent | 80c79333fe6fd28a31b65b997f1cbf2987711c91 (diff) | |
Merge Switch 2 work from local Eden (nx2 at b0dd3fe)
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 3542d5a3b6..53d964ecbc 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -6,6 +6,8 @@ // This file is automatically generated using svc_generator.py. // DO NOT MODIFY IT MANUALLY +#include <cstdlib> +#include <cstring> #include <type_traits> #include "core/arm/arm_interface.h" @@ -2505,11 +2507,60 @@ void Call(Core::System& system, u32 imm) { LOG_TRACE(Kernel_SVC, "{} [0]={:#x} [1]={:#x} [2]={:#x} [3]={:#x} [4]={:#x} [5]={:#x} [6]={:#x}", imm, GetArg64(args, 0), GetArg64(args, 1), GetArg64(args, 2), GetArg64(args, 3), GetArg64(args, 4), GetArg64(args, 5), GetArg64(args, 6)); - if (process.Is64Bit()) { + // Set EDEN_NX2_SVC_TRACE=1 to log every SVC with its arguments and results, or + // EDEN_NX2_SVC_TRACE=<first>:<last> for presents first..last only (a frame-time profile). + static const std::pair<u64, u64> trace_range = [] { + const char* text = std::getenv("EDEN_NX2_SVC_TRACE"); + if (text == nullptr) return std::pair<u64, u64>{1, 0}; + const char* colon = std::strchr(text, ':'); + if (colon == nullptr) return std::pair<u64, u64>{0, ~u64{}}; + return std::pair<u64, u64>{std::strtoull(text, nullptr, 10), std::strtoull(colon + 1, nullptr, 10)}; + }(); + const u64 presents = Core::g_nx2_present_count.load(std::memory_order_relaxed); + const bool svc_trace = presents >= trace_range.first && presents <= trace_range.second; + if (svc_trace) { + LOG_INFO(Kernel_SVC, "svc {:#04x} in t{} [0]={:#x} [1]={:#x} [2]={:#x} [3]={:#x}", imm, + GetCurrentThread(kernel).GetThreadId(), + GetArg64(args, 0), GetArg64(args, 1), GetArg64(args, 2), GetArg64(args, 3)); + } + if (imm == 0x80) { + // Switch 2 only: svcSetGpuMemoryAttribute(address, size, mask, attr). nn::gpu::sdk and + // nn::gs native memory set the new "GPU accessible" attribute (0x20) before registering + // memory with the GPU and clear it on destruction; NVN can see it through QueryMemory. + // Same checks as svcSetMemoryAttribute, restricted to that bit (as in changes.patch). + const u64 address = GetArg64(args, 0); + const u64 size = GetArg64(args, 1); + const u32 mask = static_cast<u32>(GetArg64(args, 2)); + const u32 attr = static_cast<u32>(GetArg64(args, 3)); + constexpr u32 Supported = static_cast<u32>(Svc::MemoryAttribute::GpuAccessible); + auto& page_table = process.GetPageTable(); + Result result = ResultSuccess; + if (!Common::IsAligned(address, PageSize)) { + result = ResultInvalidAddress; + } else if (size == 0 || !Common::IsAligned(size, PageSize)) { + result = ResultInvalidSize; + } else if ((attr & ~mask) != 0 || ((mask | attr) & ~Supported) != 0) { + result = ResultInvalidCombination; + } else if (address + size <= address || !page_table.Contains(address, size)) { + result = ResultInvalidCurrentMemory; + } else { + result = page_table.SetMemoryAttribute(address, size, + static_cast<KMemoryAttribute>(mask), + static_cast<KMemoryAttribute>(attr)); + } + LOG_DEBUG(Kernel_SVC, "Switch 2 svc 0x80 addr={:#x} size={:#x} mask={:#x} attr={:#x} -> {:#x}", + address, size, mask, attr, result.raw); + args[0] = result.raw; + } else if (process.Is64Bit()) { Call64(system, imm, args); } else { Call32(system, imm, args); } + if (svc_trace) { + LOG_INFO(Kernel_SVC, "svc {:#04x} out t{} [0]={:#x} [1]={:#x} [2]={:#x}", imm, + GetCurrentThread(kernel).GetThreadId(), GetArg64(args, 0), GetArg64(args, 1), + GetArg64(args, 2)); + } //kernel.ExitSVCProfile(); kernel.CurrentPhysicalCore().LoadSvcArguments(process, args); } |
