summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.ci/scripts/transifex/docker.sh12
-rw-r--r--.github/workflows/ci.yml4
-rw-r--r--dist/languages/.tx/config2
-rw-r--r--dist/languages/README.md4
-rw-r--r--src/audio_core/in/audio_in_system.cpp6
-rw-r--r--src/audio_core/out/audio_out_system.cpp6
-rw-r--r--src/audio_core/renderer/system.cpp4
-rw-r--r--src/audio_core/sink/sdl2_sink.cpp4
-rw-r--r--src/audio_core/sink/sink_details.cpp4
-rw-r--r--src/common/fixed_point.h97
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp1
-rw-r--r--src/core/hid/irs_types.h20
-rw-r--r--src/core/hle/ipc_helpers.h3
-rw-r--r--src/core/hle/kernel/hle_ipc.h2
-rw-r--r--src/core/hle/kernel/k_class_token.cpp12
-rw-r--r--src/core/hle/kernel/k_class_token.h1
-rw-r--r--src/core/hle/kernel/k_client_session.cpp5
-rw-r--r--src/core/hle/kernel/k_client_session.h3
-rw-r--r--src/core/hle/kernel/k_event.cpp44
-rw-r--r--src/core/hle/kernel/k_event.h31
-rw-r--r--src/core/hle/kernel/k_readable_event.cpp33
-rw-r--r--src/core/hle/kernel/k_readable_event.h17
-rw-r--r--src/core/hle/kernel/k_server_session.cpp243
-rw-r--r--src/core/hle/kernel/k_server_session.h37
-rw-r--r--src/core/hle/kernel/k_writable_event.cpp35
-rw-r--r--src/core/hle/kernel/k_writable_event.h39
-rw-r--r--src/core/hle/kernel/kernel.h4
-rw-r--r--src/core/hle/kernel/svc.cpp195
-rw-r--r--src/core/hle/kernel/svc_wrap.h32
-rw-r--r--src/core/hle/service/acc/async_context.cpp2
-rw-r--r--src/core/hle/service/am/am.cpp12
-rw-r--r--src/core/hle/service/am/applets/applets.cpp10
-rw-r--r--src/core/hle/service/audio/audren_u.cpp4
-rw-r--r--src/core/hle/service/bcat/backend/backend.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp5
-rw-r--r--src/core/hle/service/hid/controllers/palma.cpp16
-rw-r--r--src/core/hle/service/hid/hid.cpp2
-rw-r--r--src/core/hle/service/hid/hidbus/ringcon.cpp8
-rw-r--r--src/core/hle/service/hid/irsensor/pointing_processor.h4
-rw-r--r--src/core/hle/service/kernel_helpers.cpp5
-rw-r--r--src/core/hle/service/ldn/ldn.cpp2
-rw-r--r--src/core/hle/service/nfp/nfp_device.cpp6
-rw-r--r--src/core/hle/service/nim/nim.cpp4
-rw-r--r--src/core/hle/service/ns/ns.cpp30
-rw-r--r--src/core/hle/service/ns/ns.h3
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp5
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp1
-rw-r--r--src/core/hle/service/nvdrv/nvdrv_interface.h4
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue_producer.cpp9
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue_producer.h1
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h1
-rw-r--r--src/core/hle/service/ptm/psm.cpp6
-rw-r--r--src/core/hle/service/ptm/ts.cpp15
-rw-r--r--src/core/hle/service/ptm/ts.h1
-rw-r--r--src/core/hle/service/set/set_sys.cpp79
-rw-r--r--src/core/hle/service/set/set_sys.h2
-rw-r--r--src/core/hle/service/sm/sm.cpp3
-rw-r--r--src/core/hle/service/time/system_clock_context_update_callback.cpp10
-rw-r--r--src/core/hle/service/time/system_clock_context_update_callback.h6
-rw-r--r--src/core/hle/service/vi/display/vi_display.cpp3
-rw-r--r--src/core/hle/service/vi/vi_results.h2
-rw-r--r--src/video_core/texture_cache/descriptor_table.h2
-rw-r--r--src/video_core/texture_cache/texture_cache.h8
-rw-r--r--src/yuzu/main.cpp2
65 files changed, 798 insertions, 379 deletions
diff --git a/.ci/scripts/transifex/docker.sh b/.ci/scripts/transifex/docker.sh
index 6237b3f73..6ddbfd0dd 100755
--- a/.ci/scripts/transifex/docker.sh
+++ b/.ci/scripts/transifex/docker.sh
@@ -3,15 +3,6 @@
3# SPDX-FileCopyrightText: 2021 yuzu Emulator Project 3# SPDX-FileCopyrightText: 2021 yuzu Emulator Project
4# SPDX-License-Identifier: GPL-2.0-or-later 4# SPDX-License-Identifier: GPL-2.0-or-later
5 5
6# Setup RC file for tx
7cat << EOF > ~/.transifexrc
8[https://www.transifex.com]
9hostname = https://www.transifex.com
10username = api
11password = $TRANSIFEX_API_TOKEN
12EOF
13
14
15set -x 6set -x
16 7
17echo -e "\e[1m\e[33mBuild tools information:\e[0m" 8echo -e "\e[1m\e[33mBuild tools information:\e[0m"
@@ -19,9 +10,6 @@ cmake --version
19gcc -v 10gcc -v
20tx --version 11tx --version
21 12
22# vcpkg needs these: curl zip unzip tar, have tar
23apt-get install -y curl zip unzip
24
25mkdir build && cd build 13mkdir build && cd build
26cmake .. -DENABLE_QT_TRANSLATION=ON -DGENERATE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_SDL2=OFF -DYUZU_TESTS=OFF -DYUZU_USE_BUNDLED_VCPKG=ON 14cmake .. -DENABLE_QT_TRANSLATION=ON -DGENERATE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_SDL2=OFF -DYUZU_TESTS=OFF -DYUZU_USE_BUNDLED_VCPKG=ON
27make translation 15make translation
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index aa5824824..25ef1f078 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -19,11 +19,11 @@ jobs:
19 - uses: actions/checkout@v3 19 - uses: actions/checkout@v3
20 with: 20 with:
21 submodules: recursive 21 submodules: recursive
22 fetch-depth: 0 22 fetch-depth: 0
23 - name: Update Translation 23 - name: Update Translation
24 run: ./.ci/scripts/transifex/docker.sh 24 run: ./.ci/scripts/transifex/docker.sh
25 env: 25 env:
26 TRANSIFEX_API_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }} 26 TX_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
27 27
28 reuse: 28 reuse:
29 runs-on: ubuntu-latest 29 runs-on: ubuntu-latest
diff --git a/dist/languages/.tx/config b/dist/languages/.tx/config
index 0d9b512ea..30e76b925 100644
--- a/dist/languages/.tx/config
+++ b/dist/languages/.tx/config
@@ -1,7 +1,7 @@
1[main] 1[main]
2host = https://www.transifex.com 2host = https://www.transifex.com
3 3
4[yuzu.emulator] 4[o:yuzu-emulator:p:yuzu:r:emulator]
5file_filter = <lang>.ts 5file_filter = <lang>.ts
6source_file = en.ts 6source_file = en.ts
7source_lang = en 7source_lang = en
diff --git a/dist/languages/README.md b/dist/languages/README.md
index 61981ab1d..c5ea1ada0 100644
--- a/dist/languages/README.md
+++ b/dist/languages/README.md
@@ -1 +1,3 @@
1This directory stores translation patches (TS files) for yuzu Qt frontend. This directory is linked with [yuzu project on transifex](https://www.transifex.com/yuzu-emulator/yuzu), so you can update the translation by executing `tx pull -a`. If you want to contribute to the translation, please go the transifex link and submit your translation there. This directory on the main repo will be synchronized with transifex periodically. Do not directly open PRs on github to modify the translation. 1This directory stores translation patches (TS files) for yuzu Qt frontend. This directory is linked with [yuzu project on transifex](https://www.transifex.com/yuzu-emulator/yuzu), so you can update the translation by executing `tx pull -t -a`. If you want to contribute to the translation, please go the transifex link and submit your translation there. This directory on the main repo will be synchronized with transifex periodically.
2
3Do not directly open PRs on github to modify the translation.
diff --git a/src/audio_core/in/audio_in_system.cpp b/src/audio_core/in/audio_in_system.cpp
index e7f918a47..6b7e6715c 100644
--- a/src/audio_core/in/audio_in_system.cpp
+++ b/src/audio_core/in/audio_in_system.cpp
@@ -23,7 +23,7 @@ System::~System() {
23void System::Finalize() { 23void System::Finalize() {
24 Stop(); 24 Stop();
25 session->Finalize(); 25 session->Finalize();
26 buffer_event->GetWritableEvent().Signal(); 26 buffer_event->Signal();
27} 27}
28 28
29void System::StartSession() { 29void System::StartSession() {
@@ -142,7 +142,7 @@ void System::ReleaseBuffers() {
142 142
143 if (signal) { 143 if (signal) {
144 // Signal if any buffer was released, or if none are registered, we need more. 144 // Signal if any buffer was released, or if none are registered, we need more.
145 buffer_event->GetWritableEvent().Signal(); 145 buffer_event->Signal();
146 } 146 }
147} 147}
148 148
@@ -159,7 +159,7 @@ bool System::FlushAudioInBuffers() {
159 buffers.FlushBuffers(buffers_released); 159 buffers.FlushBuffers(buffers_released);
160 160
161 if (buffers_released > 0) { 161 if (buffers_released > 0) {
162 buffer_event->GetWritableEvent().Signal(); 162 buffer_event->Signal();
163 } 163 }
164 return true; 164 return true;
165} 165}
diff --git a/src/audio_core/out/audio_out_system.cpp b/src/audio_core/out/audio_out_system.cpp
index 8b907590a..48a801923 100644
--- a/src/audio_core/out/audio_out_system.cpp
+++ b/src/audio_core/out/audio_out_system.cpp
@@ -24,7 +24,7 @@ System::~System() {
24void System::Finalize() { 24void System::Finalize() {
25 Stop(); 25 Stop();
26 session->Finalize(); 26 session->Finalize();
27 buffer_event->GetWritableEvent().Signal(); 27 buffer_event->Signal();
28} 28}
29 29
30std::string_view System::GetDefaultOutputDeviceName() const { 30std::string_view System::GetDefaultOutputDeviceName() const {
@@ -141,7 +141,7 @@ void System::ReleaseBuffers() {
141 bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session)}; 141 bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session)};
142 if (signal) { 142 if (signal) {
143 // Signal if any buffer was released, or if none are registered, we need more. 143 // Signal if any buffer was released, or if none are registered, we need more.
144 buffer_event->GetWritableEvent().Signal(); 144 buffer_event->Signal();
145 } 145 }
146} 146}
147 147
@@ -158,7 +158,7 @@ bool System::FlushAudioOutBuffers() {
158 buffers.FlushBuffers(buffers_released); 158 buffers.FlushBuffers(buffers_released);
159 159
160 if (buffers_released > 0) { 160 if (buffers_released > 0) {
161 buffer_event->GetWritableEvent().Signal(); 161 buffer_event->Signal();
162 } 162 }
163 return true; 163 return true;
164} 164}
diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp
index 7a217969e..bde794cd1 100644
--- a/src/audio_core/renderer/system.cpp
+++ b/src/audio_core/renderer/system.cpp
@@ -534,7 +534,7 @@ Result System::Update(std::span<const u8> input, std::span<u8> performance, std:
534 return result; 534 return result;
535 } 535 }
536 536
537 adsp_rendered_event->GetWritableEvent().Clear(); 537 adsp_rendered_event->Clear();
538 num_times_updated++; 538 num_times_updated++;
539 539
540 const auto end_time{core.CoreTiming().GetClockTicks()}; 540 const auto end_time{core.CoreTiming().GetClockTicks()};
@@ -625,7 +625,7 @@ void System::SendCommandToDsp() {
625 reset_command_buffers = false; 625 reset_command_buffers = false;
626 command_buffer_size = command_size; 626 command_buffer_size = command_size;
627 if (remaining_command_count == 0) { 627 if (remaining_command_count == 0) {
628 adsp_rendered_event->GetWritableEvent().Signal(); 628 adsp_rendered_event->Signal();
629 } 629 }
630 } else { 630 } else {
631 adsp.ClearRemainCount(session_id); 631 adsp.ClearRemainCount(session_id);
diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp
index f12ebf7fe..c138dc628 100644
--- a/src/audio_core/sink/sdl2_sink.cpp
+++ b/src/audio_core/sink/sdl2_sink.cpp
@@ -230,7 +230,9 @@ std::vector<std::string> ListSDLSinkDevices(bool capture) {
230 230
231 const int device_count = SDL_GetNumAudioDevices(capture); 231 const int device_count = SDL_GetNumAudioDevices(capture);
232 for (int i = 0; i < device_count; ++i) { 232 for (int i = 0; i < device_count; ++i) {
233 device_list.emplace_back(SDL_GetAudioDeviceName(i, 0)); 233 if (const char* name = SDL_GetAudioDeviceName(i, capture)) {
234 device_list.emplace_back(name);
235 }
234 } 236 }
235 237
236 return device_list; 238 return device_list;
diff --git a/src/audio_core/sink/sink_details.cpp b/src/audio_core/sink/sink_details.cpp
index b878bf23f..39ea6d91b 100644
--- a/src/audio_core/sink/sink_details.cpp
+++ b/src/audio_core/sink/sink_details.cpp
@@ -47,7 +47,7 @@ constexpr SinkDetails sink_details[] = {
47#endif 47#endif
48#ifdef HAVE_SDL2 48#ifdef HAVE_SDL2
49 SinkDetails{ 49 SinkDetails{
50 "sdl", 50 "sdl2",
51 [](std::string_view device_id) -> std::unique_ptr<Sink> { 51 [](std::string_view device_id) -> std::unique_ptr<Sink> {
52 return std::make_unique<SDLSink>(device_id); 52 return std::make_unique<SDLSink>(device_id);
53 }, 53 },
@@ -76,7 +76,7 @@ const SinkDetails& GetOutputSinkDetails(std::string_view sink_id) {
76#if defined(HAVE_CUBEB) && defined(HAVE_SDL2) 76#if defined(HAVE_CUBEB) && defined(HAVE_SDL2)
77 iter = find_backend("cubeb"); 77 iter = find_backend("cubeb");
78 if (iter->latency() > TargetSampleCount * 3) { 78 if (iter->latency() > TargetSampleCount * 3) {
79 iter = find_backend("sdl"); 79 iter = find_backend("sdl2");
80 } 80 }
81#else 81#else
82 iter = std::begin(sink_details); 82 iter = std::begin(sink_details);
diff --git a/src/common/fixed_point.h b/src/common/fixed_point.h
index 4a0f72cc9..6eb6afe2f 100644
--- a/src/common/fixed_point.h
+++ b/src/common/fixed_point.h
@@ -4,14 +4,7 @@
4// From: https://github.com/eteran/cpp-utilities/blob/master/fixed/include/cpp-utilities/fixed.h 4// From: https://github.com/eteran/cpp-utilities/blob/master/fixed/include/cpp-utilities/fixed.h
5// See also: http://stackoverflow.com/questions/79677/whats-the-best-way-to-do-fixed-point-math 5// See also: http://stackoverflow.com/questions/79677/whats-the-best-way-to-do-fixed-point-math
6 6
7#ifndef FIXED_H_ 7#pragma once
8#define FIXED_H_
9
10#if __cplusplus >= 201402L
11#define CONSTEXPR14 constexpr
12#else
13#define CONSTEXPR14
14#endif
15 8
16#include <cstddef> // for size_t 9#include <cstddef> // for size_t
17#include <cstdint> 10#include <cstdint>
@@ -106,7 +99,7 @@ constexpr B next_to_base(N rhs) {
106struct divide_by_zero : std::exception {}; 99struct divide_by_zero : std::exception {};
107 100
108template <size_t I, size_t F> 101template <size_t I, size_t F>
109CONSTEXPR14 FixedPoint<I, F> divide( 102constexpr FixedPoint<I, F> divide(
110 FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder, 103 FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder,
111 typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { 104 typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
112 105
@@ -126,7 +119,7 @@ CONSTEXPR14 FixedPoint<I, F> divide(
126} 119}
127 120
128template <size_t I, size_t F> 121template <size_t I, size_t F>
129CONSTEXPR14 FixedPoint<I, F> divide( 122constexpr FixedPoint<I, F> divide(
130 FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder, 123 FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder,
131 typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { 124 typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
132 125
@@ -196,7 +189,7 @@ CONSTEXPR14 FixedPoint<I, F> divide(
196 189
197// this is the usual implementation of multiplication 190// this is the usual implementation of multiplication
198template <size_t I, size_t F> 191template <size_t I, size_t F>
199CONSTEXPR14 FixedPoint<I, F> multiply( 192constexpr FixedPoint<I, F> multiply(
200 FixedPoint<I, F> lhs, FixedPoint<I, F> rhs, 193 FixedPoint<I, F> lhs, FixedPoint<I, F> rhs,
201 typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { 194 typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
202 195
@@ -215,7 +208,7 @@ CONSTEXPR14 FixedPoint<I, F> multiply(
215// it is slightly slower, but is more robust since it doesn't 208// it is slightly slower, but is more robust since it doesn't
216// require and upgraded type 209// require and upgraded type
217template <size_t I, size_t F> 210template <size_t I, size_t F>
218CONSTEXPR14 FixedPoint<I, F> multiply( 211constexpr FixedPoint<I, F> multiply(
219 FixedPoint<I, F> lhs, FixedPoint<I, F> rhs, 212 FixedPoint<I, F> lhs, FixedPoint<I, F> rhs,
220 typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { 213 typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
221 214
@@ -284,7 +277,7 @@ public: // constructors
284 277
285public: // conversion 278public: // conversion
286 template <size_t I2, size_t F2> 279 template <size_t I2, size_t F2>
287 CONSTEXPR14 explicit FixedPoint(FixedPoint<I2, F2> other) { 280 constexpr explicit FixedPoint(FixedPoint<I2, F2> other) {
288 static_assert(I2 <= I && F2 <= F, "Scaling conversion can only upgrade types"); 281 static_assert(I2 <= I && F2 <= F, "Scaling conversion can only upgrade types");
289 using T = FixedPoint<I2, F2>; 282 using T = FixedPoint<I2, F2>;
290 283
@@ -353,81 +346,81 @@ public: // unary operators
353 return FixedPoint::from_base(+data_); 346 return FixedPoint::from_base(+data_);
354 } 347 }
355 348
356 CONSTEXPR14 FixedPoint& operator++() { 349 constexpr FixedPoint& operator++() {
357 data_ += one; 350 data_ += one;
358 return *this; 351 return *this;
359 } 352 }
360 353
361 CONSTEXPR14 FixedPoint& operator--() { 354 constexpr FixedPoint& operator--() {
362 data_ -= one; 355 data_ -= one;
363 return *this; 356 return *this;
364 } 357 }
365 358
366 CONSTEXPR14 FixedPoint operator++(int) { 359 constexpr FixedPoint operator++(int) {
367 FixedPoint tmp(*this); 360 FixedPoint tmp(*this);
368 data_ += one; 361 data_ += one;
369 return tmp; 362 return tmp;
370 } 363 }
371 364
372 CONSTEXPR14 FixedPoint operator--(int) { 365 constexpr FixedPoint operator--(int) {
373 FixedPoint tmp(*this); 366 FixedPoint tmp(*this);
374 data_ -= one; 367 data_ -= one;
375 return tmp; 368 return tmp;
376 } 369 }
377 370
378public: // basic math operators 371public: // basic math operators
379 CONSTEXPR14 FixedPoint& operator+=(FixedPoint n) { 372 constexpr FixedPoint& operator+=(FixedPoint n) {
380 data_ += n.data_; 373 data_ += n.data_;
381 return *this; 374 return *this;
382 } 375 }
383 376
384 CONSTEXPR14 FixedPoint& operator-=(FixedPoint n) { 377 constexpr FixedPoint& operator-=(FixedPoint n) {
385 data_ -= n.data_; 378 data_ -= n.data_;
386 return *this; 379 return *this;
387 } 380 }
388 381
389 CONSTEXPR14 FixedPoint& operator*=(FixedPoint n) { 382 constexpr FixedPoint& operator*=(FixedPoint n) {
390 return assign(detail::multiply(*this, n)); 383 return assign(detail::multiply(*this, n));
391 } 384 }
392 385
393 CONSTEXPR14 FixedPoint& operator/=(FixedPoint n) { 386 constexpr FixedPoint& operator/=(FixedPoint n) {
394 FixedPoint temp; 387 FixedPoint temp;
395 return assign(detail::divide(*this, n, temp)); 388 return assign(detail::divide(*this, n, temp));
396 } 389 }
397 390
398private: 391private:
399 CONSTEXPR14 FixedPoint& assign(FixedPoint rhs) { 392 constexpr FixedPoint& assign(FixedPoint rhs) {
400 data_ = rhs.data_; 393 data_ = rhs.data_;
401 return *this; 394 return *this;
402 } 395 }
403 396
404public: // binary math operators, effects underlying bit pattern since these 397public: // binary math operators, effects underlying bit pattern since these
405 // don't really typically make sense for non-integer values 398 // don't really typically make sense for non-integer values
406 CONSTEXPR14 FixedPoint& operator&=(FixedPoint n) { 399 constexpr FixedPoint& operator&=(FixedPoint n) {
407 data_ &= n.data_; 400 data_ &= n.data_;
408 return *this; 401 return *this;
409 } 402 }
410 403
411 CONSTEXPR14 FixedPoint& operator|=(FixedPoint n) { 404 constexpr FixedPoint& operator|=(FixedPoint n) {
412 data_ |= n.data_; 405 data_ |= n.data_;
413 return *this; 406 return *this;
414 } 407 }
415 408
416 CONSTEXPR14 FixedPoint& operator^=(FixedPoint n) { 409 constexpr FixedPoint& operator^=(FixedPoint n) {
417 data_ ^= n.data_; 410 data_ ^= n.data_;
418 return *this; 411 return *this;
419 } 412 }
420 413
421 template <class Integer, 414 template <class Integer,
422 class = typename std::enable_if<std::is_integral<Integer>::value>::type> 415 class = typename std::enable_if<std::is_integral<Integer>::value>::type>
423 CONSTEXPR14 FixedPoint& operator>>=(Integer n) { 416 constexpr FixedPoint& operator>>=(Integer n) {
424 data_ >>= n; 417 data_ >>= n;
425 return *this; 418 return *this;
426 } 419 }
427 420
428 template <class Integer, 421 template <class Integer,
429 class = typename std::enable_if<std::is_integral<Integer>::value>::type> 422 class = typename std::enable_if<std::is_integral<Integer>::value>::type>
430 CONSTEXPR14 FixedPoint& operator<<=(Integer n) { 423 constexpr FixedPoint& operator<<=(Integer n) {
431 data_ <<= n; 424 data_ <<= n;
432 return *this; 425 return *this;
433 } 426 }
@@ -485,7 +478,7 @@ public: // conversion to basic types
485 } 478 }
486 479
487public: 480public:
488 CONSTEXPR14 void swap(FixedPoint& rhs) { 481 constexpr void swap(FixedPoint& rhs) {
489 using std::swap; 482 using std::swap;
490 swap(data_, rhs.data_); 483 swap(data_, rhs.data_);
491 } 484 }
@@ -497,8 +490,8 @@ public:
497// if we have the same fractional portion, but differing integer portions, we trivially upgrade the 490// if we have the same fractional portion, but differing integer portions, we trivially upgrade the
498// smaller type 491// smaller type
499template <size_t I1, size_t I2, size_t F> 492template <size_t I1, size_t I2, size_t F>
500CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type 493constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator+(
501operator+(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { 494 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
502 495
503 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; 496 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
504 497
@@ -508,8 +501,8 @@ operator+(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
508} 501}
509 502
510template <size_t I1, size_t I2, size_t F> 503template <size_t I1, size_t I2, size_t F>
511CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type 504constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator-(
512operator-(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { 505 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
513 506
514 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; 507 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
515 508
@@ -519,8 +512,8 @@ operator-(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
519} 512}
520 513
521template <size_t I1, size_t I2, size_t F> 514template <size_t I1, size_t I2, size_t F>
522CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type 515constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator*(
523operator*(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { 516 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
524 517
525 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; 518 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
526 519
@@ -530,8 +523,8 @@ operator*(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
530} 523}
531 524
532template <size_t I1, size_t I2, size_t F> 525template <size_t I1, size_t I2, size_t F>
533CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type 526constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator/(
534operator/(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { 527 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
535 528
536 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; 529 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
537 530
@@ -548,75 +541,75 @@ std::ostream& operator<<(std::ostream& os, FixedPoint<I, F> f) {
548 541
549// basic math operators 542// basic math operators
550template <size_t I, size_t F> 543template <size_t I, size_t F>
551CONSTEXPR14 FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) { 544constexpr FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
552 lhs += rhs; 545 lhs += rhs;
553 return lhs; 546 return lhs;
554} 547}
555template <size_t I, size_t F> 548template <size_t I, size_t F>
556CONSTEXPR14 FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) { 549constexpr FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
557 lhs -= rhs; 550 lhs -= rhs;
558 return lhs; 551 return lhs;
559} 552}
560template <size_t I, size_t F> 553template <size_t I, size_t F>
561CONSTEXPR14 FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) { 554constexpr FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
562 lhs *= rhs; 555 lhs *= rhs;
563 return lhs; 556 return lhs;
564} 557}
565template <size_t I, size_t F> 558template <size_t I, size_t F>
566CONSTEXPR14 FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) { 559constexpr FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
567 lhs /= rhs; 560 lhs /= rhs;
568 return lhs; 561 return lhs;
569} 562}
570 563
571template <size_t I, size_t F, class Number, 564template <size_t I, size_t F, class Number,
572 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 565 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
573CONSTEXPR14 FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, Number rhs) { 566constexpr FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, Number rhs) {
574 lhs += FixedPoint<I, F>(rhs); 567 lhs += FixedPoint<I, F>(rhs);
575 return lhs; 568 return lhs;
576} 569}
577template <size_t I, size_t F, class Number, 570template <size_t I, size_t F, class Number,
578 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 571 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
579CONSTEXPR14 FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, Number rhs) { 572constexpr FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, Number rhs) {
580 lhs -= FixedPoint<I, F>(rhs); 573 lhs -= FixedPoint<I, F>(rhs);
581 return lhs; 574 return lhs;
582} 575}
583template <size_t I, size_t F, class Number, 576template <size_t I, size_t F, class Number,
584 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 577 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
585CONSTEXPR14 FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, Number rhs) { 578constexpr FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, Number rhs) {
586 lhs *= FixedPoint<I, F>(rhs); 579 lhs *= FixedPoint<I, F>(rhs);
587 return lhs; 580 return lhs;
588} 581}
589template <size_t I, size_t F, class Number, 582template <size_t I, size_t F, class Number,
590 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 583 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
591CONSTEXPR14 FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, Number rhs) { 584constexpr FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, Number rhs) {
592 lhs /= FixedPoint<I, F>(rhs); 585 lhs /= FixedPoint<I, F>(rhs);
593 return lhs; 586 return lhs;
594} 587}
595 588
596template <size_t I, size_t F, class Number, 589template <size_t I, size_t F, class Number,
597 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 590 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
598CONSTEXPR14 FixedPoint<I, F> operator+(Number lhs, FixedPoint<I, F> rhs) { 591constexpr FixedPoint<I, F> operator+(Number lhs, FixedPoint<I, F> rhs) {
599 FixedPoint<I, F> tmp(lhs); 592 FixedPoint<I, F> tmp(lhs);
600 tmp += rhs; 593 tmp += rhs;
601 return tmp; 594 return tmp;
602} 595}
603template <size_t I, size_t F, class Number, 596template <size_t I, size_t F, class Number,
604 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 597 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
605CONSTEXPR14 FixedPoint<I, F> operator-(Number lhs, FixedPoint<I, F> rhs) { 598constexpr FixedPoint<I, F> operator-(Number lhs, FixedPoint<I, F> rhs) {
606 FixedPoint<I, F> tmp(lhs); 599 FixedPoint<I, F> tmp(lhs);
607 tmp -= rhs; 600 tmp -= rhs;
608 return tmp; 601 return tmp;
609} 602}
610template <size_t I, size_t F, class Number, 603template <size_t I, size_t F, class Number,
611 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 604 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
612CONSTEXPR14 FixedPoint<I, F> operator*(Number lhs, FixedPoint<I, F> rhs) { 605constexpr FixedPoint<I, F> operator*(Number lhs, FixedPoint<I, F> rhs) {
613 FixedPoint<I, F> tmp(lhs); 606 FixedPoint<I, F> tmp(lhs);
614 tmp *= rhs; 607 tmp *= rhs;
615 return tmp; 608 return tmp;
616} 609}
617template <size_t I, size_t F, class Number, 610template <size_t I, size_t F, class Number,
618 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 611 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
619CONSTEXPR14 FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) { 612constexpr FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) {
620 FixedPoint<I, F> tmp(lhs); 613 FixedPoint<I, F> tmp(lhs);
621 tmp /= rhs; 614 tmp /= rhs;
622 return tmp; 615 return tmp;
@@ -625,13 +618,13 @@ CONSTEXPR14 FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) {
625// shift operators 618// shift operators
626template <size_t I, size_t F, class Integer, 619template <size_t I, size_t F, class Integer,
627 class = typename std::enable_if<std::is_integral<Integer>::value>::type> 620 class = typename std::enable_if<std::is_integral<Integer>::value>::type>
628CONSTEXPR14 FixedPoint<I, F> operator<<(FixedPoint<I, F> lhs, Integer rhs) { 621constexpr FixedPoint<I, F> operator<<(FixedPoint<I, F> lhs, Integer rhs) {
629 lhs <<= rhs; 622 lhs <<= rhs;
630 return lhs; 623 return lhs;
631} 624}
632template <size_t I, size_t F, class Integer, 625template <size_t I, size_t F, class Integer,
633 class = typename std::enable_if<std::is_integral<Integer>::value>::type> 626 class = typename std::enable_if<std::is_integral<Integer>::value>::type>
634CONSTEXPR14 FixedPoint<I, F> operator>>(FixedPoint<I, F> lhs, Integer rhs) { 627constexpr FixedPoint<I, F> operator>>(FixedPoint<I, F> lhs, Integer rhs) {
635 lhs >>= rhs; 628 lhs >>= rhs;
636 return lhs; 629 return lhs;
637} 630}
@@ -700,7 +693,3 @@ constexpr bool operator!=(Number lhs, FixedPoint<I, F> rhs) {
700} 693}
701 694
702} // namespace Common 695} // namespace Common
703
704#undef CONSTEXPR14
705
706#endif
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 95302c419..abeb5859b 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -261,8 +261,6 @@ add_library(core STATIC
261 hle/kernel/k_worker_task.h 261 hle/kernel/k_worker_task.h
262 hle/kernel/k_worker_task_manager.cpp 262 hle/kernel/k_worker_task_manager.cpp
263 hle/kernel/k_worker_task_manager.h 263 hle/kernel/k_worker_task_manager.h
264 hle/kernel/k_writable_event.cpp
265 hle/kernel/k_writable_event.h
266 hle/kernel/kernel.cpp 264 hle/kernel/kernel.cpp
267 hle/kernel/kernel.h 265 hle/kernel/kernel.h
268 hle/kernel/memory_types.h 266 hle/kernel/memory_types.h
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index 1d46f6d40..22b5d5656 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -111,6 +111,7 @@ public:
111 LOG_ERROR(Core_ARM, 111 LOG_ERROR(Core_ARM,
112 "Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc, 112 "Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc,
113 num_instructions, memory.Read32(pc)); 113 num_instructions, memory.Read32(pc));
114 ReturnException(pc, ARM_Interface::no_execute);
114 } 115 }
115 116
116 void InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op, 117 void InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op,
diff --git a/src/core/hid/irs_types.h b/src/core/hid/irs_types.h
index 88c5b016d..0d1bfe53f 100644
--- a/src/core/hid/irs_types.h
+++ b/src/core/hid/irs_types.h
@@ -14,7 +14,7 @@ enum class CameraAmbientNoiseLevel : u32 {
14 Low, 14 Low,
15 Medium, 15 Medium,
16 High, 16 High,
17 Unkown3, // This level can't be reached 17 Unknown3, // This level can't be reached
18}; 18};
19 19
20// This is nn::irsensor::CameraLightTarget 20// This is nn::irsensor::CameraLightTarget
@@ -75,9 +75,9 @@ enum class IrCameraStatus : u32 {
75enum class IrCameraInternalStatus : u32 { 75enum class IrCameraInternalStatus : u32 {
76 Stopped, 76 Stopped,
77 FirmwareUpdateNeeded, 77 FirmwareUpdateNeeded,
78 Unkown2, 78 Unknown2,
79 Unkown3, 79 Unknown3,
80 Unkown4, 80 Unknown4,
81 FirmwareVersionRequested, 81 FirmwareVersionRequested,
82 FirmwareVersionIsInvalid, 82 FirmwareVersionIsInvalid,
83 Ready, 83 Ready,
@@ -121,20 +121,20 @@ enum class IrSensorFunctionLevel : u8 {
121 121
122// This is nn::irsensor::MomentProcessorPreprocess 122// This is nn::irsensor::MomentProcessorPreprocess
123enum class MomentProcessorPreprocess : u32 { 123enum class MomentProcessorPreprocess : u32 {
124 Unkown0, 124 Unknown0,
125 Unkown1, 125 Unknown1,
126}; 126};
127 127
128// This is nn::irsensor::PackedMomentProcessorPreprocess 128// This is nn::irsensor::PackedMomentProcessorPreprocess
129enum class PackedMomentProcessorPreprocess : u8 { 129enum class PackedMomentProcessorPreprocess : u8 {
130 Unkown0, 130 Unknown0,
131 Unkown1, 131 Unknown1,
132}; 132};
133 133
134// This is nn::irsensor::PointingStatus 134// This is nn::irsensor::PointingStatus
135enum class PointingStatus : u32 { 135enum class PointingStatus : u32 {
136 Unkown0, 136 Unknown0,
137 Unkown1, 137 Unknown1,
138}; 138};
139 139
140struct IrsRect { 140struct IrsRect {
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index d631c0357..0cc26a211 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -152,7 +152,8 @@ public:
152 Kernel::LimitableResource::Sessions, 1); 152 Kernel::LimitableResource::Sessions, 1);
153 153
154 auto* session = Kernel::KSession::Create(kernel); 154 auto* session = Kernel::KSession::Create(kernel);
155 session->Initialize(nullptr, iface->GetServiceName()); 155 session->Initialize(nullptr, iface->GetServiceName(),
156 std::make_shared<Kernel::SessionRequestManager>(kernel));
156 157
157 context->AddMoveObject(&session->GetClientSession()); 158 context->AddMoveObject(&session->GetClientSession());
158 iface->ClientConnected(&session->GetServerSession()); 159 iface->ClientConnected(&session->GetServerSession());
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index 99265ce90..e258e2cdf 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -43,13 +43,13 @@ class Domain;
43class HLERequestContext; 43class HLERequestContext;
44class KAutoObject; 44class KAutoObject;
45class KernelCore; 45class KernelCore;
46class KEvent;
46class KHandleTable; 47class KHandleTable;
47class KProcess; 48class KProcess;
48class KServerSession; 49class KServerSession;
49class KThread; 50class KThread;
50class KReadableEvent; 51class KReadableEvent;
51class KSession; 52class KSession;
52class KWritableEvent;
53class ServiceThread; 53class ServiceThread;
54 54
55enum class ThreadWakeupReason; 55enum class ThreadWakeupReason;
diff --git a/src/core/hle/kernel/k_class_token.cpp b/src/core/hle/kernel/k_class_token.cpp
index cc2a0f7ca..10265c23c 100644
--- a/src/core/hle/kernel/k_class_token.cpp
+++ b/src/core/hle/kernel/k_class_token.cpp
@@ -18,7 +18,6 @@
18#include "core/hle/kernel/k_synchronization_object.h" 18#include "core/hle/kernel/k_synchronization_object.h"
19#include "core/hle/kernel/k_thread.h" 19#include "core/hle/kernel/k_thread.h"
20#include "core/hle/kernel/k_transfer_memory.h" 20#include "core/hle/kernel/k_transfer_memory.h"
21#include "core/hle/kernel/k_writable_event.h"
22 21
23namespace Kernel { 22namespace Kernel {
24 23
@@ -42,13 +41,12 @@ static_assert(ClassToken<KPort> == 0b10000101'00000000);
42static_assert(ClassToken<KSession> == 0b00011001'00000000); 41static_assert(ClassToken<KSession> == 0b00011001'00000000);
43static_assert(ClassToken<KSharedMemory> == 0b00101001'00000000); 42static_assert(ClassToken<KSharedMemory> == 0b00101001'00000000);
44static_assert(ClassToken<KEvent> == 0b01001001'00000000); 43static_assert(ClassToken<KEvent> == 0b01001001'00000000);
45static_assert(ClassToken<KWritableEvent> == 0b10001001'00000000);
46// static_assert(ClassToken<KLightClientSession> == 0b00110001'00000000); 44// static_assert(ClassToken<KLightClientSession> == 0b00110001'00000000);
47// static_assert(ClassToken<KLightServerSession> == 0b01010001'00000000); 45// static_assert(ClassToken<KLightServerSession> == 0b01010001'00000000);
48static_assert(ClassToken<KTransferMemory> == 0b10010001'00000000); 46static_assert(ClassToken<KTransferMemory> == 0b01010001'00000000);
49// static_assert(ClassToken<KDeviceAddressSpace> == 0b01100001'00000000); 47// static_assert(ClassToken<KDeviceAddressSpace> == 0b01100001'00000000);
50// static_assert(ClassToken<KSessionRequest> == 0b10100001'00000000); 48// static_assert(ClassToken<KSessionRequest> == 0b10100001'00000000);
51static_assert(ClassToken<KCodeMemory> == 0b11000001'00000000); 49static_assert(ClassToken<KCodeMemory> == 0b10100001'00000000);
52 50
53// Ensure that the token hierarchy is correct. 51// Ensure that the token hierarchy is correct.
54 52
@@ -73,13 +71,12 @@ static_assert(ClassToken<KPort> == ((0b10000101 << 8) | ClassToken<KAutoObject>)
73static_assert(ClassToken<KSession> == ((0b00011001 << 8) | ClassToken<KAutoObject>)); 71static_assert(ClassToken<KSession> == ((0b00011001 << 8) | ClassToken<KAutoObject>));
74static_assert(ClassToken<KSharedMemory> == ((0b00101001 << 8) | ClassToken<KAutoObject>)); 72static_assert(ClassToken<KSharedMemory> == ((0b00101001 << 8) | ClassToken<KAutoObject>));
75static_assert(ClassToken<KEvent> == ((0b01001001 << 8) | ClassToken<KAutoObject>)); 73static_assert(ClassToken<KEvent> == ((0b01001001 << 8) | ClassToken<KAutoObject>));
76static_assert(ClassToken<KWritableEvent> == ((0b10001001 << 8) | ClassToken<KAutoObject>));
77// static_assert(ClassToken<KLightClientSession> == ((0b00110001 << 8) | ClassToken<KAutoObject>)); 74// static_assert(ClassToken<KLightClientSession> == ((0b00110001 << 8) | ClassToken<KAutoObject>));
78// static_assert(ClassToken<KLightServerSession> == ((0b01010001 << 8) | ClassToken<KAutoObject>)); 75// static_assert(ClassToken<KLightServerSession> == ((0b01010001 << 8) | ClassToken<KAutoObject>));
79static_assert(ClassToken<KTransferMemory> == ((0b10010001 << 8) | ClassToken<KAutoObject>)); 76static_assert(ClassToken<KTransferMemory> == ((0b01010001 << 8) | ClassToken<KAutoObject>));
80// static_assert(ClassToken<KDeviceAddressSpace> == ((0b01100001 << 8) | ClassToken<KAutoObject>)); 77// static_assert(ClassToken<KDeviceAddressSpace> == ((0b01100001 << 8) | ClassToken<KAutoObject>));
81// static_assert(ClassToken<KSessionRequest> == ((0b10100001 << 8) | ClassToken<KAutoObject>)); 78// static_assert(ClassToken<KSessionRequest> == ((0b10100001 << 8) | ClassToken<KAutoObject>));
82static_assert(ClassToken<KCodeMemory> == ((0b11000001 << 8) | ClassToken<KAutoObject>)); 79static_assert(ClassToken<KCodeMemory> == ((0b10100001 << 8) | ClassToken<KAutoObject>));
83 80
84// Ensure that the token hierarchy reflects the class hierarchy. 81// Ensure that the token hierarchy reflects the class hierarchy.
85 82
@@ -110,7 +107,6 @@ static_assert(std::is_final_v<KPort> && std::is_base_of_v<KAutoObject, KPort>);
110static_assert(std::is_final_v<KSession> && std::is_base_of_v<KAutoObject, KSession>); 107static_assert(std::is_final_v<KSession> && std::is_base_of_v<KAutoObject, KSession>);
111static_assert(std::is_final_v<KSharedMemory> && std::is_base_of_v<KAutoObject, KSharedMemory>); 108static_assert(std::is_final_v<KSharedMemory> && std::is_base_of_v<KAutoObject, KSharedMemory>);
112static_assert(std::is_final_v<KEvent> && std::is_base_of_v<KAutoObject, KEvent>); 109static_assert(std::is_final_v<KEvent> && std::is_base_of_v<KAutoObject, KEvent>);
113static_assert(std::is_final_v<KWritableEvent> && std::is_base_of_v<KAutoObject, KWritableEvent>);
114// static_assert(std::is_final_v<KLightClientSession> && 110// static_assert(std::is_final_v<KLightClientSession> &&
115// std::is_base_of_v<KAutoObject, KLightClientSession>); 111// std::is_base_of_v<KAutoObject, KLightClientSession>);
116// static_assert(std::is_final_v<KLightServerSession> && 112// static_assert(std::is_final_v<KLightServerSession> &&
diff --git a/src/core/hle/kernel/k_class_token.h b/src/core/hle/kernel/k_class_token.h
index c9001ae3d..ab20e00ff 100644
--- a/src/core/hle/kernel/k_class_token.h
+++ b/src/core/hle/kernel/k_class_token.h
@@ -101,7 +101,6 @@ public:
101 KSession, 101 KSession,
102 KSharedMemory, 102 KSharedMemory,
103 KEvent, 103 KEvent,
104 KWritableEvent,
105 KLightClientSession, 104 KLightClientSession,
106 KLightServerSession, 105 KLightServerSession,
107 KTransferMemory, 106 KTransferMemory,
diff --git a/src/core/hle/kernel/k_client_session.cpp b/src/core/hle/kernel/k_client_session.cpp
index b2a887b14..8892c5b7c 100644
--- a/src/core/hle/kernel/k_client_session.cpp
+++ b/src/core/hle/kernel/k_client_session.cpp
@@ -21,10 +21,9 @@ void KClientSession::Destroy() {
21 21
22void KClientSession::OnServerClosed() {} 22void KClientSession::OnServerClosed() {}
23 23
24Result KClientSession::SendSyncRequest(KThread* thread, Core::Memory::Memory& memory, 24Result KClientSession::SendSyncRequest() {
25 Core::Timing::CoreTiming& core_timing) {
26 // Signal the server session that new data is available 25 // Signal the server session that new data is available
27 return parent->GetServerSession().HandleSyncRequest(thread, memory, core_timing); 26 return parent->GetServerSession().OnRequest();
28} 27}
29 28
30} // namespace Kernel 29} // namespace Kernel
diff --git a/src/core/hle/kernel/k_client_session.h b/src/core/hle/kernel/k_client_session.h
index 0c750d756..b4a19c546 100644
--- a/src/core/hle/kernel/k_client_session.h
+++ b/src/core/hle/kernel/k_client_session.h
@@ -46,8 +46,7 @@ public:
46 return parent; 46 return parent;
47 } 47 }
48 48
49 Result SendSyncRequest(KThread* thread, Core::Memory::Memory& memory, 49 Result SendSyncRequest();
50 Core::Timing::CoreTiming& core_timing);
51 50
52 void OnServerClosed(); 51 void OnServerClosed();
53 52
diff --git a/src/core/hle/kernel/k_event.cpp b/src/core/hle/kernel/k_event.cpp
index e52fafbc7..78ca59463 100644
--- a/src/core/hle/kernel/k_event.cpp
+++ b/src/core/hle/kernel/k_event.cpp
@@ -8,39 +8,45 @@
8namespace Kernel { 8namespace Kernel {
9 9
10KEvent::KEvent(KernelCore& kernel_) 10KEvent::KEvent(KernelCore& kernel_)
11 : KAutoObjectWithSlabHeapAndContainer{kernel_}, readable_event{kernel_}, writable_event{ 11 : KAutoObjectWithSlabHeapAndContainer{kernel_}, m_readable_event{kernel_} {}
12 kernel_} {}
13 12
14KEvent::~KEvent() = default; 13KEvent::~KEvent() = default;
15 14
16void KEvent::Initialize(std::string&& name_, KProcess* owner_) { 15void KEvent::Initialize(KProcess* owner) {
17 // Increment reference count. 16 // Create our readable event.
18 // Because reference count is one on creation, this will result 17 KAutoObject::Create(std::addressof(m_readable_event));
19 // in a reference count of two. Thus, when both readable and
20 // writable events are closed this object will be destroyed.
21 Open();
22 18
23 // Create our sub events. 19 // Initialize our readable event.
24 KAutoObject::Create(std::addressof(readable_event)); 20 m_readable_event.Initialize(this);
25 KAutoObject::Create(std::addressof(writable_event));
26
27 // Initialize our sub sessions.
28 readable_event.Initialize(this, name_ + ":Readable");
29 writable_event.Initialize(this, name_ + ":Writable");
30 21
31 // Set our owner process. 22 // Set our owner process.
32 owner = owner_; 23 m_owner = owner;
33 owner->Open(); 24 m_owner->Open();
34 25
35 // Mark initialized. 26 // Mark initialized.
36 name = std::move(name_); 27 m_initialized = true;
37 initialized = true;
38} 28}
39 29
40void KEvent::Finalize() { 30void KEvent::Finalize() {
41 KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList>::Finalize(); 31 KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList>::Finalize();
42} 32}
43 33
34Result KEvent::Signal() {
35 KScopedSchedulerLock sl{kernel};
36
37 R_SUCCEED_IF(m_readable_event_destroyed);
38
39 return m_readable_event.Signal();
40}
41
42Result KEvent::Clear() {
43 KScopedSchedulerLock sl{kernel};
44
45 R_SUCCEED_IF(m_readable_event_destroyed);
46
47 return m_readable_event.Clear();
48}
49
44void KEvent::PostDestroy(uintptr_t arg) { 50void KEvent::PostDestroy(uintptr_t arg) {
45 // Release the event count resource the owner process holds. 51 // Release the event count resource the owner process holds.
46 KProcess* owner = reinterpret_cast<KProcess*>(arg); 52 KProcess* owner = reinterpret_cast<KProcess*>(arg);
diff --git a/src/core/hle/kernel/k_event.h b/src/core/hle/kernel/k_event.h
index 2ff828feb..48ce7d9a0 100644
--- a/src/core/hle/kernel/k_event.h
+++ b/src/core/hle/kernel/k_event.h
@@ -4,14 +4,12 @@
4#pragma once 4#pragma once
5 5
6#include "core/hle/kernel/k_readable_event.h" 6#include "core/hle/kernel/k_readable_event.h"
7#include "core/hle/kernel/k_writable_event.h"
8#include "core/hle/kernel/slab_helpers.h" 7#include "core/hle/kernel/slab_helpers.h"
9 8
10namespace Kernel { 9namespace Kernel {
11 10
12class KernelCore; 11class KernelCore;
13class KReadableEvent; 12class KReadableEvent;
14class KWritableEvent;
15class KProcess; 13class KProcess;
16 14
17class KEvent final : public KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList> { 15class KEvent final : public KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList> {
@@ -21,37 +19,40 @@ public:
21 explicit KEvent(KernelCore& kernel_); 19 explicit KEvent(KernelCore& kernel_);
22 ~KEvent() override; 20 ~KEvent() override;
23 21
24 void Initialize(std::string&& name, KProcess* owner_); 22 void Initialize(KProcess* owner);
25 23
26 void Finalize() override; 24 void Finalize() override;
27 25
28 bool IsInitialized() const override { 26 bool IsInitialized() const override {
29 return initialized; 27 return m_initialized;
30 } 28 }
31 29
32 uintptr_t GetPostDestroyArgument() const override { 30 uintptr_t GetPostDestroyArgument() const override {
33 return reinterpret_cast<uintptr_t>(owner); 31 return reinterpret_cast<uintptr_t>(m_owner);
34 } 32 }
35 33
36 KProcess* GetOwner() const override { 34 KProcess* GetOwner() const override {
37 return owner; 35 return m_owner;
38 } 36 }
39 37
40 KReadableEvent& GetReadableEvent() { 38 KReadableEvent& GetReadableEvent() {
41 return readable_event; 39 return m_readable_event;
42 }
43
44 KWritableEvent& GetWritableEvent() {
45 return writable_event;
46 } 40 }
47 41
48 static void PostDestroy(uintptr_t arg); 42 static void PostDestroy(uintptr_t arg);
49 43
44 Result Signal();
45 Result Clear();
46
47 void OnReadableEventDestroyed() {
48 m_readable_event_destroyed = true;
49 }
50
50private: 51private:
51 KReadableEvent readable_event; 52 KReadableEvent m_readable_event;
52 KWritableEvent writable_event; 53 KProcess* m_owner{};
53 KProcess* owner{}; 54 bool m_initialized{};
54 bool initialized{}; 55 bool m_readable_event_destroyed{};
55}; 56};
56 57
57} // namespace Kernel 58} // namespace Kernel
diff --git a/src/core/hle/kernel/k_readable_event.cpp b/src/core/hle/kernel/k_readable_event.cpp
index 94c5464fe..5c942d47c 100644
--- a/src/core/hle/kernel/k_readable_event.cpp
+++ b/src/core/hle/kernel/k_readable_event.cpp
@@ -15,31 +15,44 @@ KReadableEvent::KReadableEvent(KernelCore& kernel_) : KSynchronizationObject{ker
15 15
16KReadableEvent::~KReadableEvent() = default; 16KReadableEvent::~KReadableEvent() = default;
17 17
18void KReadableEvent::Initialize(KEvent* parent) {
19 m_is_signaled = false;
20 m_parent = parent;
21
22 if (m_parent != nullptr) {
23 m_parent->Open();
24 }
25}
26
18bool KReadableEvent::IsSignaled() const { 27bool KReadableEvent::IsSignaled() const {
19 ASSERT(kernel.GlobalSchedulerContext().IsLocked()); 28 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
20 29
21 return is_signaled; 30 return m_is_signaled;
22} 31}
23 32
24void KReadableEvent::Destroy() { 33void KReadableEvent::Destroy() {
25 if (parent) { 34 if (m_parent) {
26 parent->Close(); 35 {
36 KScopedSchedulerLock sl{kernel};
37 m_parent->OnReadableEventDestroyed();
38 }
39 m_parent->Close();
27 } 40 }
28} 41}
29 42
30Result KReadableEvent::Signal() { 43Result KReadableEvent::Signal() {
31 KScopedSchedulerLock lk{kernel}; 44 KScopedSchedulerLock lk{kernel};
32 45
33 if (!is_signaled) { 46 if (!m_is_signaled) {
34 is_signaled = true; 47 m_is_signaled = true;
35 NotifyAvailable(); 48 this->NotifyAvailable();
36 } 49 }
37 50
38 return ResultSuccess; 51 return ResultSuccess;
39} 52}
40 53
41Result KReadableEvent::Clear() { 54Result KReadableEvent::Clear() {
42 Reset(); 55 this->Reset();
43 56
44 return ResultSuccess; 57 return ResultSuccess;
45} 58}
@@ -47,11 +60,11 @@ Result KReadableEvent::Clear() {
47Result KReadableEvent::Reset() { 60Result KReadableEvent::Reset() {
48 KScopedSchedulerLock lk{kernel}; 61 KScopedSchedulerLock lk{kernel};
49 62
50 if (!is_signaled) { 63 if (!m_is_signaled) {
51 return ResultInvalidState; 64 return ResultInvalidState;
52 } 65 }
53 66
54 is_signaled = false; 67 m_is_signaled = false;
55 return ResultSuccess; 68 return ResultSuccess;
56} 69}
57 70
diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h
index 18dcad289..743f96bf5 100644
--- a/src/core/hle/kernel/k_readable_event.h
+++ b/src/core/hle/kernel/k_readable_event.h
@@ -20,26 +20,23 @@ public:
20 explicit KReadableEvent(KernelCore& kernel_); 20 explicit KReadableEvent(KernelCore& kernel_);
21 ~KReadableEvent() override; 21 ~KReadableEvent() override;
22 22
23 void Initialize(KEvent* parent_event_, std::string&& name_) { 23 void Initialize(KEvent* parent);
24 is_signaled = false;
25 parent = parent_event_;
26 name = std::move(name_);
27 }
28 24
29 KEvent* GetParent() const { 25 KEvent* GetParent() const {
30 return parent; 26 return m_parent;
31 } 27 }
32 28
29 Result Signal();
30 Result Clear();
31
33 bool IsSignaled() const override; 32 bool IsSignaled() const override;
34 void Destroy() override; 33 void Destroy() override;
35 34
36 Result Signal();
37 Result Clear();
38 Result Reset(); 35 Result Reset();
39 36
40private: 37private:
41 bool is_signaled{}; 38 bool m_is_signaled{};
42 KEvent* parent{}; 39 KEvent* m_parent{};
43}; 40};
44 41
45} // namespace Kernel 42} // namespace Kernel
diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp
index 802c646a6..4252c9adb 100644
--- a/src/core/hle/kernel/k_server_session.cpp
+++ b/src/core/hle/kernel/k_server_session.cpp
@@ -7,6 +7,8 @@
7#include "common/assert.h" 7#include "common/assert.h"
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "common/scope_exit.h"
11#include "core/core.h"
10#include "core/core_timing.h" 12#include "core/core_timing.h"
11#include "core/hle/ipc_helpers.h" 13#include "core/hle/ipc_helpers.h"
12#include "core/hle/kernel/hle_ipc.h" 14#include "core/hle/kernel/hle_ipc.h"
@@ -18,13 +20,19 @@
18#include "core/hle/kernel/k_server_session.h" 20#include "core/hle/kernel/k_server_session.h"
19#include "core/hle/kernel/k_session.h" 21#include "core/hle/kernel/k_session.h"
20#include "core/hle/kernel/k_thread.h" 22#include "core/hle/kernel/k_thread.h"
23#include "core/hle/kernel/k_thread_queue.h"
21#include "core/hle/kernel/kernel.h" 24#include "core/hle/kernel/kernel.h"
22#include "core/hle/kernel/service_thread.h" 25#include "core/hle/kernel/service_thread.h"
23#include "core/memory.h" 26#include "core/memory.h"
24 27
25namespace Kernel { 28namespace Kernel {
26 29
27KServerSession::KServerSession(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} 30using ThreadQueueImplForKServerSessionRequest = KThreadQueue;
31
32static constexpr u32 MessageBufferSize = 0x100;
33
34KServerSession::KServerSession(KernelCore& kernel_)
35 : KSynchronizationObject{kernel_}, m_lock{kernel_} {}
28 36
29KServerSession::~KServerSession() = default; 37KServerSession::~KServerSession() = default;
30 38
@@ -33,17 +41,14 @@ void KServerSession::Initialize(KSession* parent_session_, std::string&& name_,
33 // Set member variables. 41 // Set member variables.
34 parent = parent_session_; 42 parent = parent_session_;
35 name = std::move(name_); 43 name = std::move(name_);
36 44 manager = manager_;
37 if (manager_) {
38 manager = manager_;
39 } else {
40 manager = std::make_shared<SessionRequestManager>(kernel);
41 }
42} 45}
43 46
44void KServerSession::Destroy() { 47void KServerSession::Destroy() {
45 parent->OnServerClosed(); 48 parent->OnServerClosed();
46 49
50 this->CleanupRequests();
51
47 parent->Close(); 52 parent->Close();
48 53
49 // Release host emulation members. 54 // Release host emulation members.
@@ -54,13 +59,13 @@ void KServerSession::Destroy() {
54} 59}
55 60
56void KServerSession::OnClientClosed() { 61void KServerSession::OnClientClosed() {
57 if (manager->HasSessionHandler()) { 62 if (manager && manager->HasSessionHandler()) {
58 manager->SessionHandler().ClientDisconnected(this); 63 manager->SessionHandler().ClientDisconnected(this);
59 } 64 }
60} 65}
61 66
62bool KServerSession::IsSignaled() const { 67bool KServerSession::IsSignaled() const {
63 ASSERT(kernel.GlobalSchedulerContext().IsLocked()); 68 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
64 69
65 // If the client is closed, we're always signaled. 70 // If the client is closed, we're always signaled.
66 if (parent->IsClientClosed()) { 71 if (parent->IsClientClosed()) {
@@ -68,7 +73,7 @@ bool KServerSession::IsSignaled() const {
68 } 73 }
69 74
70 // Otherwise, we're signaled if we have a request and aren't handling one. 75 // Otherwise, we're signaled if we have a request and aren't handling one.
71 return false; 76 return !m_thread_request_list.empty() && m_current_thread_request == nullptr;
72} 77}
73 78
74void KServerSession::AppendDomainHandler(SessionRequestHandlerPtr handler) { 79void KServerSession::AppendDomainHandler(SessionRequestHandlerPtr handler) {
@@ -173,9 +178,221 @@ Result KServerSession::CompleteSyncRequest(HLERequestContext& context) {
173 return result; 178 return result;
174} 179}
175 180
176Result KServerSession::HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory, 181Result KServerSession::OnRequest() {
177 Core::Timing::CoreTiming& core_timing) { 182 // Create the wait queue.
178 return QueueSyncRequest(thread, memory); 183 ThreadQueueImplForKServerSessionRequest wait_queue{kernel};
184
185 {
186 // Lock the scheduler.
187 KScopedSchedulerLock sl{kernel};
188
189 // Ensure that we can handle new requests.
190 R_UNLESS(!parent->IsServerClosed(), ResultSessionClosed);
191
192 // Check that we're not terminating.
193 R_UNLESS(!GetCurrentThread(kernel).IsTerminationRequested(), ResultTerminationRequested);
194
195 if (manager) {
196 // HLE request.
197 auto& memory{kernel.System().Memory()};
198 this->QueueSyncRequest(GetCurrentThreadPointer(kernel), memory);
199 } else {
200 // Non-HLE request.
201 auto* thread{GetCurrentThreadPointer(kernel)};
202
203 // Get whether we're empty.
204 const bool was_empty = m_thread_request_list.empty();
205
206 // Add the thread to the list.
207 thread->Open();
208 m_thread_request_list.push_back(thread);
209
210 // If we were empty, signal.
211 if (was_empty) {
212 this->NotifyAvailable();
213 }
214 }
215
216 // This is a synchronous request, so we should wait for our request to complete.
217 GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC);
218 GetCurrentThread(kernel).BeginWait(&wait_queue);
219 }
220
221 return GetCurrentThread(kernel).GetWaitResult();
222}
223
224Result KServerSession::SendReply() {
225 // Lock the session.
226 KScopedLightLock lk(m_lock);
227
228 // Get the request.
229 KThread* client_thread;
230 {
231 KScopedSchedulerLock sl{kernel};
232
233 // Get the current request.
234 client_thread = m_current_thread_request;
235 R_UNLESS(client_thread != nullptr, ResultInvalidState);
236
237 // Clear the current request, since we're processing it.
238 m_current_thread_request = nullptr;
239 if (!m_thread_request_list.empty()) {
240 this->NotifyAvailable();
241 }
242 }
243
244 // Close reference to the request once we're done processing it.
245 SCOPE_EXIT({ client_thread->Close(); });
246
247 // Extract relevant information from the request.
248 // const uintptr_t client_message = request->GetAddress();
249 // const size_t client_buffer_size = request->GetSize();
250 // KThread *client_thread = request->GetThread();
251 // KEvent *event = request->GetEvent();
252
253 // Check whether we're closed.
254 const bool closed = (client_thread == nullptr || parent->IsClientClosed());
255
256 Result result = ResultSuccess;
257 if (!closed) {
258 // If we're not closed, send the reply.
259 Core::Memory::Memory& memory{kernel.System().Memory()};
260 KThread* server_thread{GetCurrentThreadPointer(kernel)};
261 UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess());
262
263 auto* src_msg_buffer = memory.GetPointer(server_thread->GetTLSAddress());
264 auto* dst_msg_buffer = memory.GetPointer(client_thread->GetTLSAddress());
265 std::memcpy(dst_msg_buffer, src_msg_buffer, MessageBufferSize);
266 } else {
267 result = ResultSessionClosed;
268 }
269
270 // Select a result for the client.
271 Result client_result = result;
272 if (closed && R_SUCCEEDED(result)) {
273 result = ResultSessionClosed;
274 client_result = ResultSessionClosed;
275 } else {
276 result = ResultSuccess;
277 }
278
279 // If there's a client thread, update it.
280 if (client_thread != nullptr) {
281 // End the client thread's wait.
282 KScopedSchedulerLock sl{kernel};
283
284 if (!client_thread->IsTerminationRequested()) {
285 client_thread->EndWait(client_result);
286 }
287 }
288
289 return result;
290}
291
292Result KServerSession::ReceiveRequest() {
293 // Lock the session.
294 KScopedLightLock lk(m_lock);
295
296 // Get the request and client thread.
297 // KSessionRequest *request;
298 KThread* client_thread;
299
300 {
301 KScopedSchedulerLock sl{kernel};
302
303 // Ensure that we can service the request.
304 R_UNLESS(!parent->IsClientClosed(), ResultSessionClosed);
305
306 // Ensure we aren't already servicing a request.
307 R_UNLESS(m_current_thread_request == nullptr, ResultNotFound);
308
309 // Ensure we have a request to service.
310 R_UNLESS(!m_thread_request_list.empty(), ResultNotFound);
311
312 // Pop the first request from the list.
313 client_thread = m_thread_request_list.front();
314 m_thread_request_list.pop_front();
315
316 // Get the thread for the request.
317 R_UNLESS(client_thread != nullptr, ResultSessionClosed);
318
319 // Open the client thread.
320 client_thread->Open();
321 }
322
323 // SCOPE_EXIT({ client_thread->Close(); });
324
325 // Set the request as our current.
326 m_current_thread_request = client_thread;
327
328 // Receive the message.
329 Core::Memory::Memory& memory{kernel.System().Memory()};
330 KThread* server_thread{GetCurrentThreadPointer(kernel)};
331 UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess());
332
333 auto* src_msg_buffer = memory.GetPointer(client_thread->GetTLSAddress());
334 auto* dst_msg_buffer = memory.GetPointer(server_thread->GetTLSAddress());
335 std::memcpy(dst_msg_buffer, src_msg_buffer, MessageBufferSize);
336
337 // We succeeded.
338 return ResultSuccess;
339}
340
341void KServerSession::CleanupRequests() {
342 KScopedLightLock lk(m_lock);
343
344 // Clean up any pending requests.
345 while (true) {
346 // Get the next request.
347 // KSessionRequest *request = nullptr;
348 KThread* client_thread = nullptr;
349 {
350 KScopedSchedulerLock sl{kernel};
351
352 if (m_current_thread_request) {
353 // Choose the current request if we have one.
354 client_thread = m_current_thread_request;
355 m_current_thread_request = nullptr;
356 } else if (!m_thread_request_list.empty()) {
357 // Pop the request from the front of the list.
358 client_thread = m_thread_request_list.front();
359 m_thread_request_list.pop_front();
360 }
361 }
362
363 // If there's no request, we're done.
364 if (client_thread == nullptr) {
365 break;
366 }
367
368 // Close a reference to the request once it's cleaned up.
369 SCOPE_EXIT({ client_thread->Close(); });
370
371 // Extract relevant information from the request.
372 // const uintptr_t client_message = request->GetAddress();
373 // const size_t client_buffer_size = request->GetSize();
374 // KThread *client_thread = request->GetThread();
375 // KEvent *event = request->GetEvent();
376
377 // KProcess *server_process = request->GetServerProcess();
378 // KProcess *client_process = (client_thread != nullptr) ?
379 // client_thread->GetOwnerProcess() : nullptr;
380 // KProcessPageTable *client_page_table = (client_process != nullptr) ?
381 // &client_process->GetPageTable() : nullptr;
382
383 // Cleanup the mappings.
384 // Result result = CleanupMap(request, server_process, client_page_table);
385
386 // If there's a client thread, update it.
387 if (client_thread != nullptr) {
388 // End the client thread's wait.
389 KScopedSchedulerLock sl{kernel};
390
391 if (!client_thread->IsTerminationRequested()) {
392 client_thread->EndWait(ResultSessionClosed);
393 }
394 }
395 }
179} 396}
180 397
181} // namespace Kernel 398} // namespace Kernel
diff --git a/src/core/hle/kernel/k_server_session.h b/src/core/hle/kernel/k_server_session.h
index 6d0821945..748d52826 100644
--- a/src/core/hle/kernel/k_server_session.h
+++ b/src/core/hle/kernel/k_server_session.h
@@ -3,6 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <list>
6#include <memory> 7#include <memory>
7#include <string> 8#include <string>
8#include <utility> 9#include <utility>
@@ -10,6 +11,7 @@
10#include <boost/intrusive/list.hpp> 11#include <boost/intrusive/list.hpp>
11 12
12#include "core/hle/kernel/hle_ipc.h" 13#include "core/hle/kernel/hle_ipc.h"
14#include "core/hle/kernel/k_light_lock.h"
13#include "core/hle/kernel/k_synchronization_object.h" 15#include "core/hle/kernel/k_synchronization_object.h"
14#include "core/hle/result.h" 16#include "core/hle/result.h"
15 17
@@ -59,25 +61,15 @@ public:
59 void OnClientClosed(); 61 void OnClientClosed();
60 62
61 void ClientConnected(SessionRequestHandlerPtr handler) { 63 void ClientConnected(SessionRequestHandlerPtr handler) {
62 manager->SetSessionHandler(std::move(handler)); 64 if (manager) {
65 manager->SetSessionHandler(std::move(handler));
66 }
63 } 67 }
64 68
65 void ClientDisconnected() { 69 void ClientDisconnected() {
66 manager = nullptr; 70 manager = nullptr;
67 } 71 }
68 72
69 /**
70 * Handle a sync request from the emulated application.
71 *
72 * @param thread Thread that initiated the request.
73 * @param memory Memory context to handle the sync request under.
74 * @param core_timing Core timing context to schedule the request event under.
75 *
76 * @returns Result from the operation.
77 */
78 Result HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory,
79 Core::Timing::CoreTiming& core_timing);
80
81 /// Adds a new domain request handler to the collection of request handlers within 73 /// Adds a new domain request handler to the collection of request handlers within
82 /// this ServerSession instance. 74 /// this ServerSession instance.
83 void AppendDomainHandler(SessionRequestHandlerPtr handler); 75 void AppendDomainHandler(SessionRequestHandlerPtr handler);
@@ -88,7 +80,7 @@ public:
88 80
89 /// Returns true if the session has been converted to a domain, otherwise False 81 /// Returns true if the session has been converted to a domain, otherwise False
90 bool IsDomain() const { 82 bool IsDomain() const {
91 return manager->IsDomain(); 83 return manager && manager->IsDomain();
92 } 84 }
93 85
94 /// Converts the session to a domain at the end of the current command 86 /// Converts the session to a domain at the end of the current command
@@ -101,7 +93,15 @@ public:
101 return manager; 93 return manager;
102 } 94 }
103 95
96 /// TODO: flesh these out to match the real kernel
97 Result OnRequest();
98 Result SendReply();
99 Result ReceiveRequest();
100
104private: 101private:
102 /// Frees up waiting client sessions when this server session is about to die
103 void CleanupRequests();
104
105 /// Queues a sync request from the emulated application. 105 /// Queues a sync request from the emulated application.
106 Result QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory); 106 Result QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory);
107 107
@@ -112,7 +112,7 @@ private:
112 /// object handle. 112 /// object handle.
113 Result HandleDomainSyncRequest(Kernel::HLERequestContext& context); 113 Result HandleDomainSyncRequest(Kernel::HLERequestContext& context);
114 114
115 /// This session's HLE request handlers 115 /// This session's HLE request handlers; if nullptr, this is not an HLE server
116 std::shared_ptr<SessionRequestManager> manager; 116 std::shared_ptr<SessionRequestManager> manager;
117 117
118 /// When set to True, converts the session to a domain at the end of the command 118 /// When set to True, converts the session to a domain at the end of the command
@@ -120,6 +120,13 @@ private:
120 120
121 /// KSession that owns this KServerSession 121 /// KSession that owns this KServerSession
122 KSession* parent{}; 122 KSession* parent{};
123
124 /// List of threads which are pending a reply.
125 /// FIXME: KSessionRequest
126 std::list<KThread*> m_thread_request_list;
127 KThread* m_current_thread_request{};
128
129 KLightLock m_lock;
123}; 130};
124 131
125} // namespace Kernel 132} // namespace Kernel
diff --git a/src/core/hle/kernel/k_writable_event.cpp b/src/core/hle/kernel/k_writable_event.cpp
deleted file mode 100644
index ff88c5acd..000000000
--- a/src/core/hle/kernel/k_writable_event.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/kernel/k_event.h"
5#include "core/hle/kernel/k_readable_event.h"
6#include "core/hle/kernel/k_writable_event.h"
7
8namespace Kernel {
9
10KWritableEvent::KWritableEvent(KernelCore& kernel_)
11 : KAutoObjectWithSlabHeapAndContainer{kernel_} {}
12
13KWritableEvent::~KWritableEvent() = default;
14
15void KWritableEvent::Initialize(KEvent* parent_event_, std::string&& name_) {
16 parent = parent_event_;
17 name = std::move(name_);
18 parent->GetReadableEvent().Open();
19}
20
21Result KWritableEvent::Signal() {
22 return parent->GetReadableEvent().Signal();
23}
24
25Result KWritableEvent::Clear() {
26 return parent->GetReadableEvent().Clear();
27}
28
29void KWritableEvent::Destroy() {
30 // Close our references.
31 parent->GetReadableEvent().Close();
32 parent->Close();
33}
34
35} // namespace Kernel
diff --git a/src/core/hle/kernel/k_writable_event.h b/src/core/hle/kernel/k_writable_event.h
deleted file mode 100644
index 3fd0c7d0a..000000000
--- a/src/core/hle/kernel/k_writable_event.h
+++ /dev/null
@@ -1,39 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/kernel/k_auto_object.h"
7#include "core/hle/kernel/slab_helpers.h"
8#include "core/hle/result.h"
9
10namespace Kernel {
11
12class KernelCore;
13class KEvent;
14
15class KWritableEvent final
16 : public KAutoObjectWithSlabHeapAndContainer<KWritableEvent, KAutoObjectWithList> {
17 KERNEL_AUTOOBJECT_TRAITS(KWritableEvent, KAutoObject);
18
19public:
20 explicit KWritableEvent(KernelCore& kernel_);
21 ~KWritableEvent() override;
22
23 void Destroy() override;
24
25 static void PostDestroy([[maybe_unused]] uintptr_t arg) {}
26
27 void Initialize(KEvent* parent_, std::string&& name_);
28 Result Signal();
29 Result Clear();
30
31 KEvent* GetParent() const {
32 return parent;
33 }
34
35private:
36 KEvent* parent{};
37};
38
39} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index bcf016a97..0847cbcbf 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -52,7 +52,6 @@ class KThread;
52class KThreadLocalPage; 52class KThreadLocalPage;
53class KTransferMemory; 53class KTransferMemory;
54class KWorkerTaskManager; 54class KWorkerTaskManager;
55class KWritableEvent;
56class KCodeMemory; 55class KCodeMemory;
57class PhysicalCore; 56class PhysicalCore;
58class ServiceThread; 57class ServiceThread;
@@ -345,8 +344,6 @@ public:
345 return slab_heap_container->thread; 344 return slab_heap_container->thread;
346 } else if constexpr (std::is_same_v<T, KTransferMemory>) { 345 } else if constexpr (std::is_same_v<T, KTransferMemory>) {
347 return slab_heap_container->transfer_memory; 346 return slab_heap_container->transfer_memory;
348 } else if constexpr (std::is_same_v<T, KWritableEvent>) {
349 return slab_heap_container->writeable_event;
350 } else if constexpr (std::is_same_v<T, KCodeMemory>) { 347 } else if constexpr (std::is_same_v<T, KCodeMemory>) {
351 return slab_heap_container->code_memory; 348 return slab_heap_container->code_memory;
352 } else if constexpr (std::is_same_v<T, KPageBuffer>) { 349 } else if constexpr (std::is_same_v<T, KPageBuffer>) {
@@ -412,7 +409,6 @@ private:
412 KSlabHeap<KSharedMemoryInfo> shared_memory_info; 409 KSlabHeap<KSharedMemoryInfo> shared_memory_info;
413 KSlabHeap<KThread> thread; 410 KSlabHeap<KThread> thread;
414 KSlabHeap<KTransferMemory> transfer_memory; 411 KSlabHeap<KTransferMemory> transfer_memory;
415 KSlabHeap<KWritableEvent> writeable_event;
416 KSlabHeap<KCodeMemory> code_memory; 412 KSlabHeap<KCodeMemory> code_memory;
417 KSlabHeap<KPageBuffer> page_buffer; 413 KSlabHeap<KPageBuffer> page_buffer;
418 KSlabHeap<KThreadLocalPage> thread_local_page; 414 KSlabHeap<KThreadLocalPage> thread_local_page;
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 27e5a805d..1d145ea91 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -29,12 +29,12 @@
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"
35#include "core/hle/kernel/k_thread_queue.h" 36#include "core/hle/kernel/k_thread_queue.h"
36#include "core/hle/kernel/k_transfer_memory.h" 37#include "core/hle/kernel/k_transfer_memory.h"
37#include "core/hle/kernel/k_writable_event.h"
38#include "core/hle/kernel/kernel.h" 38#include "core/hle/kernel/kernel.h"
39#include "core/hle/kernel/physical_core.h" 39#include "core/hle/kernel/physical_core.h"
40#include "core/hle/kernel/svc.h" 40#include "core/hle/kernel/svc.h"
@@ -256,6 +256,93 @@ static Result UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u3
256 return UnmapMemory(system, dst_addr, src_addr, size); 256 return UnmapMemory(system, dst_addr, src_addr, size);
257} 257}
258 258
259template <typename T>
260Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, u64 name) {
261 auto& process = *system.CurrentProcess();
262 auto& handle_table = process.GetHandleTable();
263
264 // Declare the session we're going to allocate.
265 T* session;
266
267 // Reserve a new session from the process resource limit.
268 // FIXME: LimitableResource_SessionCountMax
269 KScopedResourceReservation session_reservation(&process, LimitableResource::Sessions);
270 if (session_reservation.Succeeded()) {
271 session = T::Create(system.Kernel());
272 } else {
273 return ResultLimitReached;
274
275 // // We couldn't reserve a session. Check that we support dynamically expanding the
276 // // resource limit.
277 // R_UNLESS(process.GetResourceLimit() ==
278 // &system.Kernel().GetSystemResourceLimit(), ResultLimitReached);
279 // R_UNLESS(KTargetSystem::IsDynamicResourceLimitsEnabled(), ResultLimitReached());
280
281 // // Try to allocate a session from unused slab memory.
282 // session = T::CreateFromUnusedSlabMemory();
283 // R_UNLESS(session != nullptr, ResultLimitReached);
284 // ON_RESULT_FAILURE { session->Close(); };
285
286 // // If we're creating a KSession, we want to add two KSessionRequests to the heap, to
287 // // prevent request exhaustion.
288 // // NOTE: Nintendo checks if session->DynamicCast<KSession *>() != nullptr, but there's
289 // // no reason to not do this statically.
290 // if constexpr (std::same_as<T, KSession>) {
291 // for (size_t i = 0; i < 2; i++) {
292 // KSessionRequest* request = KSessionRequest::CreateFromUnusedSlabMemory();
293 // R_UNLESS(request != nullptr, ResultLimitReached);
294 // request->Close();
295 // }
296 // }
297
298 // We successfully allocated a session, so add the object we allocated to the resource
299 // limit.
300 // system.Kernel().GetSystemResourceLimit().Reserve(LimitableResource::Sessions, 1);
301 }
302
303 // Check that we successfully created a session.
304 R_UNLESS(session != nullptr, ResultOutOfResource);
305
306 // Initialize the session.
307 session->Initialize(nullptr, fmt::format("{}", name));
308
309 // Commit the session reservation.
310 session_reservation.Commit();
311
312 // Ensure that we clean up the session (and its only references are handle table) on function
313 // end.
314 SCOPE_EXIT({
315 session->GetClientSession().Close();
316 session->GetServerSession().Close();
317 });
318
319 // Register the session.
320 T::Register(system.Kernel(), session);
321
322 // Add the server session to the handle table.
323 R_TRY(handle_table.Add(out_server, &session->GetServerSession()));
324
325 // Add the client session to the handle table.
326 const auto result = handle_table.Add(out_client, &session->GetClientSession());
327
328 if (!R_SUCCEEDED(result)) {
329 // Ensure that we maintaing a clean handle state on exit.
330 handle_table.Remove(*out_server);
331 }
332
333 return result;
334}
335
336static Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client,
337 u32 is_light, u64 name) {
338 if (is_light) {
339 // return CreateSession<KLightSession>(system, out_server, out_client, name);
340 return ResultUnknown;
341 } else {
342 return CreateSession<KSession>(system, out_server, out_client, name);
343 }
344}
345
259/// Connect to an OS service given the port name, returns the handle to the port to out 346/// Connect to an OS service given the port name, returns the handle to the port to out
260static Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) { 347static Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) {
261 auto& memory = system.Memory(); 348 auto& memory = system.Memory();
@@ -295,7 +382,8 @@ static Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_n
295 382
296 // Create a session. 383 // Create a session.
297 KClientSession* session{}; 384 KClientSession* session{};
298 R_TRY(port->CreateSession(std::addressof(session))); 385 R_TRY(port->CreateSession(std::addressof(session),
386 std::make_shared<SessionRequestManager>(kernel)));
299 port->Close(); 387 port->Close();
300 388
301 // Register the session in the table, close the extra reference. 389 // Register the session in the table, close the extra reference.
@@ -313,7 +401,7 @@ static Result ConnectToNamedPort32(Core::System& system, Handle* out_handle,
313 return ConnectToNamedPort(system, out_handle, port_name_address); 401 return ConnectToNamedPort(system, out_handle, port_name_address);
314} 402}
315 403
316/// Makes a blocking IPC call to an OS service. 404/// Makes a blocking IPC call to a service.
317static Result SendSyncRequest(Core::System& system, Handle handle) { 405static Result SendSyncRequest(Core::System& system, Handle handle) {
318 auto& kernel = system.Kernel(); 406 auto& kernel = system.Kernel();
319 407
@@ -327,22 +415,75 @@ static Result SendSyncRequest(Core::System& system, Handle handle) {
327 415
328 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); 416 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
329 417
330 { 418 return session->SendSyncRequest();
331 KScopedSchedulerLock lock(kernel);
332
333 // This is a synchronous request, so we should wait for our request to complete.
334 GetCurrentThread(kernel).BeginWait(std::addressof(wait_queue));
335 GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC);
336 session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(), system.CoreTiming());
337 }
338
339 return GetCurrentThread(kernel).GetWaitResult();
340} 419}
341 420
342static Result SendSyncRequest32(Core::System& system, Handle handle) { 421static Result SendSyncRequest32(Core::System& system, Handle handle) {
343 return SendSyncRequest(system, handle); 422 return SendSyncRequest(system, handle);
344} 423}
345 424
425static Result ReplyAndReceive(Core::System& system, s32* out_index, Handle* handles,
426 s32 num_handles, Handle reply_target, s64 timeout_ns) {
427 auto& kernel = system.Kernel();
428 auto& handle_table = GetCurrentThread(kernel).GetOwnerProcess()->GetHandleTable();
429
430 // Convert handle list to object table.
431 std::vector<KSynchronizationObject*> objs(num_handles);
432 R_UNLESS(
433 handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles, num_handles),
434 ResultInvalidHandle);
435
436 // Ensure handles are closed when we're done.
437 SCOPE_EXIT({
438 for (auto i = 0; i < num_handles; ++i) {
439 objs[i]->Close();
440 }
441 });
442
443 // Reply to the target, if one is specified.
444 if (reply_target != InvalidHandle) {
445 KScopedAutoObject session = handle_table.GetObject<KServerSession>(reply_target);
446 R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
447
448 // If we fail to reply, we want to set the output index to -1.
449 // ON_RESULT_FAILURE { *out_index = -1; };
450
451 // Send the reply.
452 // R_TRY(session->SendReply());
453
454 Result rc = session->SendReply();
455 if (!R_SUCCEEDED(rc)) {
456 *out_index = -1;
457 return rc;
458 }
459 }
460
461 // Wait for a message.
462 while (true) {
463 // Wait for an object.
464 s32 index;
465 Result result = KSynchronizationObject::Wait(kernel, &index, objs.data(),
466 static_cast<s32>(objs.size()), timeout_ns);
467 if (result == ResultTimedOut) {
468 return result;
469 }
470
471 // Receive the request.
472 if (R_SUCCEEDED(result)) {
473 KServerSession* session = objs[index]->DynamicCast<KServerSession*>();
474 if (session != nullptr) {
475 result = session->ReceiveRequest();
476 if (result == ResultNotFound) {
477 continue;
478 }
479 }
480 }
481
482 *out_index = index;
483 return result;
484 }
485}
486
346/// Get the ID for the specified thread. 487/// Get the ID for the specified thread.
347static Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) { 488static Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) {
348 // Get the thread from its handle. 489 // Get the thread from its handle.
@@ -2303,11 +2444,11 @@ static Result SignalEvent(Core::System& system, Handle event_handle) {
2303 // Get the current handle table. 2444 // Get the current handle table.
2304 const KHandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 2445 const KHandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
2305 2446
2306 // Get the writable event. 2447 // Get the event.
2307 KScopedAutoObject writable_event = handle_table.GetObject<KWritableEvent>(event_handle); 2448 KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
2308 R_UNLESS(writable_event.IsNotNull(), ResultInvalidHandle); 2449 R_UNLESS(event.IsNotNull(), ResultInvalidHandle);
2309 2450
2310 return writable_event->Signal(); 2451 return event->Signal();
2311} 2452}
2312 2453
2313static Result SignalEvent32(Core::System& system, Handle event_handle) { 2454static Result SignalEvent32(Core::System& system, Handle event_handle) {
@@ -2322,9 +2463,9 @@ static Result ClearEvent(Core::System& system, Handle event_handle) {
2322 2463
2323 // Try to clear the writable event. 2464 // Try to clear the writable event.
2324 { 2465 {
2325 KScopedAutoObject writable_event = handle_table.GetObject<KWritableEvent>(event_handle); 2466 KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
2326 if (writable_event.IsNotNull()) { 2467 if (event.IsNotNull()) {
2327 return writable_event->Clear(); 2468 return event->Clear();
2328 } 2469 }
2329 } 2470 }
2330 2471
@@ -2362,24 +2503,24 @@ static Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_r
2362 R_UNLESS(event != nullptr, ResultOutOfResource); 2503 R_UNLESS(event != nullptr, ResultOutOfResource);
2363 2504
2364 // Initialize the event. 2505 // Initialize the event.
2365 event->Initialize("CreateEvent", kernel.CurrentProcess()); 2506 event->Initialize(kernel.CurrentProcess());
2366 2507
2367 // Commit the thread reservation. 2508 // Commit the thread reservation.
2368 event_reservation.Commit(); 2509 event_reservation.Commit();
2369 2510
2370 // Ensure that we clean up the event (and its only references are handle table) on function end. 2511 // Ensure that we clean up the event (and its only references are handle table) on function end.
2371 SCOPE_EXIT({ 2512 SCOPE_EXIT({
2372 event->GetWritableEvent().Close();
2373 event->GetReadableEvent().Close(); 2513 event->GetReadableEvent().Close();
2514 event->Close();
2374 }); 2515 });
2375 2516
2376 // Register the event. 2517 // Register the event.
2377 KEvent::Register(kernel, event); 2518 KEvent::Register(kernel, event);
2378 2519
2379 // Add the writable event to the handle table. 2520 // Add the event to the handle table.
2380 R_TRY(handle_table.Add(out_write, std::addressof(event->GetWritableEvent()))); 2521 R_TRY(handle_table.Add(out_write, event));
2381 2522
2382 // Add the writable event to the handle table. 2523 // Ensure that we maintaing a clean handle state on exit.
2383 auto handle_guard = SCOPE_GUARD({ handle_table.Remove(*out_write); }); 2524 auto handle_guard = SCOPE_GUARD({ handle_table.Remove(*out_write); });
2384 2525
2385 // Add the readable event to the handle table. 2526 // Add the readable event to the handle table.
@@ -2860,10 +3001,10 @@ static const FunctionDef SVC_Table_64[] = {
2860 {0x3D, SvcWrap64<ChangeKernelTraceState>, "ChangeKernelTraceState"}, 3001 {0x3D, SvcWrap64<ChangeKernelTraceState>, "ChangeKernelTraceState"},
2861 {0x3E, nullptr, "Unknown3e"}, 3002 {0x3E, nullptr, "Unknown3e"},
2862 {0x3F, nullptr, "Unknown3f"}, 3003 {0x3F, nullptr, "Unknown3f"},
2863 {0x40, nullptr, "CreateSession"}, 3004 {0x40, SvcWrap64<CreateSession>, "CreateSession"},
2864 {0x41, nullptr, "AcceptSession"}, 3005 {0x41, nullptr, "AcceptSession"},
2865 {0x42, nullptr, "ReplyAndReceiveLight"}, 3006 {0x42, nullptr, "ReplyAndReceiveLight"},
2866 {0x43, nullptr, "ReplyAndReceive"}, 3007 {0x43, SvcWrap64<ReplyAndReceive>, "ReplyAndReceive"},
2867 {0x44, nullptr, "ReplyAndReceiveWithUserBuffer"}, 3008 {0x44, nullptr, "ReplyAndReceiveWithUserBuffer"},
2868 {0x45, SvcWrap64<CreateEvent>, "CreateEvent"}, 3009 {0x45, SvcWrap64<CreateEvent>, "CreateEvent"},
2869 {0x46, nullptr, "MapIoRegion"}, 3010 {0x46, nullptr, "MapIoRegion"},
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
index 4bc49087e..272c54cf7 100644
--- a/src/core/hle/kernel/svc_wrap.h
+++ b/src/core/hle/kernel/svc_wrap.h
@@ -8,6 +8,7 @@
8#include "core/core.h" 8#include "core/core.h"
9#include "core/hle/kernel/svc_types.h" 9#include "core/hle/kernel/svc_types.h"
10#include "core/hle/result.h" 10#include "core/hle/result.h"
11#include "core/memory.h"
11 12
12namespace Kernel { 13namespace Kernel {
13 14
@@ -346,6 +347,37 @@ void SvcWrap64(Core::System& system) {
346 FuncReturn(system, retval); 347 FuncReturn(system, retval);
347} 348}
348 349
350// Used by CreateSession
351template <Result func(Core::System&, Handle*, Handle*, u32, u64)>
352void SvcWrap64(Core::System& system) {
353 Handle param_1 = 0;
354 Handle param_2 = 0;
355 const u32 retval = func(system, &param_1, &param_2, static_cast<u32>(Param(system, 2)),
356 static_cast<u32>(Param(system, 3)))
357 .raw;
358
359 system.CurrentArmInterface().SetReg(1, param_1);
360 system.CurrentArmInterface().SetReg(2, param_2);
361 FuncReturn(system, retval);
362}
363
364// Used by ReplyAndReceive
365template <Result func(Core::System&, s32*, Handle*, s32, Handle, s64)>
366void SvcWrap64(Core::System& system) {
367 s32 param_1 = 0;
368 s32 num_handles = static_cast<s32>(Param(system, 2));
369
370 std::vector<Handle> handles(num_handles);
371 system.Memory().ReadBlock(Param(system, 1), handles.data(), num_handles * sizeof(Handle));
372
373 const u32 retval = func(system, &param_1, handles.data(), num_handles,
374 static_cast<s32>(Param(system, 3)), static_cast<s64>(Param(system, 4)))
375 .raw;
376
377 system.CurrentArmInterface().SetReg(1, param_1);
378 FuncReturn(system, retval);
379}
380
349// Used by WaitForAddress 381// Used by WaitForAddress
350template <Result func(Core::System&, u64, Svc::ArbitrationType, s32, s64)> 382template <Result func(Core::System&, u64, Svc::ArbitrationType, s32, s64)>
351void SvcWrap64(Core::System& system) { 383void SvcWrap64(Core::System& system) {
diff --git a/src/core/hle/service/acc/async_context.cpp b/src/core/hle/service/acc/async_context.cpp
index c85b2e43a..713689d8f 100644
--- a/src/core/hle/service/acc/async_context.cpp
+++ b/src/core/hle/service/acc/async_context.cpp
@@ -64,7 +64,7 @@ void IAsyncContext::GetResult(Kernel::HLERequestContext& ctx) {
64 64
65void IAsyncContext::MarkComplete() { 65void IAsyncContext::MarkComplete() {
66 is_complete.store(true); 66 is_complete.store(true);
67 completion_event->GetWritableEvent().Signal(); 67 completion_event->Signal();
68} 68}
69 69
70} // namespace Service::Account 70} // namespace Service::Account
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 6fb7e198e..e55233054 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -316,7 +316,7 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
316 316
317 accumulated_suspended_tick_changed_event = 317 accumulated_suspended_tick_changed_event =
318 service_context.CreateEvent("ISelfController:AccumulatedSuspendedTickChangedEvent"); 318 service_context.CreateEvent("ISelfController:AccumulatedSuspendedTickChangedEvent");
319 accumulated_suspended_tick_changed_event->GetWritableEvent().Signal(); 319 accumulated_suspended_tick_changed_event->Signal();
320} 320}
321 321
322ISelfController::~ISelfController() { 322ISelfController::~ISelfController() {
@@ -378,7 +378,7 @@ void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) {
378void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { 378void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) {
379 LOG_WARNING(Service_AM, "(STUBBED) called"); 379 LOG_WARNING(Service_AM, "(STUBBED) called");
380 380
381 launchable_event->GetWritableEvent().Signal(); 381 launchable_event->Signal();
382 382
383 IPC::ResponseBuilder rb{ctx, 2, 1}; 383 IPC::ResponseBuilder rb{ctx, 2, 1};
384 rb.Push(ResultSuccess); 384 rb.Push(ResultSuccess);
@@ -618,18 +618,18 @@ Kernel::KReadableEvent& AppletMessageQueue::GetOperationModeChangedEvent() {
618 618
619void AppletMessageQueue::PushMessage(AppletMessage msg) { 619void AppletMessageQueue::PushMessage(AppletMessage msg) {
620 messages.push(msg); 620 messages.push(msg);
621 on_new_message->GetWritableEvent().Signal(); 621 on_new_message->Signal();
622} 622}
623 623
624AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() { 624AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() {
625 if (messages.empty()) { 625 if (messages.empty()) {
626 on_new_message->GetWritableEvent().Clear(); 626 on_new_message->Clear();
627 return AppletMessage::None; 627 return AppletMessage::None;
628 } 628 }
629 auto msg = messages.front(); 629 auto msg = messages.front();
630 messages.pop(); 630 messages.pop();
631 if (messages.empty()) { 631 if (messages.empty()) {
632 on_new_message->GetWritableEvent().Clear(); 632 on_new_message->Clear();
633 } 633 }
634 return msg; 634 return msg;
635} 635}
@@ -653,7 +653,7 @@ void AppletMessageQueue::FocusStateChanged() {
653void AppletMessageQueue::OperationModeChanged() { 653void AppletMessageQueue::OperationModeChanged() {
654 PushMessage(AppletMessage::OperationModeChanged); 654 PushMessage(AppletMessage::OperationModeChanged);
655 PushMessage(AppletMessage::PerformanceModeChanged); 655 PushMessage(AppletMessage::PerformanceModeChanged);
656 on_operation_mode_changed->GetWritableEvent().Signal(); 656 on_operation_mode_changed->Signal();
657} 657}
658 658
659ICommonStateGetter::ICommonStateGetter(Core::System& system_, 659ICommonStateGetter::ICommonStateGetter(Core::System& system_,
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index b5b8e4cad..7062df21c 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -65,7 +65,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() {
65 65
66 auto out = std::move(out_channel.front()); 66 auto out = std::move(out_channel.front());
67 out_channel.pop_front(); 67 out_channel.pop_front();
68 pop_out_data_event->GetWritableEvent().Clear(); 68 pop_out_data_event->Clear();
69 return out; 69 return out;
70} 70}
71 71
@@ -84,7 +84,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() {
84 84
85 auto out = std::move(out_interactive_channel.front()); 85 auto out = std::move(out_interactive_channel.front());
86 out_interactive_channel.pop_front(); 86 out_interactive_channel.pop_front();
87 pop_interactive_out_data_event->GetWritableEvent().Clear(); 87 pop_interactive_out_data_event->Clear();
88 return out; 88 return out;
89} 89}
90 90
@@ -103,7 +103,7 @@ void AppletDataBroker::PushNormalDataFromGame(std::shared_ptr<IStorage>&& storag
103 103
104void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) { 104void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) {
105 out_channel.emplace_back(std::move(storage)); 105 out_channel.emplace_back(std::move(storage));
106 pop_out_data_event->GetWritableEvent().Signal(); 106 pop_out_data_event->Signal();
107} 107}
108 108
109void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) { 109void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) {
@@ -112,11 +112,11 @@ void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& s
112 112
113void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) { 113void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) {
114 out_interactive_channel.emplace_back(std::move(storage)); 114 out_interactive_channel.emplace_back(std::move(storage));
115 pop_interactive_out_data_event->GetWritableEvent().Signal(); 115 pop_interactive_out_data_event->Signal();
116} 116}
117 117
118void AppletDataBroker::SignalStateChanged() { 118void AppletDataBroker::SignalStateChanged() {
119 state_changed_event->GetWritableEvent().Signal(); 119 state_changed_event->Signal();
120 120
121 switch (applet_mode) { 121 switch (applet_mode) {
122 case LibraryAppletMode::AllForeground: 122 case LibraryAppletMode::AllForeground:
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 6fb07c37d..60c30cd5b 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -239,7 +239,7 @@ public:
239 }; 239 };
240 RegisterHandlers(functions); 240 RegisterHandlers(functions);
241 241
242 event->GetWritableEvent().Signal(); 242 event->Signal();
243 } 243 }
244 244
245 ~IAudioDevice() override { 245 ~IAudioDevice() override {
@@ -325,7 +325,7 @@ private:
325 void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { 325 void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) {
326 LOG_DEBUG(Service_Audio, "(STUBBED) called"); 326 LOG_DEBUG(Service_Audio, "(STUBBED) called");
327 327
328 event->GetWritableEvent().Signal(); 328 event->Signal();
329 329
330 IPC::ResponseBuilder rb{ctx, 2, 1}; 330 IPC::ResponseBuilder rb{ctx, 2, 1};
331 rb.Push(ResultSuccess); 331 rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp
index cd0b405ff..847f76987 100644
--- a/src/core/hle/service/bcat/backend/backend.cpp
+++ b/src/core/hle/service/bcat/backend/backend.cpp
@@ -82,7 +82,7 @@ void ProgressServiceBackend::FinishDownload(Result result) {
82} 82}
83 83
84void ProgressServiceBackend::SignalUpdate() { 84void ProgressServiceBackend::SignalUpdate() {
85 update_event->GetWritableEvent().Signal(); 85 update_event->Signal();
86} 86}
87 87
88Backend::Backend(DirectoryGetter getter) : dir_getter(std::move(getter)) {} 88Backend::Backend(DirectoryGetter getter) : dir_getter(std::move(getter)) {}
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index f8972ec7a..98e4f2af7 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -16,7 +16,6 @@
16#include "core/hid/hid_core.h" 16#include "core/hid/hid_core.h"
17#include "core/hle/kernel/k_event.h" 17#include "core/hle/kernel/k_event.h"
18#include "core/hle/kernel/k_readable_event.h" 18#include "core/hle/kernel/k_readable_event.h"
19#include "core/hle/kernel/k_writable_event.h"
20#include "core/hle/service/hid/controllers/npad.h" 19#include "core/hle/service/hid/controllers/npad.h"
21#include "core/hle/service/hid/errors.h" 20#include "core/hle/service/hid/errors.h"
22#include "core/hle/service/kernel_helpers.h" 21#include "core/hle/service/kernel_helpers.h"
@@ -167,7 +166,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
167 const auto& battery_level = controller.device->GetBattery(); 166 const auto& battery_level = controller.device->GetBattery();
168 auto* shared_memory = controller.shared_memory; 167 auto* shared_memory = controller.shared_memory;
169 if (controller_type == Core::HID::NpadStyleIndex::None) { 168 if (controller_type == Core::HID::NpadStyleIndex::None) {
170 controller.styleset_changed_event->GetWritableEvent().Signal(); 169 controller.styleset_changed_event->Signal();
171 return; 170 return;
172 } 171 }
173 172
@@ -1033,7 +1032,7 @@ Kernel::KReadableEvent& Controller_NPad::GetStyleSetChangedEvent(Core::HID::Npad
1033 1032
1034void Controller_NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const { 1033void Controller_NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const {
1035 const auto& controller = GetControllerFromNpadIdType(npad_id); 1034 const auto& controller = GetControllerFromNpadIdType(npad_id);
1036 controller.styleset_changed_event->GetWritableEvent().Signal(); 1035 controller.styleset_changed_event->Signal();
1037} 1036}
1038 1037
1039void Controller_NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller, 1038void Controller_NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller,
diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp
index 575d4e626..4564ea1e2 100644
--- a/src/core/hle/service/hid/controllers/palma.cpp
+++ b/src/core/hle/service/hid/controllers/palma.cpp
@@ -73,7 +73,7 @@ Result Controller_Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle,
73 operation.operation = PalmaOperationType::PlayActivity; 73 operation.operation = PalmaOperationType::PlayActivity;
74 operation.result = PalmaResultSuccess; 74 operation.result = PalmaResultSuccess;
75 operation.data = {}; 75 operation.data = {};
76 operation_complete_event->GetWritableEvent().Signal(); 76 operation_complete_event->Signal();
77 return ResultSuccess; 77 return ResultSuccess;
78} 78}
79 79
@@ -93,7 +93,7 @@ Result Controller_Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) {
93 operation.operation = PalmaOperationType::ReadStep; 93 operation.operation = PalmaOperationType::ReadStep;
94 operation.result = PalmaResultSuccess; 94 operation.result = PalmaResultSuccess;
95 operation.data = {}; 95 operation.data = {};
96 operation_complete_event->GetWritableEvent().Signal(); 96 operation_complete_event->Signal();
97 return ResultSuccess; 97 return ResultSuccess;
98} 98}
99 99
@@ -122,7 +122,7 @@ Result Controller_Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle
122 operation.operation = PalmaOperationType::ReadUniqueCode; 122 operation.operation = PalmaOperationType::ReadUniqueCode;
123 operation.result = PalmaResultSuccess; 123 operation.result = PalmaResultSuccess;
124 operation.data = {}; 124 operation.data = {};
125 operation_complete_event->GetWritableEvent().Signal(); 125 operation_complete_event->Signal();
126 return ResultSuccess; 126 return ResultSuccess;
127} 127}
128 128
@@ -133,7 +133,7 @@ Result Controller_Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle&
133 operation.operation = PalmaOperationType::SetUniqueCodeInvalid; 133 operation.operation = PalmaOperationType::SetUniqueCodeInvalid;
134 operation.result = PalmaResultSuccess; 134 operation.result = PalmaResultSuccess;
135 operation.data = {}; 135 operation.data = {};
136 operation_complete_event->GetWritableEvent().Signal(); 136 operation_complete_event->Signal();
137 return ResultSuccess; 137 return ResultSuccess;
138} 138}
139 139
@@ -147,7 +147,7 @@ Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandl
147 operation.operation = PalmaOperationType::WriteRgbLedPatternEntry; 147 operation.operation = PalmaOperationType::WriteRgbLedPatternEntry;
148 operation.result = PalmaResultSuccess; 148 operation.result = PalmaResultSuccess;
149 operation.data = {}; 149 operation.data = {};
150 operation_complete_event->GetWritableEvent().Signal(); 150 operation_complete_event->Signal();
151 return ResultSuccess; 151 return ResultSuccess;
152} 152}
153 153
@@ -159,7 +159,7 @@ Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle
159 operation.operation = PalmaOperationType::WriteWaveEntry; 159 operation.operation = PalmaOperationType::WriteWaveEntry;
160 operation.result = PalmaResultSuccess; 160 operation.result = PalmaResultSuccess;
161 operation.data = {}; 161 operation.data = {};
162 operation_complete_event->GetWritableEvent().Signal(); 162 operation_complete_event->Signal();
163 return ResultSuccess; 163 return ResultSuccess;
164} 164}
165 165
@@ -172,7 +172,7 @@ Result Controller_Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnec
172 operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion; 172 operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion;
173 operation.result = PalmaResultSuccess; 173 operation.result = PalmaResultSuccess;
174 operation.data[0] = {}; 174 operation.data[0] = {};
175 operation_complete_event->GetWritableEvent().Signal(); 175 operation_complete_event->Signal();
176 return ResultSuccess; 176 return ResultSuccess;
177} 177}
178 178
@@ -185,7 +185,7 @@ Result Controller_Palma::GetPalmaDataBaseIdentificationVersion(
185 operation.result = PalmaResultSuccess; 185 operation.result = PalmaResultSuccess;
186 operation.data = {}; 186 operation.data = {};
187 operation.data[0] = static_cast<u8>(database_id_version); 187 operation.data[0] = static_cast<u8>(database_id_version);
188 operation_complete_event->GetWritableEvent().Signal(); 188 operation_complete_event->Signal();
189 return ResultSuccess; 189 return ResultSuccess;
190} 190}
191 191
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 46bad7871..79375bd2f 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -2118,7 +2118,7 @@ void Hid::WritePalmaWaveEntry(Kernel::HLERequestContext& ctx) {
2118 ASSERT_MSG(t_mem->GetSize() == 0x3000, "t_mem has incorrect size"); 2118 ASSERT_MSG(t_mem->GetSize() == 0x3000, "t_mem has incorrect size");
2119 2119
2120 LOG_WARNING(Service_HID, 2120 LOG_WARNING(Service_HID,
2121 "(STUBBED) called, connection_handle={}, wave_set={}, unkown={}, " 2121 "(STUBBED) called, connection_handle={}, wave_set={}, unknown={}, "
2122 "t_mem_handle=0x{:08X}, t_mem_size={}, size={}", 2122 "t_mem_handle=0x{:08X}, t_mem_size={}, size={}",
2123 connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size); 2123 connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size);
2124 2124
diff --git a/src/core/hle/service/hid/hidbus/ringcon.cpp b/src/core/hle/service/hid/hidbus/ringcon.cpp
index ad223d649..57f1a2a26 100644
--- a/src/core/hle/service/hid/hidbus/ringcon.cpp
+++ b/src/core/hle/service/hid/hidbus/ringcon.cpp
@@ -131,12 +131,12 @@ bool RingController::SetCommand(const std::vector<u8>& data) {
131 case RingConCommands::ReadRepCount: 131 case RingConCommands::ReadRepCount:
132 case RingConCommands::ReadTotalPushCount: 132 case RingConCommands::ReadTotalPushCount:
133 ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes"); 133 ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes");
134 send_command_async_event->GetWritableEvent().Signal(); 134 send_command_async_event->Signal();
135 return true; 135 return true;
136 case RingConCommands::ResetRepCount: 136 case RingConCommands::ResetRepCount:
137 ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes"); 137 ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes");
138 total_rep_count = 0; 138 total_rep_count = 0;
139 send_command_async_event->GetWritableEvent().Signal(); 139 send_command_async_event->Signal();
140 return true; 140 return true;
141 case RingConCommands::SaveCalData: { 141 case RingConCommands::SaveCalData: {
142 ASSERT_MSG(data.size() == 0x14, "data.size is not 0x14 bytes"); 142 ASSERT_MSG(data.size() == 0x14, "data.size is not 0x14 bytes");
@@ -144,14 +144,14 @@ bool RingController::SetCommand(const std::vector<u8>& data) {
144 SaveCalData save_info{}; 144 SaveCalData save_info{};
145 std::memcpy(&save_info, data.data(), sizeof(SaveCalData)); 145 std::memcpy(&save_info, data.data(), sizeof(SaveCalData));
146 user_calibration = save_info.calibration; 146 user_calibration = save_info.calibration;
147 send_command_async_event->GetWritableEvent().Signal(); 147 send_command_async_event->Signal();
148 return true; 148 return true;
149 } 149 }
150 default: 150 default:
151 LOG_ERROR(Service_HID, "Command not implemented {}", command); 151 LOG_ERROR(Service_HID, "Command not implemented {}", command);
152 command = RingConCommands::Error; 152 command = RingConCommands::Error;
153 // Signal a reply to avoid softlocking the game 153 // Signal a reply to avoid softlocking the game
154 send_command_async_event->GetWritableEvent().Signal(); 154 send_command_async_event->Signal();
155 return false; 155 return false;
156 } 156 }
157} 157}
diff --git a/src/core/hle/service/hid/irsensor/pointing_processor.h b/src/core/hle/service/hid/irsensor/pointing_processor.h
index cf4930794..d63423aff 100644
--- a/src/core/hle/service/hid/irsensor/pointing_processor.h
+++ b/src/core/hle/service/hid/irsensor/pointing_processor.h
@@ -37,10 +37,10 @@ private:
37 u8 pointing_status; 37 u8 pointing_status;
38 INSERT_PADDING_BYTES(3); 38 INSERT_PADDING_BYTES(3);
39 u32 unknown; 39 u32 unknown;
40 float unkown_float1; 40 float unknown_float1;
41 float position_x; 41 float position_x;
42 float position_y; 42 float position_y;
43 float unkown_float2; 43 float unknown_float2;
44 Core::IrSensor::IrsRect window_of_interest; 44 Core::IrSensor::IrsRect window_of_interest;
45 }; 45 };
46 static_assert(sizeof(PointingProcessorMarkerData) == 0x20, 46 static_assert(sizeof(PointingProcessorMarkerData) == 0x20,
diff --git a/src/core/hle/service/kernel_helpers.cpp b/src/core/hle/service/kernel_helpers.cpp
index 3e317367b..af133af93 100644
--- a/src/core/hle/service/kernel_helpers.cpp
+++ b/src/core/hle/service/kernel_helpers.cpp
@@ -9,7 +9,6 @@
9#include "core/hle/kernel/k_readable_event.h" 9#include "core/hle/kernel/k_readable_event.h"
10#include "core/hle/kernel/k_resource_limit.h" 10#include "core/hle/kernel/k_resource_limit.h"
11#include "core/hle/kernel/k_scoped_resource_reservation.h" 11#include "core/hle/kernel/k_scoped_resource_reservation.h"
12#include "core/hle/kernel/k_writable_event.h"
13#include "core/hle/service/kernel_helpers.h" 12#include "core/hle/service/kernel_helpers.h"
14 13
15namespace Service::KernelHelpers { 14namespace Service::KernelHelpers {
@@ -46,7 +45,7 @@ Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) {
46 } 45 }
47 46
48 // Initialize the event. 47 // Initialize the event.
49 event->Initialize(std::move(name), process); 48 event->Initialize(process);
50 49
51 // Commit the thread reservation. 50 // Commit the thread reservation.
52 event_reservation.Commit(); 51 event_reservation.Commit();
@@ -59,7 +58,7 @@ Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) {
59 58
60void ServiceContext::CloseEvent(Kernel::KEvent* event) { 59void ServiceContext::CloseEvent(Kernel::KEvent* event) {
61 event->GetReadableEvent().Close(); 60 event->GetReadableEvent().Close();
62 event->GetWritableEvent().Close(); 61 event->Close();
63} 62}
64 63
65} // namespace Service::KernelHelpers 64} // namespace Service::KernelHelpers
diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp
index ea3e7e55a..6df563136 100644
--- a/src/core/hle/service/ldn/ldn.cpp
+++ b/src/core/hle/service/ldn/ldn.cpp
@@ -165,7 +165,7 @@ public:
165 } 165 }
166 166
167 void OnEventFired() { 167 void OnEventFired() {
168 state_change_event->GetWritableEvent().Signal(); 168 state_change_event->Signal();
169 } 169 }
170 170
171 void GetState(Kernel::HLERequestContext& ctx) { 171 void GetState(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp
index ec895ac01..76f8a267a 100644
--- a/src/core/hle/service/nfp/nfp_device.cpp
+++ b/src/core/hle/service/nfp/nfp_device.cpp
@@ -58,7 +58,7 @@ NfpDevice::~NfpDevice() {
58void NfpDevice::NpadUpdate(Core::HID::ControllerTriggerType type) { 58void NfpDevice::NpadUpdate(Core::HID::ControllerTriggerType type) {
59 if (type == Core::HID::ControllerTriggerType::Connected || 59 if (type == Core::HID::ControllerTriggerType::Connected ||
60 type == Core::HID::ControllerTriggerType::Disconnected) { 60 type == Core::HID::ControllerTriggerType::Disconnected) {
61 availability_change_event->GetWritableEvent().Signal(); 61 availability_change_event->Signal();
62 return; 62 return;
63 } 63 }
64 64
@@ -100,7 +100,7 @@ bool NfpDevice::LoadAmiibo(std::span<const u8> data) {
100 100
101 device_state = DeviceState::TagFound; 101 device_state = DeviceState::TagFound;
102 deactivate_event->GetReadableEvent().Clear(); 102 deactivate_event->GetReadableEvent().Clear();
103 activate_event->GetWritableEvent().Signal(); 103 activate_event->Signal();
104 return true; 104 return true;
105} 105}
106 106
@@ -115,7 +115,7 @@ void NfpDevice::CloseAmiibo() {
115 encrypted_tag_data = {}; 115 encrypted_tag_data = {};
116 tag_data = {}; 116 tag_data = {};
117 activate_event->GetReadableEvent().Clear(); 117 activate_event->GetReadableEvent().Clear();
118 deactivate_event->GetWritableEvent().Signal(); 118 deactivate_event->Signal();
119} 119}
120 120
121Kernel::KReadableEvent& NfpDevice::GetActivateEvent() const { 121Kernel::KReadableEvent& NfpDevice::GetActivateEvent() const {
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index b2bb7426d..5a8a91e0b 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -328,7 +328,7 @@ private:
328 void StartTask(Kernel::HLERequestContext& ctx) { 328 void StartTask(Kernel::HLERequestContext& ctx) {
329 // No need to connect to the internet, just finish the task straight away. 329 // No need to connect to the internet, just finish the task straight away.
330 LOG_DEBUG(Service_NIM, "called"); 330 LOG_DEBUG(Service_NIM, "called");
331 finished_event->GetWritableEvent().Signal(); 331 finished_event->Signal();
332 IPC::ResponseBuilder rb{ctx, 2}; 332 IPC::ResponseBuilder rb{ctx, 2};
333 rb.Push(ResultSuccess); 333 rb.Push(ResultSuccess);
334 } 334 }
@@ -350,7 +350,7 @@ private:
350 350
351 void Cancel(Kernel::HLERequestContext& ctx) { 351 void Cancel(Kernel::HLERequestContext& ctx) {
352 LOG_DEBUG(Service_NIM, "called"); 352 LOG_DEBUG(Service_NIM, "called");
353 finished_event->GetWritableEvent().Clear(); 353 finished_event->Clear();
354 IPC::ResponseBuilder rb{ctx, 2}; 354 IPC::ResponseBuilder rb{ctx, 2};
355 rb.Push(ResultSuccess); 355 rb.Push(ResultSuccess);
356 } 356 }
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index f7318c3cb..f59a1a63d 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -8,6 +8,7 @@
8#include "core/file_sys/patch_manager.h" 8#include "core/file_sys/patch_manager.h"
9#include "core/file_sys/vfs.h" 9#include "core/file_sys/vfs.h"
10#include "core/hle/ipc_helpers.h" 10#include "core/hle/ipc_helpers.h"
11#include "core/hle/service/glue/glue_manager.h"
11#include "core/hle/service/ns/errors.h" 12#include "core/hle/service/ns/errors.h"
12#include "core/hle/service/ns/iplatform_service_manager.h" 13#include "core/hle/service/ns/iplatform_service_manager.h"
13#include "core/hle/service/ns/language.h" 14#include "core/hle/service/ns/language.h"
@@ -581,7 +582,7 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
581 : ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} { 582 : ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} {
582 // clang-format off 583 // clang-format off
583 static const FunctionInfo functions[] = { 584 static const FunctionInfo functions[] = {
584 {0, nullptr, "GetApplicationControlData"}, 585 {0, &IReadOnlyApplicationControlDataInterface::GetApplicationControlData, "GetApplicationControlData"},
585 {1, nullptr, "GetApplicationDesiredLanguage"}, 586 {1, nullptr, "GetApplicationDesiredLanguage"},
586 {2, nullptr, "ConvertApplicationLanguageToLanguageCode"}, 587 {2, nullptr, "ConvertApplicationLanguageToLanguageCode"},
587 {3, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, 588 {3, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
@@ -594,6 +595,33 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
594 595
595IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default; 596IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default;
596 597
598void IReadOnlyApplicationControlDataInterface::GetApplicationControlData(
599 Kernel::HLERequestContext& ctx) {
600 enum class ApplicationControlSource : u8 {
601 CacheOnly,
602 Storage,
603 StorageOnly,
604 };
605
606 struct RequestParameters {
607 ApplicationControlSource source;
608 u64 application_id;
609 };
610 static_assert(sizeof(RequestParameters) == 0x10, "RequestParameters has incorrect size.");
611
612 IPC::RequestParser rp{ctx};
613 const auto parameters{rp.PopRaw<RequestParameters>()};
614 const auto nacp_data{system.GetARPManager().GetControlProperty(parameters.application_id)};
615 const auto result = nacp_data ? ResultSuccess : ResultUnknown;
616
617 if (nacp_data) {
618 ctx.WriteBuffer(nacp_data->data(), nacp_data->size());
619 }
620
621 IPC::ResponseBuilder rb{ctx, 2};
622 rb.Push(result);
623}
624
597NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} { 625NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} {
598 // clang-format off 626 // clang-format off
599 static const FunctionInfo functions[] = { 627 static const FunctionInfo functions[] = {
diff --git a/src/core/hle/service/ns/ns.h b/src/core/hle/service/ns/ns.h
index 4dc191518..9c18e935c 100644
--- a/src/core/hle/service/ns/ns.h
+++ b/src/core/hle/service/ns/ns.h
@@ -78,6 +78,9 @@ class IReadOnlyApplicationControlDataInterface final
78public: 78public:
79 explicit IReadOnlyApplicationControlDataInterface(Core::System& system_); 79 explicit IReadOnlyApplicationControlDataInterface(Core::System& system_);
80 ~IReadOnlyApplicationControlDataInterface() override; 80 ~IReadOnlyApplicationControlDataInterface() override;
81
82private:
83 void GetApplicationControlData(Kernel::HLERequestContext& ctx);
81}; 84};
82 85
83class NS final : public ServiceFramework<NS> { 86class NS final : public ServiceFramework<NS> {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 5bee4a3d3..eee11fab8 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -12,7 +12,6 @@
12#include "common/scope_exit.h" 12#include "common/scope_exit.h"
13#include "core/core.h" 13#include "core/core.h"
14#include "core/hle/kernel/k_event.h" 14#include "core/hle/kernel/k_event.h"
15#include "core/hle/kernel/k_writable_event.h"
16#include "core/hle/service/nvdrv/core/container.h" 15#include "core/hle/service/nvdrv/core/container.h"
17#include "core/hle/service/nvdrv/core/syncpoint_manager.h" 16#include "core/hle/service/nvdrv/core/syncpoint_manager.h"
18#include "core/hle/service/nvdrv/devices/nvhost_ctrl.h" 17#include "core/hle/service/nvdrv/devices/nvhost_ctrl.h"
@@ -206,7 +205,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
206 auto& event_ = events[slot]; 205 auto& event_ = events[slot];
207 if (event_.status.exchange(EventState::Signalling, std::memory_order_acq_rel) == 206 if (event_.status.exchange(EventState::Signalling, std::memory_order_acq_rel) ==
208 EventState::Waiting) { 207 EventState::Waiting) {
209 event_.kevent->GetWritableEvent().Signal(); 208 event_.kevent->Signal();
210 } 209 }
211 event_.status.store(EventState::Signalled, std::memory_order_release); 210 event_.status.store(EventState::Signalled, std::memory_order_release);
212 }); 211 });
@@ -306,7 +305,7 @@ NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::v
306 } 305 }
307 event.fails++; 306 event.fails++;
308 event.status.store(EventState::Cancelled, std::memory_order_release); 307 event.status.store(EventState::Cancelled, std::memory_order_release);
309 event.kevent->GetWritableEvent().Clear(); 308 event.kevent->Clear();
310 309
311 return NvResult::Success; 310 return NvResult::Success;
312} 311}
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 5e7b7468f..9d9924395 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -8,7 +8,6 @@
8#include "core/core.h" 8#include "core/core.h"
9#include "core/hle/ipc_helpers.h" 9#include "core/hle/ipc_helpers.h"
10#include "core/hle/kernel/k_event.h" 10#include "core/hle/kernel/k_event.h"
11#include "core/hle/kernel/k_writable_event.h"
12#include "core/hle/service/nvdrv/core/container.h" 11#include "core/hle/service/nvdrv/core/container.h"
13#include "core/hle/service/nvdrv/devices/nvdevice.h" 12#include "core/hle/service/nvdrv/devices/nvdevice.h"
14#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" 13#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.h b/src/core/hle/service/nvdrv/nvdrv_interface.h
index cd58a4f35..5ac06ee30 100644
--- a/src/core/hle/service/nvdrv/nvdrv_interface.h
+++ b/src/core/hle/service/nvdrv/nvdrv_interface.h
@@ -7,10 +7,6 @@
7#include "core/hle/service/nvdrv/nvdrv.h" 7#include "core/hle/service/nvdrv/nvdrv.h"
8#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
9 9
10namespace Kernel {
11class KWritableEvent;
12}
13
14namespace Service::Nvidia { 10namespace Service::Nvidia {
15 11
16class NVDRV final : public ServiceFramework<NVDRV> { 12class NVDRV final : public ServiceFramework<NVDRV> {
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
index d4ab23a10..77ddbb6ef 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
@@ -11,7 +11,6 @@
11#include "core/hle/kernel/hle_ipc.h" 11#include "core/hle/kernel/hle_ipc.h"
12#include "core/hle/kernel/k_event.h" 12#include "core/hle/kernel/k_event.h"
13#include "core/hle/kernel/k_readable_event.h" 13#include "core/hle/kernel/k_readable_event.h"
14#include "core/hle/kernel/k_writable_event.h"
15#include "core/hle/kernel/kernel.h" 14#include "core/hle/kernel/kernel.h"
16#include "core/hle/service/kernel_helpers.h" 15#include "core/hle/service/kernel_helpers.h"
17#include "core/hle/service/nvdrv/core/nvmap.h" 16#include "core/hle/service/nvdrv/core/nvmap.h"
@@ -110,7 +109,7 @@ Status BufferQueueProducer::SetBufferCount(s32 buffer_count) {
110 109
111 core->override_max_buffer_count = buffer_count; 110 core->override_max_buffer_count = buffer_count;
112 core->SignalDequeueCondition(); 111 core->SignalDequeueCondition();
113 buffer_wait_event->GetWritableEvent().Signal(); 112 buffer_wait_event->Signal();
114 listener = core->consumer_listener; 113 listener = core->consumer_listener;
115 } 114 }
116 115
@@ -623,7 +622,7 @@ void BufferQueueProducer::CancelBuffer(s32 slot, const Fence& fence) {
623 slots[slot].fence = fence; 622 slots[slot].fence = fence;
624 623
625 core->SignalDequeueCondition(); 624 core->SignalDequeueCondition();
626 buffer_wait_event->GetWritableEvent().Signal(); 625 buffer_wait_event->Signal();
627} 626}
628 627
629Status BufferQueueProducer::Query(NativeWindow what, s32* out_value) { 628Status BufferQueueProducer::Query(NativeWindow what, s32* out_value) {
@@ -753,7 +752,7 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) {
753 core->connected_producer_listener = nullptr; 752 core->connected_producer_listener = nullptr;
754 core->connected_api = NativeWindowApi::NoConnectedApi; 753 core->connected_api = NativeWindowApi::NoConnectedApi;
755 core->SignalDequeueCondition(); 754 core->SignalDequeueCondition();
756 buffer_wait_event->GetWritableEvent().Signal(); 755 buffer_wait_event->Signal();
757 listener = core->consumer_listener; 756 listener = core->consumer_listener;
758 } else { 757 } else {
759 LOG_ERROR(Service_NVFlinger, "still connected to another api (cur = {} req = {})", 758 LOG_ERROR(Service_NVFlinger, "still connected to another api (cur = {} req = {})",
@@ -802,7 +801,7 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,
802 } 801 }
803 802
804 core->SignalDequeueCondition(); 803 core->SignalDequeueCondition();
805 buffer_wait_event->GetWritableEvent().Signal(); 804 buffer_wait_event->Signal();
806 805
807 return Status::NoError; 806 return Status::NoError;
808} 807}
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.h b/src/core/hle/service/nvflinger/buffer_queue_producer.h
index 0ba03a568..7526bf8ec 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_producer.h
+++ b/src/core/hle/service/nvflinger/buffer_queue_producer.h
@@ -24,7 +24,6 @@ namespace Kernel {
24class KernelCore; 24class KernelCore;
25class KEvent; 25class KEvent;
26class KReadableEvent; 26class KReadableEvent;
27class KWritableEvent;
28} // namespace Kernel 27} // namespace Kernel
29 28
30namespace Service::KernelHelpers { 29namespace Service::KernelHelpers {
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index b62615de2..99509bc5b 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -25,7 +25,6 @@ struct EventType;
25 25
26namespace Kernel { 26namespace Kernel {
27class KReadableEvent; 27class KReadableEvent;
28class KWritableEvent;
29} // namespace Kernel 28} // namespace Kernel
30 29
31namespace Service::Nvidia { 30namespace Service::Nvidia {
diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp
index 2c31e9485..1ac97fe31 100644
--- a/src/core/hle/service/ptm/psm.cpp
+++ b/src/core/hle/service/ptm/psm.cpp
@@ -37,19 +37,19 @@ public:
37 37
38 void SignalChargerTypeChanged() { 38 void SignalChargerTypeChanged() {
39 if (should_signal && should_signal_charger_type) { 39 if (should_signal && should_signal_charger_type) {
40 state_change_event->GetWritableEvent().Signal(); 40 state_change_event->Signal();
41 } 41 }
42 } 42 }
43 43
44 void SignalPowerSupplyChanged() { 44 void SignalPowerSupplyChanged() {
45 if (should_signal && should_signal_power_supply) { 45 if (should_signal && should_signal_power_supply) {
46 state_change_event->GetWritableEvent().Signal(); 46 state_change_event->Signal();
47 } 47 }
48 } 48 }
49 49
50 void SignalBatteryVoltageStateChanged() { 50 void SignalBatteryVoltageStateChanged() {
51 if (should_signal && should_signal_battery_voltage) { 51 if (should_signal && should_signal_battery_voltage) {
52 state_change_event->GetWritableEvent().Signal(); 52 state_change_event->Signal();
53 } 53 }
54 } 54 }
55 55
diff --git a/src/core/hle/service/ptm/ts.cpp b/src/core/hle/service/ptm/ts.cpp
index 65c3f135f..b1a0a5544 100644
--- a/src/core/hle/service/ptm/ts.cpp
+++ b/src/core/hle/service/ptm/ts.cpp
@@ -15,7 +15,7 @@ TS::TS(Core::System& system_) : ServiceFramework{system_, "ts"} {
15 {0, nullptr, "GetTemperatureRange"}, 15 {0, nullptr, "GetTemperatureRange"},
16 {1, &TS::GetTemperature, "GetTemperature"}, 16 {1, &TS::GetTemperature, "GetTemperature"},
17 {2, nullptr, "SetMeasurementMode"}, 17 {2, nullptr, "SetMeasurementMode"},
18 {3, nullptr, "GetTemperatureMilliC"}, 18 {3, &TS::GetTemperatureMilliC, "GetTemperatureMilliC"},
19 {4, nullptr, "OpenSession"}, 19 {4, nullptr, "OpenSession"},
20 }; 20 };
21 // clang-format on 21 // clang-format on
@@ -29,8 +29,6 @@ void TS::GetTemperature(Kernel::HLERequestContext& ctx) {
29 IPC::RequestParser rp{ctx}; 29 IPC::RequestParser rp{ctx};
30 const auto location{rp.PopEnum<Location>()}; 30 const auto location{rp.PopEnum<Location>()};
31 31
32 LOG_WARNING(Service_HID, "(STUBBED) called. location={}", location);
33
34 const s32 temperature = location == Location::Internal ? 35 : 20; 32 const s32 temperature = location == Location::Internal ? 35 : 20;
35 33
36 IPC::ResponseBuilder rb{ctx, 3}; 34 IPC::ResponseBuilder rb{ctx, 3};
@@ -38,4 +36,15 @@ void TS::GetTemperature(Kernel::HLERequestContext& ctx) {
38 rb.Push(temperature); 36 rb.Push(temperature);
39} 37}
40 38
39void TS::GetTemperatureMilliC(Kernel::HLERequestContext& ctx) {
40 IPC::RequestParser rp{ctx};
41 const auto location{rp.PopEnum<Location>()};
42
43 const s32 temperature = location == Location::Internal ? 35000 : 20000;
44
45 IPC::ResponseBuilder rb{ctx, 3};
46 rb.Push(ResultSuccess);
47 rb.Push(temperature);
48}
49
41} // namespace Service::PTM 50} // namespace Service::PTM
diff --git a/src/core/hle/service/ptm/ts.h b/src/core/hle/service/ptm/ts.h
index 39a734ef7..39d51847e 100644
--- a/src/core/hle/service/ptm/ts.h
+++ b/src/core/hle/service/ptm/ts.h
@@ -20,6 +20,7 @@ private:
20 }; 20 };
21 21
22 void GetTemperature(Kernel::HLERequestContext& ctx); 22 void GetTemperature(Kernel::HLERequestContext& ctx);
23 void GetTemperatureMilliC(Kernel::HLERequestContext& ctx);
23}; 24};
24 25
25} // namespace Service::PTM 26} // namespace Service::PTM
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp
index 2a0b812c1..d7cea6aac 100644
--- a/src/core/hle/service/set/set_sys.cpp
+++ b/src/core/hle/service/set/set_sys.cpp
@@ -101,6 +101,81 @@ void SET_SYS::SetColorSetId(Kernel::HLERequestContext& ctx) {
101 rb.Push(ResultSuccess); 101 rb.Push(ResultSuccess);
102} 102}
103 103
104// FIXME: implement support for the real system_settings.ini
105
106template <typename T>
107static std::vector<u8> ToBytes(const T& value) {
108 static_assert(std::is_trivially_copyable_v<T>);
109
110 const auto* begin = reinterpret_cast<const u8*>(&value);
111 const auto* end = begin + sizeof(T);
112
113 return std::vector<u8>(begin, end);
114}
115
116using Settings =
117 std::map<std::string, std::map<std::string, std::vector<u8>, std::less<>>, std::less<>>;
118
119static Settings GetSettings() {
120 Settings ret;
121
122 ret["hbloader"]["applet_heap_size"] = ToBytes(u64{0x0});
123 ret["hbloader"]["applet_heap_reservation_size"] = ToBytes(u64{0x8600000});
124
125 return ret;
126}
127
128void SET_SYS::GetSettingsItemValueSize(Kernel::HLERequestContext& ctx) {
129 LOG_DEBUG(Service_SET, "called");
130
131 // The category of the setting. This corresponds to the top-level keys of
132 // system_settings.ini.
133 const auto setting_category_buf{ctx.ReadBuffer(0)};
134 const std::string setting_category{setting_category_buf.begin(), setting_category_buf.end()};
135
136 // The name of the setting. This corresponds to the second-level keys of
137 // system_settings.ini.
138 const auto setting_name_buf{ctx.ReadBuffer(1)};
139 const std::string setting_name{setting_name_buf.begin(), setting_name_buf.end()};
140
141 auto settings{GetSettings()};
142 u64 response_size{0};
143
144 if (settings.contains(setting_category) && settings[setting_category].contains(setting_name)) {
145 response_size = settings[setting_category][setting_name].size();
146 }
147
148 IPC::ResponseBuilder rb{ctx, 4};
149 rb.Push(response_size == 0 ? ResultUnknown : ResultSuccess);
150 rb.Push(response_size);
151}
152
153void SET_SYS::GetSettingsItemValue(Kernel::HLERequestContext& ctx) {
154 LOG_DEBUG(Service_SET, "called");
155
156 // The category of the setting. This corresponds to the top-level keys of
157 // system_settings.ini.
158 const auto setting_category_buf{ctx.ReadBuffer(0)};
159 const std::string setting_category{setting_category_buf.begin(), setting_category_buf.end()};
160
161 // The name of the setting. This corresponds to the second-level keys of
162 // system_settings.ini.
163 const auto setting_name_buf{ctx.ReadBuffer(1)};
164 const std::string setting_name{setting_name_buf.begin(), setting_name_buf.end()};
165
166 auto settings{GetSettings()};
167 Result response{ResultUnknown};
168
169 if (settings.contains(setting_category) && settings[setting_category].contains(setting_name)) {
170 auto setting_value = settings[setting_category][setting_name];
171 ctx.WriteBuffer(setting_value.data(), setting_value.size());
172 response = ResultSuccess;
173 }
174
175 IPC::ResponseBuilder rb{ctx, 2};
176 rb.Push(response);
177}
178
104SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { 179SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
105 // clang-format off 180 // clang-format off
106 static const FunctionInfo functions[] = { 181 static const FunctionInfo functions[] = {
@@ -138,8 +213,8 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
138 {32, nullptr, "SetAccountNotificationSettings"}, 213 {32, nullptr, "SetAccountNotificationSettings"},
139 {35, nullptr, "GetVibrationMasterVolume"}, 214 {35, nullptr, "GetVibrationMasterVolume"},
140 {36, nullptr, "SetVibrationMasterVolume"}, 215 {36, nullptr, "SetVibrationMasterVolume"},
141 {37, nullptr, "GetSettingsItemValueSize"}, 216 {37, &SET_SYS::GetSettingsItemValueSize, "GetSettingsItemValueSize"},
142 {38, nullptr, "GetSettingsItemValue"}, 217 {38, &SET_SYS::GetSettingsItemValue, "GetSettingsItemValue"},
143 {39, nullptr, "GetTvSettings"}, 218 {39, nullptr, "GetTvSettings"},
144 {40, nullptr, "SetTvSettings"}, 219 {40, nullptr, "SetTvSettings"},
145 {41, nullptr, "GetEdid"}, 220 {41, nullptr, "GetEdid"},
diff --git a/src/core/hle/service/set/set_sys.h b/src/core/hle/service/set/set_sys.h
index ac97772b7..258ef8c57 100644
--- a/src/core/hle/service/set/set_sys.h
+++ b/src/core/hle/service/set/set_sys.h
@@ -23,6 +23,8 @@ private:
23 BasicBlack = 1, 23 BasicBlack = 1,
24 }; 24 };
25 25
26 void GetSettingsItemValueSize(Kernel::HLERequestContext& ctx);
27 void GetSettingsItemValue(Kernel::HLERequestContext& ctx);
26 void GetFirmwareVersion(Kernel::HLERequestContext& ctx); 28 void GetFirmwareVersion(Kernel::HLERequestContext& ctx);
27 void GetFirmwareVersion2(Kernel::HLERequestContext& ctx); 29 void GetFirmwareVersion2(Kernel::HLERequestContext& ctx);
28 void GetColorSetId(Kernel::HLERequestContext& ctx); 30 void GetColorSetId(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index 246c94623..48e70f93c 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -156,7 +156,8 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&
156 156
157 // Create a new session. 157 // Create a new session.
158 Kernel::KClientSession* session{}; 158 Kernel::KClientSession* session{};
159 if (const auto result = port->GetClientPort().CreateSession(std::addressof(session)); 159 if (const auto result = port->GetClientPort().CreateSession(
160 std::addressof(session), std::make_shared<Kernel::SessionRequestManager>(kernel));
160 result.IsError()) { 161 result.IsError()) {
161 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw); 162 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw);
162 return result; 163 return result;
diff --git a/src/core/hle/service/time/system_clock_context_update_callback.cpp b/src/core/hle/service/time/system_clock_context_update_callback.cpp
index a649bed3a..cafc04ee7 100644
--- a/src/core/hle/service/time/system_clock_context_update_callback.cpp
+++ b/src/core/hle/service/time/system_clock_context_update_callback.cpp
@@ -1,7 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/kernel/k_writable_event.h" 4#include "core/hle/kernel/k_event.h"
5#include "core/hle/service/time/errors.h" 5#include "core/hle/service/time/errors.h"
6#include "core/hle/service/time/system_clock_context_update_callback.h" 6#include "core/hle/service/time/system_clock_context_update_callback.h"
7 7
@@ -20,13 +20,13 @@ bool SystemClockContextUpdateCallback::NeedUpdate(const SystemClockContext& valu
20} 20}
21 21
22void SystemClockContextUpdateCallback::RegisterOperationEvent( 22void SystemClockContextUpdateCallback::RegisterOperationEvent(
23 std::shared_ptr<Kernel::KWritableEvent>&& writable_event) { 23 std::shared_ptr<Kernel::KEvent>&& event) {
24 operation_event_list.emplace_back(std::move(writable_event)); 24 operation_event_list.emplace_back(std::move(event));
25} 25}
26 26
27void SystemClockContextUpdateCallback::BroadcastOperationEvent() { 27void SystemClockContextUpdateCallback::BroadcastOperationEvent() {
28 for (const auto& writable_event : operation_event_list) { 28 for (const auto& event : operation_event_list) {
29 writable_event->Signal(); 29 event->Signal();
30 } 30 }
31} 31}
32 32
diff --git a/src/core/hle/service/time/system_clock_context_update_callback.h b/src/core/hle/service/time/system_clock_context_update_callback.h
index 9c6caf196..bf657acd9 100644
--- a/src/core/hle/service/time/system_clock_context_update_callback.h
+++ b/src/core/hle/service/time/system_clock_context_update_callback.h
@@ -9,7 +9,7 @@
9#include "core/hle/service/time/clock_types.h" 9#include "core/hle/service/time/clock_types.h"
10 10
11namespace Kernel { 11namespace Kernel {
12class KWritableEvent; 12class KEvent;
13} 13}
14 14
15namespace Service::Time::Clock { 15namespace Service::Time::Clock {
@@ -24,7 +24,7 @@ public:
24 24
25 bool NeedUpdate(const SystemClockContext& value) const; 25 bool NeedUpdate(const SystemClockContext& value) const;
26 26
27 void RegisterOperationEvent(std::shared_ptr<Kernel::KWritableEvent>&& writable_event); 27 void RegisterOperationEvent(std::shared_ptr<Kernel::KEvent>&& event);
28 28
29 void BroadcastOperationEvent(); 29 void BroadcastOperationEvent();
30 30
@@ -37,7 +37,7 @@ protected:
37 37
38private: 38private:
39 bool has_context{}; 39 bool has_context{};
40 std::vector<std::shared_ptr<Kernel::KWritableEvent>> operation_event_list; 40 std::vector<std::shared_ptr<Kernel::KEvent>> operation_event_list;
41}; 41};
42 42
43} // namespace Service::Time::Clock 43} // namespace Service::Time::Clock
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp
index 288aafaaf..8ef74f1f0 100644
--- a/src/core/hle/service/vi/display/vi_display.cpp
+++ b/src/core/hle/service/vi/display/vi_display.cpp
@@ -10,7 +10,6 @@
10#include "core/core.h" 10#include "core/core.h"
11#include "core/hle/kernel/k_event.h" 11#include "core/hle/kernel/k_event.h"
12#include "core/hle/kernel/k_readable_event.h" 12#include "core/hle/kernel/k_readable_event.h"
13#include "core/hle/kernel/k_writable_event.h"
14#include "core/hle/service/kernel_helpers.h" 13#include "core/hle/service/kernel_helpers.h"
15#include "core/hle/service/nvdrv/core/container.h" 14#include "core/hle/service/nvdrv/core/container.h"
16#include "core/hle/service/nvflinger/buffer_item_consumer.h" 15#include "core/hle/service/nvflinger/buffer_item_consumer.h"
@@ -74,7 +73,7 @@ Kernel::KReadableEvent* Display::GetVSyncEventUnchecked() {
74} 73}
75 74
76void Display::SignalVSyncEvent() { 75void Display::SignalVSyncEvent() {
77 vsync_event->GetWritableEvent().Signal(); 76 vsync_event->Signal();
78} 77}
79 78
80void Display::CreateLayer(u64 layer_id, u32 binder_id, 79void Display::CreateLayer(u64 layer_id, u32 binder_id,
diff --git a/src/core/hle/service/vi/vi_results.h b/src/core/hle/service/vi/vi_results.h
index a46c247d2..22bac799f 100644
--- a/src/core/hle/service/vi/vi_results.h
+++ b/src/core/hle/service/vi/vi_results.h
@@ -1,6 +1,8 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#pragma once
5
4#include "core/hle/result.h" 6#include "core/hle/result.h"
5 7
6namespace Service::VI { 8namespace Service::VI {
diff --git a/src/video_core/texture_cache/descriptor_table.h b/src/video_core/texture_cache/descriptor_table.h
index b18e3838f..ee4240288 100644
--- a/src/video_core/texture_cache/descriptor_table.h
+++ b/src/video_core/texture_cache/descriptor_table.h
@@ -18,7 +18,7 @@ class DescriptorTable {
18public: 18public:
19 explicit DescriptorTable(Tegra::MemoryManager& gpu_memory_) : gpu_memory{gpu_memory_} {} 19 explicit DescriptorTable(Tegra::MemoryManager& gpu_memory_) : gpu_memory{gpu_memory_} {}
20 20
21 [[nodiscard]] bool Synchornize(GPUVAddr gpu_addr, u32 limit) { 21 [[nodiscard]] bool Synchronize(GPUVAddr gpu_addr, u32 limit) {
22 [[likely]] if (current_gpu_addr == gpu_addr && current_limit == limit) { 22 [[likely]] if (current_gpu_addr == gpu_addr && current_limit == limit) {
23 return false; 23 return false;
24 } 24 }
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 413baf730..0e0fd410f 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -193,11 +193,11 @@ void TextureCache<P>::SynchronizeGraphicsDescriptors() {
193 const bool linked_tsc = maxwell3d->regs.sampler_binding == SamplerBinding::ViaHeaderBinding; 193 const bool linked_tsc = maxwell3d->regs.sampler_binding == SamplerBinding::ViaHeaderBinding;
194 const u32 tic_limit = maxwell3d->regs.tex_header.limit; 194 const u32 tic_limit = maxwell3d->regs.tex_header.limit;
195 const u32 tsc_limit = linked_tsc ? tic_limit : maxwell3d->regs.tex_sampler.limit; 195 const u32 tsc_limit = linked_tsc ? tic_limit : maxwell3d->regs.tex_sampler.limit;
196 if (channel_state->graphics_sampler_table.Synchornize(maxwell3d->regs.tex_sampler.Address(), 196 if (channel_state->graphics_sampler_table.Synchronize(maxwell3d->regs.tex_sampler.Address(),
197 tsc_limit)) { 197 tsc_limit)) {
198 channel_state->graphics_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID); 198 channel_state->graphics_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID);
199 } 199 }
200 if (channel_state->graphics_image_table.Synchornize(maxwell3d->regs.tex_header.Address(), 200 if (channel_state->graphics_image_table.Synchronize(maxwell3d->regs.tex_header.Address(),
201 tic_limit)) { 201 tic_limit)) {
202 channel_state->graphics_image_view_ids.resize(tic_limit + 1, CORRUPT_ID); 202 channel_state->graphics_image_view_ids.resize(tic_limit + 1, CORRUPT_ID);
203 } 203 }
@@ -209,10 +209,10 @@ void TextureCache<P>::SynchronizeComputeDescriptors() {
209 const u32 tic_limit = kepler_compute->regs.tic.limit; 209 const u32 tic_limit = kepler_compute->regs.tic.limit;
210 const u32 tsc_limit = linked_tsc ? tic_limit : kepler_compute->regs.tsc.limit; 210 const u32 tsc_limit = linked_tsc ? tic_limit : kepler_compute->regs.tsc.limit;
211 const GPUVAddr tsc_gpu_addr = kepler_compute->regs.tsc.Address(); 211 const GPUVAddr tsc_gpu_addr = kepler_compute->regs.tsc.Address();
212 if (channel_state->compute_sampler_table.Synchornize(tsc_gpu_addr, tsc_limit)) { 212 if (channel_state->compute_sampler_table.Synchronize(tsc_gpu_addr, tsc_limit)) {
213 channel_state->compute_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID); 213 channel_state->compute_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID);
214 } 214 }
215 if (channel_state->compute_image_table.Synchornize(kepler_compute->regs.tic.Address(), 215 if (channel_state->compute_image_table.Synchronize(kepler_compute->regs.tic.Address(),
216 tic_limit)) { 216 tic_limit)) {
217 channel_state->compute_image_view_ids.resize(tic_limit + 1, CORRUPT_ID); 217 channel_state->compute_image_view_ids.resize(tic_limit + 1, CORRUPT_ID);
218 } 218 }
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index f45a25410..a94624be6 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -3280,7 +3280,7 @@ void GMainWindow::LoadAmiibo(const QString& filename) {
3280 QMessageBox::warning(this, title, tr("The current game is not looking for amiibos")); 3280 QMessageBox::warning(this, title, tr("The current game is not looking for amiibos"));
3281 break; 3281 break;
3282 case InputCommon::VirtualAmiibo::Info::Unknown: 3282 case InputCommon::VirtualAmiibo::Info::Unknown:
3283 QMessageBox::warning(this, title, tr("An unkown error occured")); 3283 QMessageBox::warning(this, title, tr("An unknown error occurred"));
3284 break; 3284 break;
3285 default: 3285 default:
3286 break; 3286 break;