aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-31 03:02:20 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-11-01 12:35:47 -0500
commit7f31fc4f538e5442e9ae72e3d6f9f65702832b9e (patch)
treefd1288bc2c1442b97a09da800a49eba988b34cf4 /src/core
parent5b4695e5f2772db22317a3445fd539e563dae46b (diff)
nx2: echo the TIPC 0 handshake on the gpu and vi2 sessions
Newer SDKs open the Switch 2 sessions with TIPC 0(u64 token) and expect the token back. The syncpt session echoed it; the gpu and vi2 sessions relied on the auto stub leaving the request's words in place. Share the syncpt handler.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/service/nx2_gsv.h22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/core/hle/service/nx2_gsv.h b/src/core/hle/service/nx2_gsv.h
index 6acc84bc30..a34f3c24af 100644
--- a/src/core/hle/service/nx2_gsv.h
+++ b/src/core/hle/service/nx2_gsv.h
@@ -102,6 +102,14 @@ inline void TipcReplyWords(HLERequestContext& ctx, std::initializer_list<u32> wo
TipcReplyWords(ctx, std::span<const u32>{words.begin(), words.size()});
}
+// TIPC 0(u64 token) on the Switch 2 sessions: a handshake newer SDKs send first; the reply echoes
+// the token. (The auto stub's reply only echoed it by leaving the request's words in place.)
+inline void TipcHandshake(HLERequestContext& ctx, std::string_view session) {
+ const auto* w = ctx.CommandBuffer();
+ LOG_INFO(Service, "{} TIPC 0 handshake {:#x}", session, u64{w[2]} | (u64{w[3]} << 32));
+ TipcReplyWords(ctx, {w[2], w[3]});
+}
+
// Replies with success and a copied handle to a new session served by `iface`.
template <class T>
inline void ReturnRawSession(Core::System& system, HLERequestContext& ctx, std::shared_ptr<T> iface) {
@@ -160,9 +168,7 @@ public:
private:
// Newer SDKs (title 1) open with TIPC 0(u64 token) and abort unless the reply echoes it.
void Handshake(HLERequestContext& ctx) {
- const auto* w = ctx.CommandBuffer();
- LOG_INFO(Service, "nx2:syncpt TIPC 0 handshake {:#x}", u64{w[2]} | (u64{w[3]} << 32));
- TipcReplyWords(ctx, {w[2], w[3]});
+ TipcHandshake(ctx, "nx2:syncpt");
}
void GetCount(HLERequestContext& ctx) {
@@ -299,6 +305,7 @@ public:
explicit INx2GpuSession(Core::System& system_)
: ServiceFramework{system_, "nx2:gpu"}, m_context{system_, "nx2:gpu"} {
RegisterHandlersTipc({
+ {0, &INx2GpuSession::Handshake, "Handshake"},
{11, &INx2GpuSession::GetIdRange, "GetIdRange (guessed)"},
{12, &INx2GpuSession::GetIdEvent, "GetIdEvent (guessed)"},
{21, &INx2GpuSession::Start, "Start (guessed)"},
@@ -334,6 +341,10 @@ public:
}
private:
+ void Handshake(HLERequestContext& ctx) {
+ TipcHandshake(ctx, "nx2:gpu");
+ }
+
static constexpr u32 NumIds = 32;
Kernel::KEvent* EventFor(u32 id) {
@@ -1401,6 +1412,7 @@ public:
: ServiceFramework{system_, "nx2:vi2"}, m_context{system_, "nx2:vi2"},
m_objects{std::move(objects_)} {
RegisterHandlersTipc({
+ {0, &INx2Vi2Session::Handshake, "Handshake"},
{1, &INx2Vi2Session::ReturnOne, "Unknown1"},
{3, &INx2Vi2Session::ReturnOne, "GetDisplayCount (guessed)"},
{5, &INx2Vi2Session::GetTimestampRecorderCount, "GetTimestampRecorderCount (guessed)"},
@@ -1447,6 +1459,10 @@ public:
}
private:
+ void Handshake(HLERequestContext& ctx) {
+ TipcHandshake(ctx, "nx2:vi2");
+ }
+
// 229(u64 client token, u32 slot, u32 image, ...fences): result, u64 mask of buffer slots the
// client may acquire next, four zero words. Nothing is shown yet; every slot is handed back
// at once (changes.patch's default mask is 0x7fff).