diff options
| author | 2022-10-03 22:52:52 -0400 | |
|---|---|---|
| committer | 2022-10-11 18:15:45 -0400 | |
| commit | 9b34afa588c4e4bf312e2812ffe6879e09dafc75 (patch) | |
| tree | 052c8d4c70805dabfa6fc06264bbe53b1911c8ba /src/core/hle/kernel/svc.cpp | |
| parent | general: preliminary support for hbl (diff) | |
| download | yuzu-9b34afa588c4e4bf312e2812ffe6879e09dafc75.tar.gz yuzu-9b34afa588c4e4bf312e2812ffe6879e09dafc75.tar.xz yuzu-9b34afa588c4e4bf312e2812ffe6879e09dafc75.zip | |
Add implementation of svcCreateSession
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 90 |
1 files changed, 89 insertions, 1 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 27e5a805d..3a89511aa 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include "core/hle/kernel/k_resource_limit.h" | 29 | #include "core/hle/kernel/k_resource_limit.h" |
| 30 | #include "core/hle/kernel/k_scheduler.h" | 30 | #include "core/hle/kernel/k_scheduler.h" |
| 31 | #include "core/hle/kernel/k_scoped_resource_reservation.h" | 31 | #include "core/hle/kernel/k_scoped_resource_reservation.h" |
| 32 | #include "core/hle/kernel/k_session.h" | ||
| 32 | #include "core/hle/kernel/k_shared_memory.h" | 33 | #include "core/hle/kernel/k_shared_memory.h" |
| 33 | #include "core/hle/kernel/k_synchronization_object.h" | 34 | #include "core/hle/kernel/k_synchronization_object.h" |
| 34 | #include "core/hle/kernel/k_thread.h" | 35 | #include "core/hle/kernel/k_thread.h" |
| @@ -256,6 +257,93 @@ static Result UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u3 | |||
| 256 | return UnmapMemory(system, dst_addr, src_addr, size); | 257 | return UnmapMemory(system, dst_addr, src_addr, size); |
| 257 | } | 258 | } |
| 258 | 259 | ||
| 260 | template <typename T> | ||
| 261 | Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, u64 name) { | ||
| 262 | auto& process = *system.CurrentProcess(); | ||
| 263 | auto& handle_table = process.GetHandleTable(); | ||
| 264 | |||
| 265 | // Declare the session we're going to allocate. | ||
| 266 | T* session; | ||
| 267 | |||
| 268 | // Reserve a new session from the process resource limit. | ||
| 269 | // FIXME: LimitableResource_SessionCountMax | ||
| 270 | KScopedResourceReservation session_reservation(&process, LimitableResource::Sessions); | ||
| 271 | if (session_reservation.Succeeded()) { | ||
| 272 | session = T::Create(system.Kernel()); | ||
| 273 | } else { | ||
| 274 | return ResultLimitReached; | ||
| 275 | |||
| 276 | // // We couldn't reserve a session. Check that we support dynamically expanding the | ||
| 277 | // // resource limit. | ||
| 278 | // R_UNLESS(process.GetResourceLimit() == | ||
| 279 | // &system.Kernel().GetSystemResourceLimit(), ResultLimitReached); | ||
| 280 | // R_UNLESS(KTargetSystem::IsDynamicResourceLimitsEnabled(), ResultLimitReached()); | ||
| 281 | |||
| 282 | // // Try to allocate a session from unused slab memory. | ||
| 283 | // session = T::CreateFromUnusedSlabMemory(); | ||
| 284 | // R_UNLESS(session != nullptr, ResultLimitReached); | ||
| 285 | // ON_RESULT_FAILURE { session->Close(); }; | ||
| 286 | |||
| 287 | // // If we're creating a KSession, we want to add two KSessionRequests to the heap, to | ||
| 288 | // // prevent request exhaustion. | ||
| 289 | // // NOTE: Nintendo checks if session->DynamicCast<KSession *>() != nullptr, but there's | ||
| 290 | // // no reason to not do this statically. | ||
| 291 | // if constexpr (std::same_as<T, KSession>) { | ||
| 292 | // for (size_t i = 0; i < 2; i++) { | ||
| 293 | // KSessionRequest* request = KSessionRequest::CreateFromUnusedSlabMemory(); | ||
| 294 | // R_UNLESS(request != nullptr, ResultLimitReached); | ||
| 295 | // request->Close(); | ||
| 296 | // } | ||
| 297 | // } | ||
| 298 | |||
| 299 | // We successfully allocated a session, so add the object we allocated to the resource | ||
| 300 | // limit. | ||
| 301 | // system.Kernel().GetSystemResourceLimit().Reserve(LimitableResource::Sessions, 1); | ||
| 302 | } | ||
| 303 | |||
| 304 | // Check that we successfully created a session. | ||
| 305 | R_UNLESS(session != nullptr, ResultOutOfResource); | ||
| 306 | |||
| 307 | // Initialize the session. | ||
| 308 | session->Initialize(nullptr, fmt::format("{}", name)); | ||
| 309 | |||
| 310 | // Commit the session reservation. | ||
| 311 | session_reservation.Commit(); | ||
| 312 | |||
| 313 | // Ensure that we clean up the session (and its only references are handle table) on function | ||
| 314 | // end. | ||
| 315 | SCOPE_EXIT({ | ||
| 316 | session->GetClientSession().Close(); | ||
| 317 | session->GetServerSession().Close(); | ||
| 318 | }); | ||
| 319 | |||
| 320 | // Register the session. | ||
| 321 | T::Register(system.Kernel(), session); | ||
| 322 | |||
| 323 | // Add the server session to the handle table. | ||
| 324 | R_TRY(handle_table.Add(out_server, &session->GetServerSession())); | ||
| 325 | |||
| 326 | // Add the client session to the handle table. */ | ||
| 327 | const auto result = handle_table.Add(out_client, &session->GetClientSession()); | ||
| 328 | |||
| 329 | if (!R_SUCCEEDED(result)) { | ||
| 330 | // Ensure that we maintaing a clean handle state on exit. | ||
| 331 | handle_table.Remove(*out_server); | ||
| 332 | } | ||
| 333 | |||
| 334 | return result; | ||
| 335 | } | ||
| 336 | |||
| 337 | static Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, | ||
| 338 | u32 is_light, u64 name) { | ||
| 339 | if (is_light) { | ||
| 340 | // return CreateSession<KLightSession>(system, out_server, out_client, name); | ||
| 341 | return ResultUnknown; | ||
| 342 | } else { | ||
| 343 | return CreateSession<KSession>(system, out_server, out_client, name); | ||
| 344 | } | ||
| 345 | } | ||
| 346 | |||
| 259 | /// Connect to an OS service given the port name, returns the handle to the port to out | 347 | /// Connect to an OS service given the port name, returns the handle to the port to out |
| 260 | static Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) { | 348 | static Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) { |
| 261 | auto& memory = system.Memory(); | 349 | auto& memory = system.Memory(); |
| @@ -2860,7 +2948,7 @@ static const FunctionDef SVC_Table_64[] = { | |||
| 2860 | {0x3D, SvcWrap64<ChangeKernelTraceState>, "ChangeKernelTraceState"}, | 2948 | {0x3D, SvcWrap64<ChangeKernelTraceState>, "ChangeKernelTraceState"}, |
| 2861 | {0x3E, nullptr, "Unknown3e"}, | 2949 | {0x3E, nullptr, "Unknown3e"}, |
| 2862 | {0x3F, nullptr, "Unknown3f"}, | 2950 | {0x3F, nullptr, "Unknown3f"}, |
| 2863 | {0x40, nullptr, "CreateSession"}, | 2951 | {0x40, SvcWrap64<CreateSession>, "CreateSession"}, |
| 2864 | {0x41, nullptr, "AcceptSession"}, | 2952 | {0x41, nullptr, "AcceptSession"}, |
| 2865 | {0x42, nullptr, "ReplyAndReceiveLight"}, | 2953 | {0x42, nullptr, "ReplyAndReceiveLight"}, |
| 2866 | {0x43, nullptr, "ReplyAndReceive"}, | 2954 | {0x43, nullptr, "ReplyAndReceive"}, |