summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x.ci/scripts/windows/docker.sh11
-rw-r--r--src/common/fs/file.cpp4
-rw-r--r--src/common/fs/file.h12
-rw-r--r--src/common/fs/fs.cpp5
-rw-r--r--src/common/fs/fs.h30
-rw-r--r--src/common/logging/backend.cpp4
-rw-r--r--src/core/CMakeLists.txt3
-rw-r--r--src/core/core.cpp5
-rw-r--r--src/core/file_sys/system_archive/system_version.cpp48
-rw-r--r--src/core/file_sys/vfs_real.cpp7
-rw-r--r--src/core/hle/api_version.h38
-rw-r--r--src/core/hle/kernel/k_resource_limit.cpp1
-rw-r--r--src/core/hle/service/bcat/backend/boxcat.cpp4
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp4
-rw-r--r--src/core/hle/service/hid/controllers/npad.h4
-rw-r--r--src/core/hle/service/spl/csrng.cpp2
-rw-r--r--src/core/hle/service/spl/module.cpp124
-rw-r--r--src/core/hle/service/spl/module.h13
-rw-r--r--src/core/hle/service/spl/spl.cpp84
-rw-r--r--src/core/hle/service/spl/spl_results.h29
-rw-r--r--src/core/hle/service/spl/spl_types.h230
-rw-r--r--src/core/hle/service/time/time_zone_content_manager.cpp2
-rw-r--r--src/input_common/mouse/mouse_input.cpp16
-rw-r--r--src/input_common/mouse/mouse_input.h6
-rw-r--r--src/video_core/renderer_vulkan/vk_master_semaphore.cpp18
-rw-r--r--src/video_core/renderer_vulkan/vk_master_semaphore.h9
-rw-r--r--src/video_core/vulkan_common/nsight_aftermath_tracker.cpp2
-rw-r--r--src/yuzu/configuration/configure_per_game_addons.cpp4
-rw-r--r--src/yuzu/main.cpp24
29 files changed, 578 insertions, 165 deletions
diff --git a/.ci/scripts/windows/docker.sh b/.ci/scripts/windows/docker.sh
index feba3fd6e..155d8a5c8 100755
--- a/.ci/scripts/windows/docker.sh
+++ b/.ci/scripts/windows/docker.sh
@@ -18,19 +18,20 @@ cd ..
mkdir package
if [ -d "/usr/x86_64-w64-mingw32/lib/qt5/plugins/platforms/" ]; then
- QT_PLATFORM_DLL_PATH='/usr/x86_64-w64-mingw32/lib/qt5/plugins/platforms/'
+ QT_PLUGINS_PATH='/usr/x86_64-w64-mingw32/lib/qt5/plugins'
else
#fallback to qt
- QT_PLATFORM_DLL_PATH='/usr/x86_64-w64-mingw32/lib/qt/plugins/platforms/'
+ QT_PLUGINS_PATH='/usr/x86_64-w64-mingw32/lib/qt/plugins'
fi
find build/ -name "yuzu*.exe" -exec cp {} 'package' \;
# copy Qt plugins
mkdir package/platforms
-cp "${QT_PLATFORM_DLL_PATH}/qwindows.dll" package/platforms/
-cp -rv "${QT_PLATFORM_DLL_PATH}/../mediaservice/" package/
-cp -rv "${QT_PLATFORM_DLL_PATH}/../imageformats/" package/
+cp -v "${QT_PLUGINS_PATH}/platforms/qwindows.dll" package/platforms/
+cp -rv "${QT_PLUGINS_PATH}/mediaservice/" package/
+cp -rv "${QT_PLUGINS_PATH}/imageformats/" package/
+cp -rv "${QT_PLUGINS_PATH}/styles/" package/
rm -f package/mediaservice/*d.dll
for i in package/*.exe; do
diff --git a/src/common/fs/file.cpp b/src/common/fs/file.cpp
index 710e88b39..077f34995 100644
--- a/src/common/fs/file.cpp
+++ b/src/common/fs/file.cpp
@@ -172,7 +172,7 @@ std::string ReadStringFromFile(const std::filesystem::path& path, FileType type)
size_t WriteStringToFile(const std::filesystem::path& path, FileType type,
std::string_view string) {
- if (!IsFile(path)) {
+ if (Exists(path) && !IsFile(path)) {
return 0;
}
@@ -183,7 +183,7 @@ size_t WriteStringToFile(const std::filesystem::path& path, FileType type,
size_t AppendStringToFile(const std::filesystem::path& path, FileType type,
std::string_view string) {
- if (!IsFile(path)) {
+ if (Exists(path) && !IsFile(path)) {
return 0;
}
diff --git a/src/common/fs/file.h b/src/common/fs/file.h
index 0f10b6003..588fe619d 100644
--- a/src/common/fs/file.h
+++ b/src/common/fs/file.h
@@ -49,7 +49,7 @@ void OpenFileStream(FileStream& file_stream, const Path& path, std::ios_base::op
/**
* Reads an entire file at path and returns a string of the contents read from the file.
- * If the filesystem object at path is not a file, this function returns an empty string.
+ * If the filesystem object at path is not a regular file, this function returns an empty string.
*
* @param path Filesystem path
* @param type File type
@@ -72,7 +72,8 @@ template <typename Path>
/**
* Writes a string to a file at path and returns the number of characters successfully written.
* If a file already exists at path, its contents will be erased.
- * If the filesystem object at path is not a file, this function returns 0.
+ * If a file does not exist at path, it creates and opens a new empty file for writing.
+ * If the filesystem object at path exists and is not a regular file, this function returns 0.
*
* @param path Filesystem path
* @param type File type
@@ -95,7 +96,8 @@ template <typename Path>
/**
* Appends a string to a file at path and returns the number of characters successfully written.
- * If the filesystem object at path is not a file, this function returns 0.
+ * If a file does not exist at path, it creates and opens a new empty file for appending.
+ * If the filesystem object at path exists and is not a regular file, this function returns 0.
*
* @param path Filesystem path
* @param type File type
@@ -394,11 +396,11 @@ public:
[[nodiscard]] size_t WriteString(std::span<const char> string) const;
/**
- * Flushes any unwritten buffered data into the file.
+ * Attempts to flush any unwritten buffered data into the file and flush the file into the disk.
*
* @returns True if the flush was successful, false otherwise.
*/
- [[nodiscard]] bool Flush() const;
+ bool Flush() const;
/**
* Resizes the file to a given size.
diff --git a/src/common/fs/fs.cpp b/src/common/fs/fs.cpp
index d3159e908..9089cad67 100644
--- a/src/common/fs/fs.cpp
+++ b/src/common/fs/fs.cpp
@@ -135,8 +135,9 @@ std::shared_ptr<IOFile> FileOpen(const fs::path& path, FileAccessMode mode, File
return nullptr;
}
- if (!IsFile(path)) {
- LOG_ERROR(Common_Filesystem, "Filesystem object at path={} is not a file",
+ if (Exists(path) && !IsFile(path)) {
+ LOG_ERROR(Common_Filesystem,
+ "Filesystem object at path={} exists and is not a regular file",
PathToUTF8String(path));
return nullptr;
}
diff --git a/src/common/fs/fs.h b/src/common/fs/fs.h
index f6f256349..183126de3 100644
--- a/src/common/fs/fs.h
+++ b/src/common/fs/fs.h
@@ -48,18 +48,18 @@ template <typename Path>
*
* Failures occur when:
* - Input path is not valid
- * - Filesystem object at path is not a file
+ * - Filesystem object at path is not a regular file
* - Filesystem at path is read only
*
* @param path Filesystem path
*
* @returns True if file removal succeeds or file does not exist, false otherwise.
*/
-[[nodiscard]] bool RemoveFile(const std::filesystem::path& path);
+bool RemoveFile(const std::filesystem::path& path);
#ifdef _WIN32
template <typename Path>
-[[nodiscard]] bool RemoveFile(const Path& path) {
+bool RemoveFile(const Path& path) {
if constexpr (IsChar<typename Path::value_type>) {
return RemoveFile(ToU8String(path));
} else {
@@ -74,7 +74,7 @@ template <typename Path>
* Failures occur when:
* - One or both input path(s) is not valid
* - Filesystem object at old_path does not exist
- * - Filesystem object at old_path is not a file
+ * - Filesystem object at old_path is not a regular file
* - Filesystem object at new_path exists
* - Filesystem at either path is read only
*
@@ -110,8 +110,8 @@ template <typename Path1, typename Path2>
*
* Failures occur when:
* - Input path is not valid
- * - Filesystem object at path is not a file
- * - The file is not opened
+ * - Filesystem object at path exists and is not a regular file
+ * - The file is not open
*
* @param path Filesystem path
* @param mode File access mode
@@ -251,11 +251,11 @@ template <typename Path>
*
* @returns True if directory removal succeeds or directory does not exist, false otherwise.
*/
-[[nodiscard]] bool RemoveDir(const std::filesystem::path& path);
+bool RemoveDir(const std::filesystem::path& path);
#ifdef _WIN32
template <typename Path>
-[[nodiscard]] bool RemoveDir(const Path& path) {
+bool RemoveDir(const Path& path) {
if constexpr (IsChar<typename Path::value_type>) {
return RemoveDir(ToU8String(path));
} else {
@@ -276,11 +276,11 @@ template <typename Path>
*
* @returns True if the directory and all of its contents are removed successfully, false otherwise.
*/
-[[nodiscard]] bool RemoveDirRecursively(const std::filesystem::path& path);
+bool RemoveDirRecursively(const std::filesystem::path& path);
#ifdef _WIN32
template <typename Path>
-[[nodiscard]] bool RemoveDirRecursively(const Path& path) {
+bool RemoveDirRecursively(const Path& path) {
if constexpr (IsChar<typename Path::value_type>) {
return RemoveDirRecursively(ToU8String(path));
} else {
@@ -301,11 +301,11 @@ template <typename Path>
*
* @returns True if all of the directory's contents are removed successfully, false otherwise.
*/
-[[nodiscard]] bool RemoveDirContentsRecursively(const std::filesystem::path& path);
+bool RemoveDirContentsRecursively(const std::filesystem::path& path);
#ifdef _WIN32
template <typename Path>
-[[nodiscard]] bool RemoveDirContentsRecursively(const Path& path) {
+bool RemoveDirContentsRecursively(const Path& path) {
if constexpr (IsChar<typename Path::value_type>) {
return RemoveDirContentsRecursively(ToU8String(path));
} else {
@@ -435,11 +435,13 @@ template <typename Path>
#endif
/**
- * Returns whether a filesystem object at path is a file.
+ * Returns whether a filesystem object at path is a regular file.
+ * A regular file is a file that stores text or binary data.
+ * It is not a directory, symlink, FIFO, socket, block device, or character device.
*
* @param path Filesystem path
*
- * @returns True if a filesystem object at path is a file, false otherwise.
+ * @returns True if a filesystem object at path is a regular file, false otherwise.
*/
[[nodiscard]] bool IsFile(const std::filesystem::path& path);
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index d5cff400f..47ce06478 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -159,7 +159,7 @@ FileBackend::FileBackend(const std::filesystem::path& filename) {
// Existence checks are done within the functions themselves.
// We don't particularly care if these succeed or not.
- void(FS::RemoveFile(old_filename));
+ FS::RemoveFile(old_filename);
void(FS::RenameFile(filename, old_filename));
file =
@@ -186,7 +186,7 @@ void FileBackend::Write(const Entry& entry) {
bytes_written += file->WriteString(FormatLogMessage(entry).append(1, '\n'));
if (entry.log_level >= Level::Error) {
- void(file->Flush());
+ file->Flush();
}
}
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index efb851f5a..83b5b7676 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -139,6 +139,7 @@ add_library(core STATIC
frontend/input.h
hardware_interrupt_manager.cpp
hardware_interrupt_manager.h
+ hle/api_version.h
hle/ipc.h
hle/ipc_helpers.h
hle/kernel/board/nintendo/nx/k_system_control.cpp
@@ -550,6 +551,8 @@ add_library(core STATIC
hle/service/spl/module.h
hle/service/spl/spl.cpp
hle/service/spl/spl.h
+ hle/service/spl/spl_results.h
+ hle/service/spl/spl_types.h
hle/service/ssl/ssl.cpp
hle/service/ssl/ssl.h
hle/service/time/clock_types.h
diff --git a/src/core/core.cpp b/src/core/core.cpp
index c5004b7b4..e6f1aa0e7 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include <array>
+#include <atomic>
#include <memory>
#include <utility>
@@ -377,7 +378,7 @@ struct System::Impl {
std::unique_ptr<Core::DeviceMemory> device_memory;
Core::Memory::Memory memory;
CpuManager cpu_manager;
- bool is_powered_on = false;
+ std::atomic_bool is_powered_on{};
bool exit_lock = false;
Reporter reporter;
@@ -463,7 +464,7 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
}
bool System::IsPoweredOn() const {
- return impl->is_powered_on;
+ return impl->is_powered_on.load(std::memory_order::relaxed);
}
void System::PrepareReschedule() {
diff --git a/src/core/file_sys/system_archive/system_version.cpp b/src/core/file_sys/system_archive/system_version.cpp
index 54704105b..9b76d007e 100644
--- a/src/core/file_sys/system_archive/system_version.cpp
+++ b/src/core/file_sys/system_archive/system_version.cpp
@@ -4,47 +4,29 @@
#include "core/file_sys/system_archive/system_version.h"
#include "core/file_sys/vfs_vector.h"
+#include "core/hle/api_version.h"
namespace FileSys::SystemArchive {
-namespace SystemVersionData {
-
-// This section should reflect the best system version to describe yuzu's HLE api.
-// TODO(DarkLordZach): Update when HLE gets better.
-
-constexpr u8 VERSION_MAJOR = 11;
-constexpr u8 VERSION_MINOR = 0;
-constexpr u8 VERSION_MICRO = 1;
-
-constexpr u8 REVISION_MAJOR = 1;
-constexpr u8 REVISION_MINOR = 0;
-
-constexpr char PLATFORM_STRING[] = "NX";
-constexpr char VERSION_HASH[] = "69103fcb2004dace877094c2f8c29e6113be5dbf";
-constexpr char DISPLAY_VERSION[] = "11.0.1";
-constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 11.0.1-1.0";
-
-} // namespace SystemVersionData
-
std::string GetLongDisplayVersion() {
- return SystemVersionData::DISPLAY_TITLE;
+ return HLE::ApiVersion::DISPLAY_TITLE;
}
VirtualDir SystemVersion() {
VirtualFile file = std::make_shared<VectorVfsFile>(std::vector<u8>(0x100), "file");
- file->WriteObject(SystemVersionData::VERSION_MAJOR, 0);
- file->WriteObject(SystemVersionData::VERSION_MINOR, 1);
- file->WriteObject(SystemVersionData::VERSION_MICRO, 2);
- file->WriteObject(SystemVersionData::REVISION_MAJOR, 4);
- file->WriteObject(SystemVersionData::REVISION_MINOR, 5);
- file->WriteArray(SystemVersionData::PLATFORM_STRING,
- std::min<u64>(sizeof(SystemVersionData::PLATFORM_STRING), 0x20ULL), 0x8);
- file->WriteArray(SystemVersionData::VERSION_HASH,
- std::min<u64>(sizeof(SystemVersionData::VERSION_HASH), 0x40ULL), 0x28);
- file->WriteArray(SystemVersionData::DISPLAY_VERSION,
- std::min<u64>(sizeof(SystemVersionData::DISPLAY_VERSION), 0x18ULL), 0x68);
- file->WriteArray(SystemVersionData::DISPLAY_TITLE,
- std::min<u64>(sizeof(SystemVersionData::DISPLAY_TITLE), 0x80ULL), 0x80);
+ file->WriteObject(HLE::ApiVersion::HOS_VERSION_MAJOR, 0);
+ file->WriteObject(HLE::ApiVersion::HOS_VERSION_MINOR, 1);
+ file->WriteObject(HLE::ApiVersion::HOS_VERSION_MICRO, 2);
+ file->WriteObject(HLE::ApiVersion::SDK_REVISION_MAJOR, 4);
+ file->WriteObject(HLE::ApiVersion::SDK_REVISION_MINOR, 5);
+ file->WriteArray(HLE::ApiVersion::PLATFORM_STRING,
+ std::min<u64>(sizeof(HLE::ApiVersion::PLATFORM_STRING), 0x20ULL), 0x8);
+ file->WriteArray(HLE::ApiVersion::VERSION_HASH,
+ std::min<u64>(sizeof(HLE::ApiVersion::VERSION_HASH), 0x40ULL), 0x28);
+ file->WriteArray(HLE::ApiVersion::DISPLAY_VERSION,
+ std::min<u64>(sizeof(HLE::ApiVersion::DISPLAY_VERSION), 0x18ULL), 0x68);
+ file->WriteArray(HLE::ApiVersion::DISPLAY_TITLE,
+ std::min<u64>(sizeof(HLE::ApiVersion::DISPLAY_TITLE), 0x80ULL), 0x80);
return std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{file},
std::vector<VirtualDir>{}, "data");
}
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp
index d0b8fd046..3dad54f49 100644
--- a/src/core/file_sys/vfs_real.cpp
+++ b/src/core/file_sys/vfs_real.cpp
@@ -24,17 +24,12 @@ constexpr FS::FileAccessMode ModeFlagsToFileAccessMode(Mode mode) {
case Mode::Read:
return FS::FileAccessMode::Read;
case Mode::Write:
- return FS::FileAccessMode::Write;
case Mode::ReadWrite:
- return FS::FileAccessMode::ReadWrite;
case Mode::Append:
- return FS::FileAccessMode::Append;
case Mode::ReadAppend:
- return FS::FileAccessMode::ReadAppend;
case Mode::WriteAppend:
- return FS::FileAccessMode::Append;
case Mode::All:
- return FS::FileAccessMode::ReadAppend;
+ return FS::FileAccessMode::ReadWrite;
default:
return {};
}
diff --git a/src/core/hle/api_version.h b/src/core/hle/api_version.h
new file mode 100644
index 000000000..811732179
--- /dev/null
+++ b/src/core/hle/api_version.h
@@ -0,0 +1,38 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/common_types.h"
+
+// This file contains yuzu's HLE API version constants.
+
+namespace HLE::ApiVersion {
+
+// Horizon OS version constants.
+
+constexpr u8 HOS_VERSION_MAJOR = 11;
+constexpr u8 HOS_VERSION_MINOR = 0;
+constexpr u8 HOS_VERSION_MICRO = 1;
+
+// NintendoSDK version constants.
+
+constexpr u8 SDK_REVISION_MAJOR = 1;
+constexpr u8 SDK_REVISION_MINOR = 0;
+
+constexpr char PLATFORM_STRING[] = "NX";
+constexpr char VERSION_HASH[] = "69103fcb2004dace877094c2f8c29e6113be5dbf";
+constexpr char DISPLAY_VERSION[] = "11.0.1";
+constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 11.0.1-1.0";
+
+// Atmosphere version constants.
+
+constexpr u8 ATMOSPHERE_RELEASE_VERSION_MAJOR = 0;
+constexpr u8 ATMOSPHERE_RELEASE_VERSION_MINOR = 19;
+constexpr u8 ATMOSPHERE_RELEASE_VERSION_MICRO = 4;
+
+constexpr u32 GetTargetFirmware() {
+ return u32{HOS_VERSION_MAJOR} << 24 | u32{HOS_VERSION_MINOR} << 16 |
+ u32{HOS_VERSION_MICRO} << 8 | 0U;
+}
+
+} // namespace HLE::ApiVersion
diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp
index da88f35bc..0c4bba66b 100644
--- a/src/core/hle/kernel/k_resource_limit.cpp
+++ b/src/core/hle/kernel/k_resource_limit.cpp
@@ -79,6 +79,7 @@ ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) {
R_UNLESS(current_values[index] <= value, ResultInvalidState);
limit_values[index] = value;
+ peak_values[index] = current_values[index];
return ResultSuccess;
}
diff --git a/src/core/hle/service/bcat/backend/boxcat.cpp b/src/core/hle/service/bcat/backend/boxcat.cpp
index a2844ea8c..dc15cf58b 100644
--- a/src/core/hle/service/bcat/backend/boxcat.cpp
+++ b/src/core/hle/service/bcat/backend/boxcat.cpp
@@ -313,7 +313,7 @@ void SynchronizeInternal(AM::Applets::AppletManager& applet_manager, DirectoryGe
LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res);
if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) {
- void(Common::FS::RemoveFile(zip_path));
+ Common::FS::RemoveFile(zip_path);
}
HandleDownloadDisplayResult(applet_manager, res);
@@ -445,7 +445,7 @@ std::optional<std::vector<u8>> Boxcat::GetLaunchParameter(TitleIDVersion title)
LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res);
if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) {
- void(Common::FS::RemoveFile(bin_file_path));
+ Common::FS::RemoveFile(bin_file_path);
}
HandleDownloadDisplayResult(applet_manager, res);
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 7acad3798..1eb02aee2 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -314,6 +314,8 @@ void Controller_NPad::OnInit() {
void Controller_NPad::OnLoadInputDevices() {
const auto& players = Settings::values.players.GetValue();
+
+ std::lock_guard lock{mutex};
for (std::size_t i = 0; i < players.size(); ++i) {
std::transform(players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN,
players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_END,
@@ -348,6 +350,8 @@ void Controller_NPad::OnRelease() {
}
void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
+ std::lock_guard lock{mutex};
+
const auto controller_idx = NPadIdToIndex(npad_id);
const auto controller_type = connected_controllers[controller_idx].type;
if (!connected_controllers[controller_idx].is_connected) {
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index c050c9a44..1409d82a2 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -6,6 +6,8 @@
#include <array>
#include <atomic>
+#include <mutex>
+
#include "common/bit_field.h"
#include "common/common_types.h"
#include "common/quaternion.h"
@@ -563,6 +565,8 @@ private:
using MotionArray = std::array<
std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTIONS_HID>,
10>;
+
+ std::mutex mutex;
ButtonArray buttons;
StickArray sticks;
VibrationArray vibrations;
diff --git a/src/core/hle/service/spl/csrng.cpp b/src/core/hle/service/spl/csrng.cpp
index 1beca417c..9c7f89475 100644
--- a/src/core/hle/service/spl/csrng.cpp
+++ b/src/core/hle/service/spl/csrng.cpp
@@ -9,7 +9,7 @@ namespace Service::SPL {
CSRNG::CSRNG(Core::System& system_, std::shared_ptr<Module> module_)
: Interface(system_, std::move(module_), "csrng") {
static const FunctionInfo functions[] = {
- {0, &CSRNG::GetRandomBytes, "GetRandomBytes"},
+ {0, &CSRNG::GenerateRandomBytes, "GenerateRandomBytes"},
};
RegisterHandlers(functions);
}
diff --git a/src/core/hle/service/spl/module.cpp b/src/core/hle/service/spl/module.cpp
index 0b5e2b7c3..ebb179aa8 100644
--- a/src/core/hle/service/spl/module.cpp
+++ b/src/core/hle/service/spl/module.cpp
@@ -10,6 +10,7 @@
#include <vector>
#include "common/logging/log.h"
#include "common/settings.h"
+#include "core/hle/api_version.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/spl/csrng.h"
#include "core/hle/service/spl/module.h"
@@ -24,7 +25,46 @@ Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> modu
Module::Interface::~Interface() = default;
-void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) {
+void Module::Interface::GetConfig(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto config_item = rp.PopEnum<ConfigItem>();
+
+ // This should call svcCallSecureMonitor with the appropriate args.
+ // Since we do not have it implemented yet, we will use this for now.
+ const auto smc_result = GetConfigImpl(config_item);
+ const auto result_code = smc_result.Code();
+
+ if (smc_result.Failed()) {
+ LOG_ERROR(Service_SPL, "called, config_item={}, result_code={}", config_item,
+ result_code.raw);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result_code);
+ }
+
+ LOG_DEBUG(Service_SPL, "called, config_item={}, result_code={}, smc_result={}", config_item,
+ result_code.raw, *smc_result);
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(result_code);
+ rb.Push(*smc_result);
+}
+
+void Module::Interface::ModularExponentiate(Kernel::HLERequestContext& ctx) {
+ UNIMPLEMENTED_MSG("ModularExponentiate is not implemented!");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSecureMonitorNotImplemented);
+}
+
+void Module::Interface::SetConfig(Kernel::HLERequestContext& ctx) {
+ UNIMPLEMENTED_MSG("SetConfig is not implemented!");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSecureMonitorNotImplemented);
+}
+
+void Module::Interface::GenerateRandomBytes(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_SPL, "called");
const std::size_t size = ctx.GetWriteBufferSize();
@@ -39,6 +79,88 @@ void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) {
rb.Push(ResultSuccess);
}
+void Module::Interface::IsDevelopment(Kernel::HLERequestContext& ctx) {
+ UNIMPLEMENTED_MSG("IsDevelopment is not implemented!");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSecureMonitorNotImplemented);
+}
+
+void Module::Interface::SetBootReason(Kernel::HLERequestContext& ctx) {
+ UNIMPLEMENTED_MSG("SetBootReason is not implemented!");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSecureMonitorNotImplemented);
+}
+
+void Module::Interface::GetBootReason(Kernel::HLERequestContext& ctx) {
+ UNIMPLEMENTED_MSG("GetBootReason is not implemented!");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSecureMonitorNotImplemented);
+}
+
+ResultVal<u64> Module::Interface::GetConfigImpl(ConfigItem config_item) const {
+ switch (config_item) {
+ case ConfigItem::DisableProgramVerification:
+ case ConfigItem::DramId:
+ case ConfigItem::SecurityEngineInterruptNumber:
+ case ConfigItem::FuseVersion:
+ case ConfigItem::HardwareType:
+ case ConfigItem::HardwareState:
+ case ConfigItem::IsRecoveryBoot:
+ case ConfigItem::DeviceId:
+ case ConfigItem::BootReason:
+ case ConfigItem::MemoryMode:
+ case ConfigItem::IsDevelopmentFunctionEnabled:
+ case ConfigItem::KernelConfiguration:
+ case ConfigItem::IsChargerHiZModeEnabled:
+ case ConfigItem::QuestState:
+ case ConfigItem::RegulatorType:
+ case ConfigItem::DeviceUniqueKeyGeneration:
+ case ConfigItem::Package2Hash:
+ return ResultSecureMonitorNotImplemented;
+ case ConfigItem::ExosphereApiVersion:
+ // Get information about the current exosphere version.
+ return MakeResult((u64{HLE::ApiVersion::ATMOSPHERE_RELEASE_VERSION_MAJOR} << 56) |
+ (u64{HLE::ApiVersion::ATMOSPHERE_RELEASE_VERSION_MINOR} << 48) |
+ (u64{HLE::ApiVersion::ATMOSPHERE_RELEASE_VERSION_MICRO} << 40) |
+ (static_cast<u64>(HLE::ApiVersion::GetTargetFirmware())));
+ case ConfigItem::ExosphereNeedsReboot:
+ // We are executing, so we aren't in the process of rebooting.
+ return MakeResult(u64{0});
+ case ConfigItem::ExosphereNeedsShutdown:
+ // We are executing, so we aren't in the process of shutting down.
+ return MakeResult(u64{0});
+ case ConfigItem::ExosphereGitCommitHash:
+ // Get information about the current exosphere git commit hash.
+ return MakeResult(u64{0});
+ case ConfigItem::ExosphereHasRcmBugPatch:
+ // Get information about whether this unit has the RCM bug patched.
+ return MakeResult(u64{0});
+ case ConfigItem::ExosphereBlankProdInfo:
+ // Get whether this unit should simulate a "blanked" PRODINFO.
+ return MakeResult(u64{0});
+ case ConfigItem::ExosphereAllowCalWrites:
+ // Get whether this unit should allow writing to the calibration partition.
+ return MakeResult(u64{0});
+ case ConfigItem::ExosphereEmummcType:
+ // Get what kind of emummc this unit has active.
+ return MakeResult(u64{0});
+ case ConfigItem::ExospherePayloadAddress:
+ // Gets the physical address of the reboot payload buffer, if one exists.
+ return ResultSecureMonitorNotInitialized;
+ case ConfigItem::ExosphereLogConfiguration:
+ // Get the log configuration.
+ return MakeResult(u64{0});
+ case ConfigItem::ExosphereForceEnableUsb30:
+ // Get whether usb 3.0 should be force-enabled.
+ return MakeResult(u64{0});
+ default:
+ return ResultSecureMonitorInvalidArgument;
+ }
+}
+
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
auto module = std::make_shared<Module>();
std::make_shared<CSRNG>(system, module)->InstallAsService(service_manager);
diff --git a/src/core/hle/service/spl/module.h b/src/core/hle/service/spl/module.h
index 71855c1bf..61630df80 100644
--- a/src/core/hle/service/spl/module.h
+++ b/src/core/hle/service/spl/module.h
@@ -6,6 +6,8 @@
#include <random>
#include "core/hle/service/service.h"
+#include "core/hle/service/spl/spl_results.h"
+#include "core/hle/service/spl/spl_types.h"
namespace Core {
class System;
@@ -21,12 +23,21 @@ public:
const char* name);
~Interface() override;
- void GetRandomBytes(Kernel::HLERequestContext& ctx);
+ // General
+ void GetConfig(Kernel::HLERequestContext& ctx);
+ void ModularExponentiate(Kernel::HLERequestContext& ctx);
+ void SetConfig(Kernel::HLERequestContext& ctx);
+ void GenerateRandomBytes(Kernel::HLERequestContext& ctx);
+ void IsDevelopment(Kernel::HLERequestContext& ctx);
+ void SetBootReason(Kernel::HLERequestContext& ctx);
+ void GetBootReason(Kernel::HLERequestContext& ctx);
protected:
std::shared_ptr<Module> module;
private:
+ ResultVal<u64> GetConfigImpl(ConfigItem config_item) const;
+
std::mt19937 rng;
};
};
diff --git a/src/core/hle/service/spl/spl.cpp b/src/core/hle/service/spl/spl.cpp
index fff3f3c42..20384042f 100644
--- a/src/core/hle/service/spl/spl.cpp
+++ b/src/core/hle/service/spl/spl.cpp
@@ -10,13 +10,13 @@ SPL::SPL(Core::System& system_, std::shared_ptr<Module> module_)
: Interface(system_, std::move(module_), "spl:") {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "GetConfig"},
- {1, nullptr, "ModularExponentiate"},
- {5, nullptr, "SetConfig"},
- {7, &SPL::GetRandomBytes, "GetRandomBytes"},
- {11, nullptr, "IsDevelopment"},
- {24, nullptr, "SetBootReason"},
- {25, nullptr, "GetBootReason"},
+ {0, &SPL::GetConfig, "GetConfig"},
+ {1, &SPL::ModularExponentiate, "ModularExponentiate"},
+ {5, &SPL::SetConfig, "SetConfig"},
+ {7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
+ {11, &SPL::IsDevelopment, "IsDevelopment"},
+ {24, &SPL::SetBootReason, "SetBootReason"},
+ {25, &SPL::GetBootReason, "GetBootReason"},
};
// clang-format on
@@ -27,22 +27,22 @@ SPL_MIG::SPL_MIG(Core::System& system_, std::shared_ptr<Module> module_)
: Interface(system_, std::move(module_), "spl:mig") {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "GetConfig"},
- {1, nullptr, "ModularExponentiate"},
+ {0, &SPL::GetConfig, "GetConfig"},
+ {1, &SPL::ModularExponentiate, "ModularExponentiate"},
{2, nullptr, "GenerateAesKek"},
{3, nullptr, "LoadAesKey"},
{4, nullptr, "GenerateAesKey"},
- {5, nullptr, "SetConfig"},
- {7, &SPL::GetRandomBytes, "GenerateRandomBytes"},
- {11, nullptr, "IsDevelopment"},
+ {5, &SPL::SetConfig, "SetConfig"},
+ {7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
+ {11, &SPL::IsDevelopment, "IsDevelopment"},
{14, nullptr, "DecryptAesKey"},
{15, nullptr, "CryptAesCtr"},
{16, nullptr, "ComputeCmac"},
{21, nullptr, "AllocateAesKeyslot"},
{22, nullptr, "DeallocateAesKeySlot"},
{23, nullptr, "GetAesKeyslotAvailableEvent"},
- {24, nullptr, "SetBootReason"},
- {25, nullptr, "GetBootReason"},
+ {24, &SPL::SetBootReason, "SetBootReason"},
+ {25, &SPL::GetBootReason, "GetBootReason"},
};
// clang-format on
@@ -53,16 +53,16 @@ SPL_FS::SPL_FS(Core::System& system_, std::shared_ptr<Module> module_)
: Interface(system_, std::move(module_), "spl:fs") {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "GetConfig"},
- {1, nullptr, "ModularExponentiate"},
+ {0, &SPL::GetConfig, "GetConfig"},
+ {1, &SPL::ModularExponentiate, "ModularExponentiate"},
{2, nullptr, "GenerateAesKek"},
{3, nullptr, "LoadAesKey"},
{4, nullptr, "GenerateAesKey"},
- {5, nullptr, "SetConfig"},
- {7, &SPL::GetRandomBytes, "GenerateRandomBytes"},
+ {5, &SPL::SetConfig, "SetConfig"},
+ {7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
{9, nullptr, "ImportLotusKey"},
{10, nullptr, "DecryptLotusMessage"},
- {11, nullptr, "IsDevelopment"},
+ {11, &SPL::IsDevelopment, "IsDevelopment"},
{12, nullptr, "GenerateSpecificAesKey"},
{14, nullptr, "DecryptAesKey"},
{15, nullptr, "CryptAesCtr"},
@@ -71,8 +71,8 @@ SPL_FS::SPL_FS(Core::System& system_, std::shared_ptr<Module> module_)
{21, nullptr, "AllocateAesKeyslot"},
{22, nullptr, "DeallocateAesKeySlot"},
{23, nullptr, "GetAesKeyslotAvailableEvent"},
- {24, nullptr, "SetBootReason"},
- {25, nullptr, "GetBootReason"},
+ {24, &SPL::SetBootReason, "SetBootReason"},
+ {25, &SPL::GetBootReason, "GetBootReason"},
{31, nullptr, "GetPackage2Hash"},
};
// clang-format on
@@ -84,14 +84,14 @@ SPL_SSL::SPL_SSL(Core::System& system_, std::shared_ptr<Module> module_)
: Interface(system_, std::move(module_), "spl:ssl") {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "GetConfig"},
- {1, nullptr, "ModularExponentiate"},
+ {0, &SPL::GetConfig, "GetConfig"},
+ {1, &SPL::ModularExponentiate, "ModularExponentiate"},
{2, nullptr, "GenerateAesKek"},
{3, nullptr, "LoadAesKey"},
{4, nullptr, "GenerateAesKey"},
- {5, nullptr, "SetConfig"},
- {7, &SPL::GetRandomBytes, "GetRandomBytes"},
- {11, nullptr, "IsDevelopment"},
+ {5, &SPL::SetConfig, "SetConfig"},
+ {7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
+ {11, &SPL::IsDevelopment, "IsDevelopment"},
{13, nullptr, "DecryptDeviceUniqueData"},
{14, nullptr, "DecryptAesKey"},
{15, nullptr, "CryptAesCtr"},
@@ -99,8 +99,8 @@ SPL_SSL::SPL_SSL(Core::System& system_, std::shared_ptr<Module> module_)
{21, nullptr, "AllocateAesKeyslot"},
{22, nullptr, "DeallocateAesKeySlot"},
{23, nullptr, "GetAesKeyslotAvailableEvent"},
- {24, nullptr, "SetBootReason"},
- {25, nullptr, "GetBootReason"},
+ {24, &SPL::SetBootReason, "SetBootReason"},
+ {25, &SPL::GetBootReason, "GetBootReason"},
{26, nullptr, "DecryptAndStoreSslClientCertKey"},
{27, nullptr, "ModularExponentiateWithSslClientCertKey"},
};
@@ -113,14 +113,14 @@ SPL_ES::SPL_ES(Core::System& system_, std::shared_ptr<Module> module_)
: Interface(system_, std::move(module_), "spl:es") {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "GetConfig"},
- {1, nullptr, "ModularExponentiate"},
+ {0, &SPL::GetConfig, "GetConfig"},
+ {1, &SPL::ModularExponentiate, "ModularExponentiate"},
{2, nullptr, "GenerateAesKek"},
{3, nullptr, "LoadAesKey"},
{4, nullptr, "GenerateAesKey"},
- {5, nullptr, "SetConfig"},
- {7, &SPL::GetRandomBytes, "GenerateRandomBytes"},
- {11, nullptr, "IsDevelopment"},
+ {5, &SPL::SetConfig, "SetConfig"},
+ {7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
+ {11, &SPL::IsDevelopment, "IsDevelopment"},
{13, nullptr, "DecryptDeviceUniqueData"},
{14, nullptr, "DecryptAesKey"},
{15, nullptr, "CryptAesCtr"},
@@ -131,8 +131,8 @@ SPL_ES::SPL_ES(Core::System& system_, std::shared_ptr<Module> module_)
{21, nullptr, "AllocateAesKeyslot"},
{22, nullptr, "DeallocateAesKeySlot"},
{23, nullptr, "GetAesKeyslotAvailableEvent"},
- {24, nullptr, "SetBootReason"},
- {25, nullptr, "GetBootReason"},
+ {24, &SPL::SetBootReason, "SetBootReason"},
+ {25, &SPL::GetBootReason, "GetBootReason"},
{28, nullptr, "DecryptAndStoreDrmDeviceCertKey"},
{29, nullptr, "ModularExponentiateWithDrmDeviceCertKey"},
{31, nullptr, "PrepareEsArchiveKey"},
@@ -147,14 +147,14 @@ SPL_MANU::SPL_MANU(Core::System& system_, std::shared_ptr<Module> module_)
: Interface(system_, std::move(module_), "spl:manu") {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "GetConfig"},
- {1, nullptr, "ModularExponentiate"},
+ {0, &SPL::GetConfig, "GetConfig"},
+ {1, &SPL::ModularExponentiate, "ModularExponentiate"},
{2, nullptr, "GenerateAesKek"},
{3, nullptr, "LoadAesKey"},
{4, nullptr, "GenerateAesKey"},
- {5, nullptr, "SetConfig"},
- {7, &SPL::GetRandomBytes, "GetRandomBytes"},
- {11, nullptr, "IsDevelopment"},
+ {5, &SPL::SetConfig, "SetConfig"},
+ {7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
+ {11, &SPL::IsDevelopment, "IsDevelopment"},
{13, nullptr, "DecryptDeviceUniqueData"},
{14, nullptr, "DecryptAesKey"},
{15, nullptr, "CryptAesCtr"},
@@ -162,8 +162,8 @@ SPL_MANU::SPL_MANU(Core::System& system_, std::shared_ptr<Module> module_)
{21, nullptr, "AllocateAesKeyslot"},
{22, nullptr, "DeallocateAesKeySlot"},
{23, nullptr, "GetAesKeyslotAvailableEvent"},
- {24, nullptr, "SetBootReason"},
- {25, nullptr, "GetBootReason"},
+ {24, &SPL::SetBootReason, "SetBootReason"},
+ {25, &SPL::GetBootReason, "GetBootReason"},
{30, nullptr, "ReencryptDeviceUniqueData"},
};
// clang-format on
diff --git a/src/core/hle/service/spl/spl_results.h b/src/core/hle/service/spl/spl_results.h
new file mode 100644
index 000000000..878fa91b7
--- /dev/null
+++ b/src/core/hle/service/spl/spl_results.h
@@ -0,0 +1,29 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/result.h"
+
+namespace Service::SPL {
+
+// Description 0 - 99
+constexpr ResultCode ResultSecureMonitorError{ErrorModule::SPL, 0};
+constexpr ResultCode ResultSecureMonitorNotImplemented{ErrorModule::SPL, 1};
+constexpr ResultCode ResultSecureMonitorInvalidArgument{ErrorModule::SPL, 2};
+constexpr ResultCode ResultSecureMonitorBusy{ErrorModule::SPL, 3};
+constexpr ResultCode ResultSecureMonitorNoAsyncOperation{ErrorModule::SPL, 4};
+constexpr ResultCode ResultSecureMonitorInvalidAsyncOperation{ErrorModule::SPL, 5};
+constexpr ResultCode ResultSecureMonitorNotPermitted{ErrorModule::SPL, 6};
+constexpr ResultCode ResultSecureMonitorNotInitialized{ErrorModule::SPL, 7};
+
+constexpr ResultCode ResultInvalidSize{ErrorModule::SPL, 100};
+constexpr ResultCode ResultUnknownSecureMonitorError{ErrorModule::SPL, 101};
+constexpr ResultCode ResultDecryptionFailed{ErrorModule::SPL, 102};
+
+constexpr ResultCode ResultOutOfKeySlots{ErrorModule::SPL, 104};
+constexpr ResultCode ResultInvalidKeySlot{ErrorModule::SPL, 105};
+constexpr ResultCode ResultBootReasonAlreadySet{ErrorModule::SPL, 106};
+constexpr ResultCode ResultBootReasonNotSet{ErrorModule::SPL, 107};
+constexpr ResultCode ResultInvalidArgument{ErrorModule::SPL, 108};
+
+} // namespace Service::SPL
diff --git a/src/core/hle/service/spl/spl_types.h b/src/core/hle/service/spl/spl_types.h
new file mode 100644
index 000000000..23c39f7ed
--- /dev/null
+++ b/src/core/hle/service/spl/spl_types.h
@@ -0,0 +1,230 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <span>
+
+#include "common/bit_field.h"
+#include "common/common_types.h"
+
+namespace Service::SPL {
+
+constexpr size_t AES_128_KEY_SIZE = 0x10;
+
+namespace Smc {
+
+enum class FunctionId : u32 {
+ SetConfig = 0xC3000401,
+ GetConfig = 0xC3000002,
+ GetResult = 0xC3000003,
+ GetResultData = 0xC3000404,
+ ModularExponentiate = 0xC3000E05,
+ GenerateRandomBytes = 0xC3000006,
+ GenerateAesKek = 0xC3000007,
+ LoadAesKey = 0xC3000008,
+ ComputeAes = 0xC3000009,
+ GenerateSpecificAesKey = 0xC300000A,
+ ComputeCmac = 0xC300040B,
+ ReencryptDeviceUniqueData = 0xC300D60C,
+ DecryptDeviceUniqueData = 0xC300100D,
+
+ ModularExponentiateWithStorageKey = 0xC300060F,
+ PrepareEsDeviceUniqueKey = 0xC3000610,
+ LoadPreparedAesKey = 0xC3000011,
+ PrepareCommonEsTitleKey = 0xC3000012,
+
+ // Deprecated functions.
+ LoadEsDeviceKey = 0xC300100C,
+ DecryptAndStoreGcKey = 0xC300100E,
+
+ // Atmosphere functions.
+ AtmosphereIramCopy = 0xF0000201,
+ AtmosphereReadWriteRegister = 0xF0000002,
+
+ AtmosphereGetEmummcConfig = 0xF0000404,
+};
+
+enum class CipherMode {
+ CbcEncrypt = 0,
+ CbcDecrypt = 1,
+ Ctr = 2,
+};
+
+enum class DeviceUniqueDataMode {
+ DecryptDeviceUniqueData = 0,
+ DecryptAndStoreGcKey = 1,
+ DecryptAndStoreEsDeviceKey = 2,
+ DecryptAndStoreSslKey = 3,
+ DecryptAndStoreDrmDeviceCertKey = 4,
+};
+
+enum class ModularExponentiateWithStorageKeyMode {
+ Gc = 0,
+ Ssl = 1,
+ DrmDeviceCert = 2,
+};
+
+enum class EsCommonKeyType {
+ TitleKey = 0,
+ ArchiveKey = 1,
+};
+
+struct AsyncOperationKey {
+ u64 value;
+};
+
+} // namespace Smc
+
+enum class HardwareType {
+ Icosa = 0,
+ Copper = 1,
+ Hoag = 2,
+ Iowa = 3,
+ Calcio = 4,
+ Aula = 5,
+};
+
+enum class SocType {
+ Erista = 0,
+ Mariko = 1,
+};
+
+enum class HardwareState {
+ Development = 0,
+ Production = 1,
+};
+
+enum class MemoryArrangement {
+ Standard = 0,
+ StandardForAppletDev = 1,
+ StandardForSystemDev = 2,
+ Expanded = 3,
+ ExpandedForAppletDev = 4,
+
+ // Note: Dynamic is not official.
+ // Atmosphere uses it to maintain compatibility with firmwares prior to 6.0.0,
+ // which removed the explicit retrieval of memory arrangement from PM.
+ Dynamic = 5,
+ Count,
+};
+
+enum class BootReason {
+ Unknown = 0,
+ AcOk = 1,
+ OnKey = 2,
+ RtcAlarm1 = 3,
+ RtcAlarm2 = 4,
+};
+
+struct BootReasonValue {
+ union {
+ u32 value{};
+
+ BitField<0, 8, u32> power_intr;
+ BitField<8, 8, u32> rtc_intr;
+ BitField<16, 8, u32> nv_erc;
+ BitField<24, 8, u32> boot_reason;
+ };
+};
+static_assert(sizeof(BootReasonValue) == sizeof(u32), "BootReasonValue definition!");
+
+struct AesKey {
+ std::array<u64, AES_128_KEY_SIZE / sizeof(u64)> data64{};
+
+ std::span<u8> AsBytes() {
+ return std::span{reinterpret_cast<u8*>(data64.data()), AES_128_KEY_SIZE};
+ }
+
+ std::span<const u8> AsBytes() const {
+ return std::span{reinterpret_cast<const u8*>(data64.data()), AES_128_KEY_SIZE};
+ }
+};
+static_assert(sizeof(AesKey) == AES_128_KEY_SIZE, "AesKey definition!");
+
+struct IvCtr {
+ std::array<u64, AES_128_KEY_SIZE / sizeof(u64)> data64{};
+
+ std::span<u8> AsBytes() {
+ return std::span{reinterpret_cast<u8*>(data64.data()), AES_128_KEY_SIZE};
+ }
+
+ std::span<const u8> AsBytes() const {
+ return std::span{reinterpret_cast<const u8*>(data64.data()), AES_128_KEY_SIZE};
+ }
+};
+static_assert(sizeof(AesKey) == AES_128_KEY_SIZE, "IvCtr definition!");
+
+struct Cmac {
+ std::array<u64, AES_128_KEY_SIZE / sizeof(u64)> data64{};
+
+ std::span<u8> AsBytes() {
+ return std::span{reinterpret_cast<u8*>(data64.data()), AES_128_KEY_SIZE};
+ }
+
+ std::span<const u8> AsBytes() const {
+ return std::span{reinterpret_cast<const u8*>(data64.data()), AES_128_KEY_SIZE};
+ }
+};
+static_assert(sizeof(AesKey) == AES_128_KEY_SIZE, "Cmac definition!");
+
+struct AccessKey {
+ std::array<u64, AES_128_KEY_SIZE / sizeof(u64)> data64{};
+
+ std::span<u8> AsBytes() {
+ return std::span{reinterpret_cast<u8*>(data64.data()), AES_128_KEY_SIZE};
+ }
+
+ std::span<const u8> AsBytes() const {
+ return std::span{reinterpret_cast<const u8*>(data64.data()), AES_128_KEY_SIZE};
+ }
+};
+static_assert(sizeof(AesKey) == AES_128_KEY_SIZE, "AccessKey definition!");
+
+struct KeySource {
+ std::array<u64, AES_128_KEY_SIZE / sizeof(u64)> data64{};
+
+ std::span<u8> AsBytes() {
+ return std::span{reinterpret_cast<u8*>(data64.data()), AES_128_KEY_SIZE};
+ }
+
+ std::span<const u8> AsBytes() const {
+ return std::span{reinterpret_cast<const u8*>(data64.data()), AES_128_KEY_SIZE};
+ }
+};
+static_assert(sizeof(AesKey) == AES_128_KEY_SIZE, "KeySource definition!");
+
+enum class ConfigItem : u32 {
+ // Standard config items.
+ DisableProgramVerification = 1,
+ DramId = 2,
+ SecurityEngineInterruptNumber = 3,
+ FuseVersion = 4,
+ HardwareType = 5,
+ HardwareState = 6,
+ IsRecoveryBoot = 7,
+ DeviceId = 8,
+ BootReason = 9,
+ MemoryMode = 10,
+ IsDevelopmentFunctionEnabled = 11,
+ KernelConfiguration = 12,
+ IsChargerHiZModeEnabled = 13,
+ QuestState = 14,
+ RegulatorType = 15,
+ DeviceUniqueKeyGeneration = 16,
+ Package2Hash = 17,
+
+ // Extension config items for exosphere.
+ ExosphereApiVersion = 65000,
+ ExosphereNeedsReboot = 65001,
+ ExosphereNeedsShutdown = 65002,
+ ExosphereGitCommitHash = 65003,
+ ExosphereHasRcmBugPatch = 65004,
+ ExosphereBlankProdInfo = 65005,
+ ExosphereAllowCalWrites = 65006,
+ ExosphereEmummcType = 65007,
+ ExospherePayloadAddress = 65008,
+ ExosphereLogConfiguration = 65009,
+ ExosphereForceEnableUsb30 = 65010,
+};
+
+} // namespace Service::SPL
diff --git a/src/core/hle/service/time/time_zone_content_manager.cpp b/src/core/hle/service/time/time_zone_content_manager.cpp
index bf4402308..c634b6abd 100644
--- a/src/core/hle/service/time/time_zone_content_manager.cpp
+++ b/src/core/hle/service/time/time_zone_content_manager.cpp
@@ -125,7 +125,7 @@ ResultCode TimeZoneContentManager::GetTimeZoneInfoFile(const std::string& locati
return ERROR_TIME_NOT_FOUND;
}
- vfs_file = zoneinfo_dir->GetFile(location_name);
+ vfs_file = zoneinfo_dir->GetFileRelative(location_name);
if (!vfs_file) {
LOG_ERROR(Service_Time, "{:016X} has no file \"{}\"! Using default timezone.",
time_zone_binary_titleid, location_name);
diff --git a/src/input_common/mouse/mouse_input.cpp b/src/input_common/mouse/mouse_input.cpp
index a335e6da1..3b052ffb2 100644
--- a/src/input_common/mouse/mouse_input.cpp
+++ b/src/input_common/mouse/mouse_input.cpp
@@ -2,25 +2,23 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
+#include <stop_token>
+#include <thread>
+
#include "common/settings.h"
#include "input_common/mouse/mouse_input.h"
namespace MouseInput {
Mouse::Mouse() {
- update_thread = std::thread(&Mouse::UpdateThread, this);
+ update_thread = std::jthread([this](std::stop_token stop_token) { UpdateThread(stop_token); });
}
-Mouse::~Mouse() {
- update_thread_running = false;
- if (update_thread.joinable()) {
- update_thread.join();
- }
-}
+Mouse::~Mouse() = default;
-void Mouse::UpdateThread() {
+void Mouse::UpdateThread(std::stop_token stop_token) {
constexpr int update_time = 10;
- while (update_thread_running) {
+ while (!stop_token.stop_requested()) {
for (MouseInfo& info : mouse_info) {
const Common::Vec3f angular_direction{
-info.tilt_direction.y,
diff --git a/src/input_common/mouse/mouse_input.h b/src/input_common/mouse/mouse_input.h
index 5a971ad67..c8bae99c1 100644
--- a/src/input_common/mouse/mouse_input.h
+++ b/src/input_common/mouse/mouse_input.h
@@ -6,6 +6,7 @@
#include <array>
#include <mutex>
+#include <stop_token>
#include <thread>
#include "common/common_types.h"
@@ -85,7 +86,7 @@ public:
[[nodiscard]] const MouseData& GetMouseState(std::size_t button) const;
private:
- void UpdateThread();
+ void UpdateThread(std::stop_token stop_token);
void UpdateYuzuSettings();
void StopPanning();
@@ -105,12 +106,11 @@ private:
u16 buttons{};
u16 toggle_buttons{};
u16 lock_buttons{};
- std::thread update_thread;
+ std::jthread update_thread;
MouseButton last_button{MouseButton::Undefined};
std::array<MouseInfo, 7> mouse_info;
Common::SPSCQueue<MouseStatus> mouse_queue;
bool configuring{false};
- bool update_thread_running{true};
int mouse_panning_timout{};
};
} // namespace MouseInput
diff --git a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp
index db78ce3d9..6852c11b0 100644
--- a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp
+++ b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp
@@ -2,8 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include <atomic>
-#include <chrono>
+#include <thread>
#include "common/settings.h"
#include "video_core/renderer_vulkan/vk_master_semaphore.h"
@@ -12,8 +11,6 @@
namespace Vulkan {
-using namespace std::chrono_literals;
-
MasterSemaphore::MasterSemaphore(const Device& device) {
static constexpr VkSemaphoreTypeCreateInfoKHR semaphore_type_ci{
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR,
@@ -34,9 +31,9 @@ MasterSemaphore::MasterSemaphore(const Device& device) {
// Validation layers have a bug where they fail to track resource usage when using timeline
// semaphores and synchronizing with GetSemaphoreCounterValueKHR. To workaround this issue, have
// a separate thread waiting for each timeline semaphore value.
- debug_thread = std::thread([this] {
+ debug_thread = std::jthread([this](std::stop_token stop_token) {
u64 counter = 0;
- while (!shutdown) {
+ while (!stop_token.stop_requested()) {
if (semaphore.Wait(counter, 10'000'000)) {
++counter;
}
@@ -44,13 +41,6 @@ MasterSemaphore::MasterSemaphore(const Device& device) {
});
}
-MasterSemaphore::~MasterSemaphore() {
- shutdown = true;
-
- // This thread might not be started
- if (debug_thread.joinable()) {
- debug_thread.join();
- }
-}
+MasterSemaphore::~MasterSemaphore() = default;
} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_master_semaphore.h b/src/video_core/renderer_vulkan/vk_master_semaphore.h
index 4b6d64daa..ee3cd35d0 100644
--- a/src/video_core/renderer_vulkan/vk_master_semaphore.h
+++ b/src/video_core/renderer_vulkan/vk_master_semaphore.h
@@ -65,11 +65,10 @@ public:
}
private:
- vk::Semaphore semaphore; ///< Timeline semaphore.
- std::atomic<u64> gpu_tick{0}; ///< Current known GPU tick.
- std::atomic<u64> current_tick{1}; ///< Current logical tick.
- std::atomic<bool> shutdown{false}; ///< True when the object is being destroyed.
- std::thread debug_thread; ///< Debug thread to workaround validation layer bugs.
+ vk::Semaphore semaphore; ///< Timeline semaphore.
+ std::atomic<u64> gpu_tick{0}; ///< Current known GPU tick.
+ std::atomic<u64> current_tick{1}; ///< Current logical tick.
+ std::jthread debug_thread; ///< Debug thread to workaround validation layer bugs.
};
} // namespace Vulkan
diff --git a/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp b/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp
index f0ee76519..758c038ba 100644
--- a/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp
+++ b/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp
@@ -50,7 +50,7 @@ NsightAftermathTracker::NsightAftermathTracker() {
}
dump_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::LogDir) / "gpucrash";
- void(Common::FS::RemoveDirRecursively(dump_dir));
+ Common::FS::RemoveDirRecursively(dump_dir);
if (!Common::FS::CreateDir(dump_dir)) {
LOG_ERROR(Render_Vulkan, "Failed to create Nsight Aftermath dump directory");
return;
diff --git a/src/yuzu/configuration/configure_per_game_addons.cpp b/src/yuzu/configuration/configure_per_game_addons.cpp
index 9b709d405..ebb0f411c 100644
--- a/src/yuzu/configuration/configure_per_game_addons.cpp
+++ b/src/yuzu/configuration/configure_per_game_addons.cpp
@@ -79,8 +79,8 @@ void ConfigurePerGameAddons::ApplyConfiguration() {
std::sort(disabled_addons.begin(), disabled_addons.end());
std::sort(current.begin(), current.end());
if (disabled_addons != current) {
- void(Common::FS::RemoveFile(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
- "game_list" / fmt::format("{:016X}.pv.txt", title_id)));
+ Common::FS::RemoveFile(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
+ "game_list" / fmt::format("{:016X}.pv.txt", title_id));
}
Settings::values.disabled_addons[title_id] = disabled_addons;
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index d4c7d2c0b..75ab5ef44 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -194,10 +194,10 @@ static void RemoveCachedContents() {
const auto offline_legal_information = cache_dir / "offline_web_applet_legal_information";
const auto offline_system_data = cache_dir / "offline_web_applet_system_data";
- void(Common::FS::RemoveDirRecursively(offline_fonts));
- void(Common::FS::RemoveDirRecursively(offline_manual));
- void(Common::FS::RemoveDirRecursively(offline_legal_information));
- void(Common::FS::RemoveDirRecursively(offline_system_data));
+ Common::FS::RemoveDirRecursively(offline_fonts);
+ Common::FS::RemoveDirRecursively(offline_manual);
+ Common::FS::RemoveDirRecursively(offline_legal_information);
+ Common::FS::RemoveDirRecursively(offline_system_data);
}
GMainWindow::GMainWindow()
@@ -1743,8 +1743,8 @@ void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryT
RemoveAddOnContent(program_id, entry_type);
break;
}
- void(Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
- "game_list"));
+ Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
+ "game_list");
game_list->PopulateAsync(UISettings::values.game_dirs);
}
@@ -2213,8 +2213,8 @@ void GMainWindow::OnMenuInstallToNAND() {
: tr("%n file(s) failed to install\n", "", failed_files.size()));
QMessageBox::information(this, tr("Install Results"), install_results);
- void(Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
- "game_list"));
+ Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
+ "game_list");
game_list->PopulateAsync(UISettings::values.game_dirs);
ui.action_Install_File_NAND->setEnabled(true);
}
@@ -2846,7 +2846,7 @@ void GMainWindow::MigrateConfigFiles() {
LOG_INFO(Frontend, "Migrating config file from {} to {}", origin, destination);
if (!Common::FS::RenameFile(origin, destination)) {
// Delete the old config file if one already exists in the new location.
- void(Common::FS::RemoveFile(origin));
+ Common::FS::RemoveFile(origin);
}
}
}
@@ -3040,9 +3040,9 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
const auto keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir);
- void(Common::FS::RemoveFile(keys_dir / "prod.keys_autogenerated"));
- void(Common::FS::RemoveFile(keys_dir / "console.keys_autogenerated"));
- void(Common::FS::RemoveFile(keys_dir / "title.keys_autogenerated"));
+ Common::FS::RemoveFile(keys_dir / "prod.keys_autogenerated");
+ Common::FS::RemoveFile(keys_dir / "console.keys_autogenerated");
+ Common::FS::RemoveFile(keys_dir / "title.keys_autogenerated");
}
Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::Instance();