summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--CMakeLists.txt28
-rw-r--r--CMakeModules/FindDiscordRPC.cmake (renamed from externals/find-modules/FindDiscordRPC.cmake)0
-rw-r--r--CMakeModules/FindFFmpeg.cmake (renamed from externals/find-modules/FindFFmpeg.cmake)0
-rw-r--r--CMakeModules/FindOpus.cmake (renamed from externals/find-modules/FindOpus.cmake)0
-rw-r--r--CMakeModules/Findenet.cmake (renamed from externals/find-modules/Findenet.cmake)0
-rw-r--r--CMakeModules/Findhttplib.cmake (renamed from externals/find-modules/Findhttplib.cmake)2
-rw-r--r--CMakeModules/Findinih.cmake (renamed from externals/find-modules/Findinih.cmake)0
-rw-r--r--CMakeModules/Findlibusb.cmake (renamed from externals/find-modules/Findlibusb.cmake)0
-rw-r--r--CMakeModules/Findlz4.cmake (renamed from externals/find-modules/Findlz4.cmake)2
-rw-r--r--CMakeModules/Findzstd.cmake (renamed from externals/find-modules/Findzstd.cmake)2
-rw-r--r--CMakeModules/WindowsCopyFiles.cmake (renamed from externals/cmake-modules/WindowsCopyFiles.cmake)0
-rw-r--r--externals/CMakeLists.txt19
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/hid/emulated_controller.cpp20
-rw-r--r--src/core/hle/kernel/k_code_memory.cpp29
-rw-r--r--src/core/hle/kernel/k_code_memory.h6
-rw-r--r--src/core/hle/kernel/k_memory_manager.cpp8
-rw-r--r--src/core/hle/kernel/k_page_group.cpp121
-rw-r--r--src/core/hle/kernel/k_page_group.h163
-rw-r--r--src/core/hle/kernel/k_page_table.cpp142
-rw-r--r--src/core/hle/kernel/k_page_table.h9
-rw-r--r--src/core/hle/kernel/k_shared_memory.cpp19
-rw-r--r--src/core/hle/kernel/memory_types.h3
-rw-r--r--src/core/hle/kernel/svc.cpp2
-rw-r--r--src/core/hle/service/nifm/nifm.cpp88
-rw-r--r--src/dedicated_room/CMakeLists.txt2
-rw-r--r--src/yuzu/CMakeLists.txt1
-rw-r--r--src/yuzu/debugger/controller.cpp10
-rw-r--r--src/yuzu_cmd/CMakeLists.txt2
29 files changed, 278 insertions, 401 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 55fdf8fcc..cee720940 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,13 +3,8 @@
cmake_minimum_required(VERSION 3.22)
-# Dynarmic has cmake_minimum_required(3.12) and we may want to override
-# some of its variables, which is only possible in 3.13+
-set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
-
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules")
-list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/find-modules")
include(DownloadExternals)
include(CMakeDependentOption)
@@ -207,42 +202,43 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
# System imported libraries
# =======================================================================
-find_package(enet 1.3)
+# Enforce the search mode of non-required packages for better and shorter failure messages
+find_package(enet 1.3 MODULE)
find_package(fmt 9 REQUIRED)
-find_package(inih)
+find_package(inih MODULE)
find_package(lz4 REQUIRED)
find_package(nlohmann_json 3.8 REQUIRED)
-find_package(Opus 1.3)
+find_package(Opus 1.3 MODULE)
find_package(ZLIB 1.2 REQUIRED)
find_package(zstd 1.5 REQUIRED)
if (NOT YUZU_USE_EXTERNAL_VULKAN_HEADERS)
- find_package(Vulkan 1.3.238)
+ find_package(Vulkan 1.3.238 REQUIRED)
endif()
if (ENABLE_LIBUSB)
- find_package(libusb 1.0.24)
+ find_package(libusb 1.0.24 MODULE)
endif()
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
- find_package(xbyak 6 QUIET)
+ find_package(xbyak 6 CONFIG)
endif()
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
- find_package(dynarmic 6.4.0 QUIET)
+ find_package(dynarmic 6.4.0 CONFIG)
endif()
if (ENABLE_CUBEB)
- find_package(cubeb QUIET)
+ find_package(cubeb CONFIG)
endif()
if (USE_DISCORD_PRESENCE)
- find_package(DiscordRPC QUIET)
+ find_package(DiscordRPC MODULE)
endif()
if (ENABLE_WEB_SERVICE)
- find_package(cpp-jwt 1.4 QUIET)
- find_package(httplib 0.11 QUIET)
+ find_package(cpp-jwt 1.4 CONFIG)
+ find_package(httplib 0.11 MODULE)
endif()
if (YUZU_TESTS)
diff --git a/externals/find-modules/FindDiscordRPC.cmake b/CMakeModules/FindDiscordRPC.cmake
index 44ca9904f..44ca9904f 100644
--- a/externals/find-modules/FindDiscordRPC.cmake
+++ b/CMakeModules/FindDiscordRPC.cmake
diff --git a/externals/find-modules/FindFFmpeg.cmake b/CMakeModules/FindFFmpeg.cmake
index eedf28aea..eedf28aea 100644
--- a/externals/find-modules/FindFFmpeg.cmake
+++ b/CMakeModules/FindFFmpeg.cmake
diff --git a/externals/find-modules/FindOpus.cmake b/CMakeModules/FindOpus.cmake
index 25a44fd87..25a44fd87 100644
--- a/externals/find-modules/FindOpus.cmake
+++ b/CMakeModules/FindOpus.cmake
diff --git a/externals/find-modules/Findenet.cmake b/CMakeModules/Findenet.cmake
index 859a6f386..859a6f386 100644
--- a/externals/find-modules/Findenet.cmake
+++ b/CMakeModules/Findenet.cmake
diff --git a/externals/find-modules/Findhttplib.cmake b/CMakeModules/Findhttplib.cmake
index 4d17cb393..861207eb5 100644
--- a/externals/find-modules/Findhttplib.cmake
+++ b/CMakeModules/Findhttplib.cmake
@@ -5,7 +5,7 @@
include(FindPackageHandleStandardArgs)
find_package(httplib QUIET CONFIG)
-if (httplib_FOUND)
+if (httplib_CONSIDERED_CONFIGS)
find_package_handle_standard_args(httplib CONFIG_MODE)
else()
find_package(PkgConfig QUIET)
diff --git a/externals/find-modules/Findinih.cmake b/CMakeModules/Findinih.cmake
index b8d38dcff..b8d38dcff 100644
--- a/externals/find-modules/Findinih.cmake
+++ b/CMakeModules/Findinih.cmake
diff --git a/externals/find-modules/Findlibusb.cmake b/CMakeModules/Findlibusb.cmake
index 0eadce957..0eadce957 100644
--- a/externals/find-modules/Findlibusb.cmake
+++ b/CMakeModules/Findlibusb.cmake
diff --git a/externals/find-modules/Findlz4.cmake b/CMakeModules/Findlz4.cmake
index c82405c59..7a9a02d4e 100644
--- a/externals/find-modules/Findlz4.cmake
+++ b/CMakeModules/Findlz4.cmake
@@ -4,7 +4,7 @@
include(FindPackageHandleStandardArgs)
find_package(lz4 QUIET CONFIG)
-if (lz4_FOUND)
+if (lz4_CONSIDERED_CONFIGS)
find_package_handle_standard_args(lz4 CONFIG_MODE)
else()
find_package(PkgConfig QUIET)
diff --git a/externals/find-modules/Findzstd.cmake b/CMakeModules/Findzstd.cmake
index f6eb9643a..ae3ea0865 100644
--- a/externals/find-modules/Findzstd.cmake
+++ b/CMakeModules/Findzstd.cmake
@@ -4,7 +4,7 @@
include(FindPackageHandleStandardArgs)
find_package(zstd QUIET CONFIG)
-if (zstd_FOUND)
+if (zstd_CONSIDERED_CONFIGS)
find_package_handle_standard_args(zstd CONFIG_MODE)
else()
find_package(PkgConfig QUIET)
diff --git a/externals/cmake-modules/WindowsCopyFiles.cmake b/CMakeModules/WindowsCopyFiles.cmake
index 08b598365..08b598365 100644
--- a/externals/cmake-modules/WindowsCopyFiles.cmake
+++ b/CMakeModules/WindowsCopyFiles.cmake
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt
index 1b9ae0009..dfd40cba6 100644
--- a/externals/CMakeLists.txt
+++ b/externals/CMakeLists.txt
@@ -1,9 +1,9 @@
# SPDX-FileCopyrightText: 2016 Citra Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
-list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules")
-list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/externals/find-modules")
-include(DownloadExternals)
+# Dynarmic has cmake_minimum_required(3.12) and we may want to override
+# some of its variables, which is only possible in 3.13+
+set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
# xbyak
if ((ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) AND NOT TARGET xbyak::xbyak)
@@ -12,8 +12,7 @@ endif()
# Dynarmic
if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) AND NOT TARGET dynarmic::dynarmic)
- set(DYNARMIC_NO_BUNDLED_FMT ON)
- set(DYNARMIC_IGNORE_ASSERTS ON CACHE BOOL "" FORCE)
+ set(DYNARMIC_IGNORE_ASSERTS ON)
add_subdirectory(dynarmic EXCLUDE_FROM_ALL)
add_library(dynarmic::dynarmic ALIAS dynarmic)
endif()
@@ -60,10 +59,10 @@ if (YUZU_USE_EXTERNAL_SDL2)
Locale Power Render)
foreach(_SUB ${SDL_UNUSED_SUBSYSTEMS})
string(TOUPPER ${_SUB} _OPT)
- option(SDL_${_OPT} "" OFF)
+ set(SDL_${_OPT} OFF)
endforeach()
- option(HIDAPI "" ON)
+ set(HIDAPI ON)
endif()
set(SDL_STATIC ON)
set(SDL_SHARED OFF)
@@ -83,7 +82,7 @@ endif()
# Cubeb
if (ENABLE_CUBEB AND NOT TARGET cubeb::cubeb)
- set(BUILD_TESTS OFF CACHE BOOL "")
+ set(BUILD_TESTS OFF)
add_subdirectory(cubeb EXCLUDE_FROM_ALL)
add_library(cubeb::cubeb ALIAS cubeb)
endif()
@@ -98,6 +97,7 @@ endif()
# Sirit
add_subdirectory(sirit EXCLUDE_FROM_ALL)
+# httplib
if (ENABLE_WEB_SERVICE AND NOT TARGET httplib::httplib)
if (NOT WIN32)
find_package(OpenSSL 1.1)
@@ -108,7 +108,7 @@ if (ENABLE_WEB_SERVICE AND NOT TARGET httplib::httplib)
if (WIN32 OR NOT OPENSSL_FOUND)
# LibreSSL
- set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "")
+ set(LIBRESSL_SKIP_INSTALL ON)
set(OPENSSLDIR "/etc/ssl/")
add_subdirectory(libressl EXCLUDE_FROM_ALL)
target_include_directories(ssl INTERFACE ./libressl/include)
@@ -118,7 +118,6 @@ if (ENABLE_WEB_SERVICE AND NOT TARGET httplib::httplib)
DEFINITION OPENSSL_LIBS)
endif()
- # httplib
add_library(httplib INTERFACE)
target_include_directories(httplib INTERFACE ./cpp-httplib)
target_compile_definitions(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 5afdeb5ff..0252c8c31 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -226,7 +226,6 @@ add_library(core STATIC
hle/kernel/k_page_buffer.h
hle/kernel/k_page_heap.cpp
hle/kernel/k_page_heap.h
- hle/kernel/k_page_group.cpp
hle/kernel/k_page_group.h
hle/kernel/k_page_table.cpp
hle/kernel/k_page_table.h
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index 5587ee097..71364c323 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -11,6 +11,11 @@
namespace Core::HID {
constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
constexpr s32 HID_TRIGGER_MAX = 0x7fff;
+// Use a common UUID for TAS and Virtual Gamepad
+constexpr Common::UUID TAS_UUID =
+ Common::UUID{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xA5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
+constexpr Common::UUID VIRTUAL_UUID =
+ Common::UUID{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
EmulatedController::EmulatedController(NpadIdType npad_id_type_) : npad_id_type(npad_id_type_) {}
@@ -348,10 +353,6 @@ void EmulatedController::ReloadInput() {
}
}
- // Use a common UUID for TAS
- static constexpr Common::UUID TAS_UUID = Common::UUID{
- {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xA5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
-
// Register TAS devices. No need to force update
for (std::size_t index = 0; index < tas_button_devices.size(); ++index) {
if (!tas_button_devices[index]) {
@@ -377,10 +378,6 @@ void EmulatedController::ReloadInput() {
});
}
- // Use a common UUID for Virtual Gamepad
- static constexpr Common::UUID VIRTUAL_UUID = Common::UUID{
- {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
-
// Register virtual devices. No need to force update
for (std::size_t index = 0; index < virtual_button_devices.size(); ++index) {
if (!virtual_button_devices[index]) {
@@ -780,7 +777,12 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback,
// Only read stick values that have the same uuid or are over the threshold to avoid flapping
if (controller.stick_values[index].uuid != uuid) {
- if (!stick_value.down && !stick_value.up && !stick_value.left && !stick_value.right) {
+ const bool is_tas = uuid == TAS_UUID;
+ if (is_tas && stick_value.x.value == 0 && stick_value.y.value == 0) {
+ return;
+ }
+ if (!is_tas && !stick_value.down && !stick_value.up && !stick_value.left &&
+ !stick_value.right) {
return;
}
}
diff --git a/src/core/hle/kernel/k_code_memory.cpp b/src/core/hle/kernel/k_code_memory.cpp
index d9da1e600..4b1c134d4 100644
--- a/src/core/hle/kernel/k_code_memory.cpp
+++ b/src/core/hle/kernel/k_code_memory.cpp
@@ -27,13 +27,13 @@ Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr, si
auto& page_table = m_owner->PageTable();
// Construct the page group.
- m_page_group.emplace(kernel, page_table.GetBlockInfoManager());
+ m_page_group = {};
// Lock the memory.
- R_TRY(page_table.LockForCodeMemory(std::addressof(*m_page_group), addr, size))
+ R_TRY(page_table.LockForCodeMemory(&m_page_group, addr, size))
// Clear the memory.
- for (const auto& block : *m_page_group) {
+ for (const auto& block : m_page_group.Nodes()) {
std::memset(device_memory.GetPointer<void>(block.GetAddress()), 0xFF, block.GetSize());
}
@@ -51,13 +51,12 @@ Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr, si
void KCodeMemory::Finalize() {
// Unlock.
if (!m_is_mapped && !m_is_owner_mapped) {
- const size_t size = m_page_group->GetNumPages() * PageSize;
- m_owner->PageTable().UnlockForCodeMemory(m_address, size, *m_page_group);
+ const size_t size = m_page_group.GetNumPages() * PageSize;
+ m_owner->PageTable().UnlockForCodeMemory(m_address, size, m_page_group);
}
// Close the page group.
- m_page_group->Close();
- m_page_group->Finalize();
+ m_page_group = {};
// Close our reference to our owner.
m_owner->Close();
@@ -65,7 +64,7 @@ void KCodeMemory::Finalize() {
Result KCodeMemory::Map(VAddr address, size_t size) {
// Validate the size.
- R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
+ R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
// Lock ourselves.
KScopedLightLock lk(m_lock);
@@ -75,7 +74,7 @@ Result KCodeMemory::Map(VAddr address, size_t size) {
// Map the memory.
R_TRY(kernel.CurrentProcess()->PageTable().MapPages(
- address, *m_page_group, KMemoryState::CodeOut, KMemoryPermission::UserReadWrite));
+ address, m_page_group, KMemoryState::CodeOut, KMemoryPermission::UserReadWrite));
// Mark ourselves as mapped.
m_is_mapped = true;
@@ -85,13 +84,13 @@ Result KCodeMemory::Map(VAddr address, size_t size) {
Result KCodeMemory::Unmap(VAddr address, size_t size) {
// Validate the size.
- R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
+ R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
// Lock ourselves.
KScopedLightLock lk(m_lock);
// Unmap the memory.
- R_TRY(kernel.CurrentProcess()->PageTable().UnmapPages(address, *m_page_group,
+ R_TRY(kernel.CurrentProcess()->PageTable().UnmapPages(address, m_page_group,
KMemoryState::CodeOut));
// Mark ourselves as unmapped.
@@ -102,7 +101,7 @@ Result KCodeMemory::Unmap(VAddr address, size_t size) {
Result KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermission perm) {
// Validate the size.
- R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
+ R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
// Lock ourselves.
KScopedLightLock lk(m_lock);
@@ -126,7 +125,7 @@ Result KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermission
// Map the memory.
R_TRY(
- m_owner->PageTable().MapPages(address, *m_page_group, KMemoryState::GeneratedCode, k_perm));
+ m_owner->PageTable().MapPages(address, m_page_group, KMemoryState::GeneratedCode, k_perm));
// Mark ourselves as mapped.
m_is_owner_mapped = true;
@@ -136,13 +135,13 @@ Result KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermission
Result KCodeMemory::UnmapFromOwner(VAddr address, size_t size) {
// Validate the size.
- R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
+ R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize);
// Lock ourselves.
KScopedLightLock lk(m_lock);
// Unmap the memory.
- R_TRY(m_owner->PageTable().UnmapPages(address, *m_page_group, KMemoryState::GeneratedCode));
+ R_TRY(m_owner->PageTable().UnmapPages(address, m_page_group, KMemoryState::GeneratedCode));
// Mark ourselves as unmapped.
m_is_owner_mapped = false;
diff --git a/src/core/hle/kernel/k_code_memory.h b/src/core/hle/kernel/k_code_memory.h
index 5b260b385..2e7e1436a 100644
--- a/src/core/hle/kernel/k_code_memory.h
+++ b/src/core/hle/kernel/k_code_memory.h
@@ -3,8 +3,6 @@
#pragma once
-#include <optional>
-
#include "common/common_types.h"
#include "core/device_memory.h"
#include "core/hle/kernel/k_auto_object.h"
@@ -51,11 +49,11 @@ public:
return m_address;
}
size_t GetSize() const {
- return m_is_initialized ? m_page_group->GetNumPages() * PageSize : 0;
+ return m_is_initialized ? m_page_group.GetNumPages() * PageSize : 0;
}
private:
- std::optional<KPageGroup> m_page_group{};
+ KPageGroup m_page_group{};
KProcess* m_owner{};
VAddr m_address{};
KLightLock m_lock;
diff --git a/src/core/hle/kernel/k_memory_manager.cpp b/src/core/hle/kernel/k_memory_manager.cpp
index cd6ea388e..bd33571da 100644
--- a/src/core/hle/kernel/k_memory_manager.cpp
+++ b/src/core/hle/kernel/k_memory_manager.cpp
@@ -223,7 +223,7 @@ Result KMemoryManager::AllocatePageGroupImpl(KPageGroup* out, size_t num_pages,
// Ensure that we don't leave anything un-freed.
ON_RESULT_FAILURE {
- for (const auto& it : *out) {
+ for (const auto& it : out->Nodes()) {
auto& manager = this->GetManager(it.GetAddress());
const size_t node_num_pages = std::min<u64>(
it.GetNumPages(), (manager.GetEndAddress() - it.GetAddress()) / PageSize);
@@ -285,7 +285,7 @@ Result KMemoryManager::AllocateAndOpen(KPageGroup* out, size_t num_pages, u32 op
m_has_optimized_process[static_cast<size_t>(pool)], true));
// Open the first reference to the pages.
- for (const auto& block : *out) {
+ for (const auto& block : out->Nodes()) {
PAddr cur_address = block.GetAddress();
size_t remaining_pages = block.GetNumPages();
while (remaining_pages > 0) {
@@ -335,7 +335,7 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32
// Perform optimized memory tracking, if we should.
if (optimized) {
// Iterate over the allocated blocks.
- for (const auto& block : *out) {
+ for (const auto& block : out->Nodes()) {
// Get the block extents.
const PAddr block_address = block.GetAddress();
const size_t block_pages = block.GetNumPages();
@@ -391,7 +391,7 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32
}
} else {
// Set all the allocated memory.
- for (const auto& block : *out) {
+ for (const auto& block : out->Nodes()) {
std::memset(m_system.DeviceMemory().GetPointer<void>(block.GetAddress()), fill_pattern,
block.GetSize());
}
diff --git a/src/core/hle/kernel/k_page_group.cpp b/src/core/hle/kernel/k_page_group.cpp
deleted file mode 100644
index d8c644a33..000000000
--- a/src/core/hle/kernel/k_page_group.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/kernel/k_dynamic_resource_manager.h"
-#include "core/hle/kernel/k_memory_manager.h"
-#include "core/hle/kernel/k_page_group.h"
-#include "core/hle/kernel/kernel.h"
-#include "core/hle/kernel/svc_results.h"
-
-namespace Kernel {
-
-void KPageGroup::Finalize() {
- KBlockInfo* cur = m_first_block;
- while (cur != nullptr) {
- KBlockInfo* next = cur->GetNext();
- m_manager->Free(cur);
- cur = next;
- }
-
- m_first_block = nullptr;
- m_last_block = nullptr;
-}
-
-void KPageGroup::CloseAndReset() {
- auto& mm = m_kernel.MemoryManager();
-
- KBlockInfo* cur = m_first_block;
- while (cur != nullptr) {
- KBlockInfo* next = cur->GetNext();
- mm.Close(cur->GetAddress(), cur->GetNumPages());
- m_manager->Free(cur);
- cur = next;
- }
-
- m_first_block = nullptr;
- m_last_block = nullptr;
-}
-
-size_t KPageGroup::GetNumPages() const {
- size_t num_pages = 0;
-
- for (const auto& it : *this) {
- num_pages += it.GetNumPages();
- }
-
- return num_pages;
-}
-
-Result KPageGroup::AddBlock(KPhysicalAddress addr, size_t num_pages) {
- // Succeed immediately if we're adding no pages.
- R_SUCCEED_IF(num_pages == 0);
-
- // Check for overflow.
- ASSERT(addr < addr + num_pages * PageSize);
-
- // Try to just append to the last block.
- if (m_last_block != nullptr) {
- R_SUCCEED_IF(m_last_block->TryConcatenate(addr, num_pages));
- }
-
- // Allocate a new block.
- KBlockInfo* new_block = m_manager->Allocate();
- R_UNLESS(new_block != nullptr, ResultOutOfResource);
-
- // Initialize the block.
- new_block->Initialize(addr, num_pages);
-
- // Add the block to our list.
- if (m_last_block != nullptr) {
- m_last_block->SetNext(new_block);
- } else {
- m_first_block = new_block;
- }
- m_last_block = new_block;
-
- R_SUCCEED();
-}
-
-void KPageGroup::Open() const {
- auto& mm = m_kernel.MemoryManager();
-
- for (const auto& it : *this) {
- mm.Open(it.GetAddress(), it.GetNumPages());
- }
-}
-
-void KPageGroup::OpenFirst() const {
- auto& mm = m_kernel.MemoryManager();
-
- for (const auto& it : *this) {
- mm.OpenFirst(it.GetAddress(), it.GetNumPages());
- }
-}
-
-void KPageGroup::Close() const {
- auto& mm = m_kernel.MemoryManager();
-
- for (const auto& it : *this) {
- mm.Close(it.GetAddress(), it.GetNumPages());
- }
-}
-
-bool KPageGroup::IsEquivalentTo(const KPageGroup& rhs) const {
- auto lit = this->begin();
- auto rit = rhs.begin();
- auto lend = this->end();
- auto rend = rhs.end();
-
- while (lit != lend && rit != rend) {
- if (*lit != *rit) {
- return false;
- }
-
- ++lit;
- ++rit;
- }
-
- return lit == lend && rit == rend;
-}
-
-} // namespace Kernel
diff --git a/src/core/hle/kernel/k_page_group.h b/src/core/hle/kernel/k_page_group.h
index c07f17663..316f172f2 100644
--- a/src/core/hle/kernel/k_page_group.h
+++ b/src/core/hle/kernel/k_page_group.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
@@ -13,23 +13,24 @@
namespace Kernel {
-class KBlockInfoManager;
-class KernelCore;
class KPageGroup;
class KBlockInfo {
+private:
+ friend class KPageGroup;
+
public:
- constexpr explicit KBlockInfo() : m_next(nullptr) {}
+ constexpr KBlockInfo() = default;
- constexpr void Initialize(KPhysicalAddress addr, size_t np) {
+ constexpr void Initialize(PAddr addr, size_t np) {
ASSERT(Common::IsAligned(addr, PageSize));
ASSERT(static_cast<u32>(np) == np);
- m_page_index = static_cast<u32>(addr / PageSize);
+ m_page_index = static_cast<u32>(addr) / PageSize;
m_num_pages = static_cast<u32>(np);
}
- constexpr KPhysicalAddress GetAddress() const {
+ constexpr PAddr GetAddress() const {
return m_page_index * PageSize;
}
constexpr size_t GetNumPages() const {
@@ -38,10 +39,10 @@ public:
constexpr size_t GetSize() const {
return this->GetNumPages() * PageSize;
}
- constexpr KPhysicalAddress GetEndAddress() const {
+ constexpr PAddr GetEndAddress() const {
return (m_page_index + m_num_pages) * PageSize;
}
- constexpr KPhysicalAddress GetLastAddress() const {
+ constexpr PAddr GetLastAddress() const {
return this->GetEndAddress() - 1;
}
@@ -61,8 +62,8 @@ public:
return !(*this == rhs);
}
- constexpr bool IsStrictlyBefore(KPhysicalAddress addr) const {
- const KPhysicalAddress end = this->GetEndAddress();
+ constexpr bool IsStrictlyBefore(PAddr addr) const {
+ const PAddr end = this->GetEndAddress();
if (m_page_index != 0 && end == 0) {
return false;
@@ -71,11 +72,11 @@ public:
return end < addr;
}
- constexpr bool operator<(KPhysicalAddress addr) const {
+ constexpr bool operator<(PAddr addr) const {
return this->IsStrictlyBefore(addr);
}
- constexpr bool TryConcatenate(KPhysicalAddress addr, size_t np) {
+ constexpr bool TryConcatenate(PAddr addr, size_t np) {
if (addr != 0 && addr == this->GetEndAddress()) {
m_num_pages += static_cast<u32>(np);
return true;
@@ -89,118 +90,96 @@ private:
}
private:
- friend class KPageGroup;
-
KBlockInfo* m_next{};
u32 m_page_index{};
u32 m_num_pages{};
};
static_assert(sizeof(KBlockInfo) <= 0x10);
-class KPageGroup {
+class KPageGroup final {
public:
- class Iterator {
+ class Node final {
public:
- using iterator_category = std::forward_iterator_tag;
- using value_type = const KBlockInfo;
- using difference_type = std::ptrdiff_t;
- using pointer = value_type*;
- using reference = value_type&;
-
- constexpr explicit Iterator(pointer n) : m_node(n) {}
-
- constexpr bool operator==(const Iterator& rhs) const {
- return m_node == rhs.m_node;
- }
- constexpr bool operator!=(const Iterator& rhs) const {
- return !(*this == rhs);
- }
+ constexpr Node(u64 addr_, std::size_t num_pages_) : addr{addr_}, num_pages{num_pages_} {}
- constexpr pointer operator->() const {
- return m_node;
- }
- constexpr reference operator*() const {
- return *m_node;
+ constexpr u64 GetAddress() const {
+ return addr;
}
- constexpr Iterator& operator++() {
- m_node = m_node->GetNext();
- return *this;
+ constexpr std::size_t GetNumPages() const {
+ return num_pages;
}
- constexpr Iterator operator++(int) {
- const Iterator it{*this};
- ++(*this);
- return it;
+ constexpr std::size_t GetSize() const {
+ return GetNumPages() * PageSize;
}
private:
- pointer m_node{};
+ u64 addr{};
+ std::size_t num_pages{};
};
- explicit KPageGroup(KernelCore& kernel, KBlockInfoManager* m)
- : m_kernel{kernel}, m_manager{m} {}
- ~KPageGroup() {
- this->Finalize();
+public:
+ KPageGroup() = default;
+ KPageGroup(u64 address, u64 num_pages) {
+ ASSERT(AddBlock(address, num_pages).IsSuccess());
}
- void CloseAndReset();
- void Finalize();
-
- Iterator begin() const {
- return Iterator{m_first_block};
- }
- Iterator end() const {
- return Iterator{nullptr};
- }
- bool empty() const {
- return m_first_block == nullptr;
+ constexpr std::list<Node>& Nodes() {
+ return nodes;
}
- Result AddBlock(KPhysicalAddress addr, size_t num_pages);
- void Open() const;
- void OpenFirst() const;
- void Close() const;
-
- size_t GetNumPages() const;
-
- bool IsEquivalentTo(const KPageGroup& rhs) const;
-
- bool operator==(const KPageGroup& rhs) const {
- return this->IsEquivalentTo(rhs);
+ constexpr const std::list<Node>& Nodes() const {
+ return nodes;
}
- bool operator!=(const KPageGroup& rhs) const {
- return !(*this == rhs);
- }
+ std::size_t GetNumPages() const {
+ std::size_t num_pages = 0;
+ for (const Node& node : nodes) {
+ num_pages += node.GetNumPages();
+ }
+ return num_pages;
+ }
+
+ bool IsEqual(KPageGroup& other) const {
+ auto this_node = nodes.begin();
+ auto other_node = other.nodes.begin();
+ while (this_node != nodes.end() && other_node != other.nodes.end()) {
+ if (this_node->GetAddress() != other_node->GetAddress() ||
+ this_node->GetNumPages() != other_node->GetNumPages()) {
+ return false;
+ }
+ this_node = std::next(this_node);
+ other_node = std::next(other_node);
+ }
-private:
- KernelCore& m_kernel;
- KBlockInfo* m_first_block{};
- KBlockInfo* m_last_block{};
- KBlockInfoManager* m_manager{};
-};
+ return this_node == nodes.end() && other_node == other.nodes.end();
+ }
-class KScopedPageGroup {
-public:
- explicit KScopedPageGroup(const KPageGroup* gp) : m_pg(gp) {
- if (m_pg) {
- m_pg->Open();
+ Result AddBlock(u64 address, u64 num_pages) {
+ if (!num_pages) {
+ return ResultSuccess;
}
- }
- explicit KScopedPageGroup(const KPageGroup& gp) : KScopedPageGroup(std::addressof(gp)) {}
- ~KScopedPageGroup() {
- if (m_pg) {
- m_pg->Close();
+ if (!nodes.empty()) {
+ const auto node = nodes.back();
+ if (node.GetAddress() + node.GetNumPages() * PageSize == address) {
+ address = node.GetAddress();
+ num_pages += node.GetNumPages();
+ nodes.pop_back();
+ }
}
+ nodes.push_back({address, num_pages});
+ return ResultSuccess;
}
- void CancelClose() {
- m_pg = nullptr;
+ bool Empty() const {
+ return nodes.empty();
}
+ void Finalize() {}
+
private:
- const KPageGroup* m_pg{};
+ std::list<Node> nodes;
};
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index 9c7ac22dc..612fc76fa 100644
--- a/src/core/hle/kernel/k_page_table.cpp
+++ b/src/core/hle/kernel/k_page_table.cpp
@@ -100,7 +100,7 @@ constexpr size_t GetAddressSpaceWidthFromType(FileSys::ProgramAddressSpaceType a
KPageTable::KPageTable(Core::System& system_)
: m_general_lock{system_.Kernel()},
- m_map_physical_memory_lock{system_.Kernel()}, m_system{system_}, m_kernel{system_.Kernel()} {}
+ m_map_physical_memory_lock{system_.Kernel()}, m_system{system_} {}
KPageTable::~KPageTable() = default;
@@ -373,7 +373,7 @@ Result KPageTable::MapProcessCode(VAddr addr, size_t num_pages, KMemoryState sta
m_memory_block_slab_manager);
// Allocate and open.
- KPageGroup pg{m_kernel, m_block_info_manager};
+ KPageGroup pg;
R_TRY(m_system.Kernel().MemoryManager().AllocateAndOpen(
&pg, num_pages,
KMemoryManager::EncodeOption(KMemoryManager::Pool::Application, m_allocation_option)));
@@ -432,7 +432,7 @@ Result KPageTable::MapCodeMemory(VAddr dst_address, VAddr src_address, size_t si
const size_t num_pages = size / PageSize;
// Create page groups for the memory being mapped.
- KPageGroup pg{m_kernel, m_block_info_manager};
+ KPageGroup pg;
AddRegionToPages(src_address, num_pages, pg);
// Reprotect the source as kernel-read/not mapped.
@@ -593,7 +593,7 @@ Result KPageTable::MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages) {
const size_t size = num_pages * PageSize;
// We're making a new group, not adding to an existing one.
- R_UNLESS(pg.empty(), ResultInvalidCurrentMemory);
+ R_UNLESS(pg.Empty(), ResultInvalidCurrentMemory);
// Begin traversal.
Common::PageTable::TraversalContext context;
@@ -640,10 +640,11 @@ Result KPageTable::MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages) {
R_SUCCEED();
}
-bool KPageTable::IsValidPageGroup(const KPageGroup& pg, VAddr addr, size_t num_pages) {
+bool KPageTable::IsValidPageGroup(const KPageGroup& pg_ll, VAddr addr, size_t num_pages) {
ASSERT(this->IsLockedByCurrentThread());
const size_t size = num_pages * PageSize;
+ const auto& pg = pg_ll.Nodes();
const auto& memory_layout = m_system.Kernel().MemoryLayout();
// Empty groups are necessarily invalid.
@@ -941,6 +942,9 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
ON_RESULT_FAILURE {
if (cur_mapped_addr != dst_addr) {
+ // HACK: Manually close the pages.
+ HACK_ClosePages(dst_addr, (cur_mapped_addr - dst_addr) / PageSize);
+
ASSERT(Operate(dst_addr, (cur_mapped_addr - dst_addr) / PageSize,
KMemoryPermission::None, OperationType::Unmap)
.IsSuccess());
@@ -1016,6 +1020,9 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
// Map the page.
R_TRY(Operate(cur_mapped_addr, 1, test_perm, OperationType::Map, start_partial_page));
+ // HACK: Manually open the pages.
+ HACK_OpenPages(start_partial_page, 1);
+
// Update tracking extents.
cur_mapped_addr += PageSize;
cur_block_addr += PageSize;
@@ -1044,6 +1051,9 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
R_TRY(Operate(cur_mapped_addr, cur_block_size / PageSize, test_perm, OperationType::Map,
cur_block_addr));
+ // HACK: Manually open the pages.
+ HACK_OpenPages(cur_block_addr, cur_block_size / PageSize);
+
// Update tracking extents.
cur_mapped_addr += cur_block_size;
cur_block_addr = next_entry.phys_addr;
@@ -1063,6 +1073,9 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
R_TRY(Operate(cur_mapped_addr, last_block_size / PageSize, test_perm, OperationType::Map,
cur_block_addr));
+ // HACK: Manually open the pages.
+ HACK_OpenPages(cur_block_addr, last_block_size / PageSize);
+
// Update tracking extents.
cur_mapped_addr += last_block_size;
cur_block_addr += last_block_size;
@@ -1094,6 +1107,9 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
// Map the page.
R_TRY(Operate(cur_mapped_addr, 1, test_perm, OperationType::Map, end_partial_page));
+
+ // HACK: Manually open the pages.
+ HACK_OpenPages(end_partial_page, 1);
}
// Update memory blocks to reflect our changes
@@ -1195,6 +1211,9 @@ Result KPageTable::CleanupForIpcServer(VAddr address, size_t size, KMemoryState
const size_t aligned_size = aligned_end - aligned_start;
const size_t aligned_num_pages = aligned_size / PageSize;
+ // HACK: Manually close the pages.
+ HACK_ClosePages(aligned_start, aligned_num_pages);
+
// Unmap the pages.
R_TRY(Operate(aligned_start, aligned_num_pages, KMemoryPermission::None, OperationType::Unmap));
@@ -1482,6 +1501,17 @@ void KPageTable::CleanupForIpcClientOnServerSetupFailure([[maybe_unused]] PageLi
}
}
+void KPageTable::HACK_OpenPages(PAddr phys_addr, size_t num_pages) {
+ m_system.Kernel().MemoryManager().OpenFirst(phys_addr, num_pages);
+}
+
+void KPageTable::HACK_ClosePages(VAddr virt_addr, size_t num_pages) {
+ for (size_t index = 0; index < num_pages; ++index) {
+ const auto paddr = GetPhysicalAddr(virt_addr + (index * PageSize));
+ m_system.Kernel().MemoryManager().Close(paddr, 1);
+ }
+}
+
Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
// Lock the physical memory lock.
KScopedLightLock phys_lk(m_map_physical_memory_lock);
@@ -1542,7 +1572,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
// Allocate pages for the new memory.
- KPageGroup pg{m_kernel, m_block_info_manager};
+ KPageGroup pg;
R_TRY(m_system.Kernel().MemoryManager().AllocateForProcess(
&pg, (size - mapped_size) / PageSize, m_allocate_option, 0, 0));
@@ -1620,7 +1650,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
KScopedPageTableUpdater updater(this);
// Prepare to iterate over the memory.
- auto pg_it = pg.begin();
+ auto pg_it = pg.Nodes().begin();
PAddr pg_phys_addr = pg_it->GetAddress();
size_t pg_pages = pg_it->GetNumPages();
@@ -1650,6 +1680,9 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
last_unmap_address + 1 - cur_address) /
PageSize;
+ // HACK: Manually close the pages.
+ HACK_ClosePages(cur_address, cur_pages);
+
// Unmap.
ASSERT(Operate(cur_address, cur_pages, KMemoryPermission::None,
OperationType::Unmap)
@@ -1670,7 +1703,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
// Release any remaining unmapped memory.
m_system.Kernel().MemoryManager().OpenFirst(pg_phys_addr, pg_pages);
m_system.Kernel().MemoryManager().Close(pg_phys_addr, pg_pages);
- for (++pg_it; pg_it != pg.end(); ++pg_it) {
+ for (++pg_it; pg_it != pg.Nodes().end(); ++pg_it) {
m_system.Kernel().MemoryManager().OpenFirst(pg_it->GetAddress(),
pg_it->GetNumPages());
m_system.Kernel().MemoryManager().Close(pg_it->GetAddress(),
@@ -1698,7 +1731,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
// Check if we're at the end of the physical block.
if (pg_pages == 0) {
// Ensure there are more pages to map.
- ASSERT(pg_it != pg.end());
+ ASSERT(pg_it != pg.Nodes().end());
// Advance our physical block.
++pg_it;
@@ -1709,7 +1742,10 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
// Map whatever we can.
const size_t cur_pages = std::min(pg_pages, map_pages);
R_TRY(Operate(cur_address, cur_pages, KMemoryPermission::UserReadWrite,
- OperationType::MapFirst, pg_phys_addr));
+ OperationType::Map, pg_phys_addr));
+
+ // HACK: Manually open the pages.
+ HACK_OpenPages(pg_phys_addr, cur_pages);
// Advance.
cur_address += cur_pages * PageSize;
@@ -1852,6 +1888,9 @@ Result KPageTable::UnmapPhysicalMemory(VAddr address, size_t size) {
last_address + 1 - cur_address) /
PageSize;
+ // HACK: Manually close the pages.
+ HACK_ClosePages(cur_address, cur_pages);
+
// Unmap.
ASSERT(Operate(cur_address, cur_pages, KMemoryPermission::None, OperationType::Unmap)
.IsSuccess());
@@ -1916,7 +1955,7 @@ Result KPageTable::MapMemory(VAddr dst_address, VAddr src_address, size_t size)
R_TRY(dst_allocator_result);
// Map the memory.
- KPageGroup page_linked_list{m_kernel, m_block_info_manager};
+ KPageGroup page_linked_list;
const size_t num_pages{size / PageSize};
const KMemoryPermission new_src_perm = static_cast<KMemoryPermission>(
KMemoryPermission::KernelRead | KMemoryPermission::NotMapped);
@@ -1983,14 +2022,14 @@ Result KPageTable::UnmapMemory(VAddr dst_address, VAddr src_address, size_t size
num_dst_allocator_blocks);
R_TRY(dst_allocator_result);
- KPageGroup src_pages{m_kernel, m_block_info_manager};
- KPageGroup dst_pages{m_kernel, m_block_info_manager};
+ KPageGroup src_pages;
+ KPageGroup dst_pages;
const size_t num_pages{size / PageSize};
AddRegionToPages(src_address, num_pages, src_pages);
AddRegionToPages(dst_address, num_pages, dst_pages);
- R_UNLESS(dst_pages.IsEquivalentTo(src_pages), ResultInvalidMemoryRegion);
+ R_UNLESS(dst_pages.IsEqual(src_pages), ResultInvalidMemoryRegion);
{
auto block_guard = detail::ScopeExit([&] { MapPages(dst_address, dst_pages, dst_perm); });
@@ -2021,7 +2060,7 @@ Result KPageTable::MapPages(VAddr addr, const KPageGroup& page_linked_list,
VAddr cur_addr{addr};
- for (const auto& node : page_linked_list) {
+ for (const auto& node : page_linked_list.Nodes()) {
if (const auto result{
Operate(cur_addr, node.GetNumPages(), perm, OperationType::Map, node.GetAddress())};
result.IsError()) {
@@ -2121,7 +2160,7 @@ Result KPageTable::UnmapPages(VAddr addr, const KPageGroup& page_linked_list) {
VAddr cur_addr{addr};
- for (const auto& node : page_linked_list) {
+ for (const auto& node : page_linked_list.Nodes()) {
if (const auto result{Operate(cur_addr, node.GetNumPages(), KMemoryPermission::None,
OperationType::Unmap)};
result.IsError()) {
@@ -2488,13 +2527,13 @@ Result KPageTable::SetHeapSize(VAddr* out, size_t size) {
R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
// Allocate pages for the heap extension.
- KPageGroup pg{m_kernel, m_block_info_manager};
+ KPageGroup pg;
R_TRY(m_system.Kernel().MemoryManager().AllocateAndOpen(
&pg, allocation_size / PageSize,
KMemoryManager::EncodeOption(m_memory_pool, m_allocation_option)));
// Clear all the newly allocated pages.
- for (const auto& it : pg) {
+ for (const auto& it : pg.Nodes()) {
std::memset(m_system.DeviceMemory().GetPointer<void>(it.GetAddress()), m_heap_fill_value,
it.GetSize());
}
@@ -2571,23 +2610,11 @@ ResultVal<VAddr> KPageTable::AllocateAndMapMemory(size_t needed_num_pages, size_
if (is_map_only) {
R_TRY(Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr));
} else {
- // Create a page group tohold the pages we allocate.
- KPageGroup pg{m_kernel, m_block_info_manager};
-
- R_TRY(m_system.Kernel().MemoryManager().AllocateAndOpen(
- &pg, needed_num_pages,
- KMemoryManager::EncodeOption(m_memory_pool, m_allocation_option)));
-
- // Ensure that the page group is closed when we're done working with it.
- SCOPE_EXIT({ pg.Close(); });
-
- // Clear all pages.
- for (const auto& it : pg) {
- std::memset(m_system.DeviceMemory().GetPointer<void>(it.GetAddress()),
- m_heap_fill_value, it.GetSize());
- }
-
- R_TRY(Operate(addr, needed_num_pages, pg, OperationType::MapGroup));
+ KPageGroup page_group;
+ R_TRY(m_system.Kernel().MemoryManager().AllocateForProcess(
+ &page_group, needed_num_pages,
+ KMemoryManager::EncodeOption(m_memory_pool, m_allocation_option), 0, 0));
+ R_TRY(Operate(addr, needed_num_pages, page_group, OperationType::MapGroup));
}
// Update the blocks.
@@ -2768,28 +2795,19 @@ Result KPageTable::Operate(VAddr addr, size_t num_pages, const KPageGroup& page_
ASSERT(num_pages > 0);
ASSERT(num_pages == page_group.GetNumPages());
- switch (operation) {
- case OperationType::MapGroup: {
- // We want to maintain a new reference to every page in the group.
- KScopedPageGroup spg(page_group);
-
- for (const auto& node : page_group) {
- const size_t size{node.GetNumPages() * PageSize};
+ for (const auto& node : page_group.Nodes()) {
+ const size_t size{node.GetNumPages() * PageSize};
- // Map the pages.
+ switch (operation) {
+ case OperationType::MapGroup:
m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, size, node.GetAddress());
-
- addr += size;
+ break;
+ default:
+ ASSERT(false);
+ break;
}
- // We succeeded! We want to persist the reference to the pages.
- spg.CancelClose();
-
- break;
- }
- default:
- ASSERT(false);
- break;
+ addr += size;
}
R_SUCCEED();
@@ -2804,29 +2822,13 @@ Result KPageTable::Operate(VAddr addr, size_t num_pages, KMemoryPermission perm,
ASSERT(ContainsPages(addr, num_pages));
switch (operation) {
- case OperationType::Unmap: {
- // Ensure that any pages we track close on exit.
- KPageGroup pages_to_close{m_kernel, this->GetBlockInfoManager()};
- SCOPE_EXIT({ pages_to_close.CloseAndReset(); });
-
- this->AddRegionToPages(addr, num_pages, pages_to_close);
+ case OperationType::Unmap:
m_system.Memory().UnmapRegion(*m_page_table_impl, addr, num_pages * PageSize);
break;
- }
- case OperationType::MapFirst:
case OperationType::Map: {
ASSERT(map_addr);
ASSERT(Common::IsAligned(map_addr, PageSize));
m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, num_pages * PageSize, map_addr);
-
- // Open references to pages, if we should.
- if (IsHeapPhysicalAddress(m_kernel.MemoryLayout(), map_addr)) {
- if (operation == OperationType::MapFirst) {
- m_kernel.MemoryManager().OpenFirst(map_addr, num_pages);
- } else {
- m_kernel.MemoryManager().Open(map_addr, num_pages);
- }
- }
break;
}
case OperationType::Separate: {
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h
index 0a454b05b..f1ca785d7 100644
--- a/src/core/hle/kernel/k_page_table.h
+++ b/src/core/hle/kernel/k_page_table.h
@@ -107,10 +107,6 @@ public:
return *m_page_table_impl;
}
- KBlockInfoManager* GetBlockInfoManager() {
- return m_block_info_manager;
- }
-
bool CanContain(VAddr addr, size_t size, KMemoryState state) const;
protected:
@@ -265,6 +261,10 @@ private:
void CleanupForIpcClientOnServerSetupFailure(PageLinkedList* page_list, VAddr address,
size_t size, KMemoryPermission prot_perm);
+ // HACK: These will be removed once we automatically manage page reference counts.
+ void HACK_OpenPages(PAddr phys_addr, size_t num_pages);
+ void HACK_ClosePages(VAddr virt_addr, size_t num_pages);
+
mutable KLightLock m_general_lock;
mutable KLightLock m_map_physical_memory_lock;
@@ -488,7 +488,6 @@ private:
std::unique_ptr<Common::PageTable> m_page_table_impl;
Core::System& m_system;
- KernelCore& m_kernel;
};
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp
index 3cf2b5d91..0aa68103c 100644
--- a/src/core/hle/kernel/k_shared_memory.cpp
+++ b/src/core/hle/kernel/k_shared_memory.cpp
@@ -13,7 +13,10 @@
namespace Kernel {
KSharedMemory::KSharedMemory(KernelCore& kernel_) : KAutoObjectWithSlabHeapAndContainer{kernel_} {}
-KSharedMemory::~KSharedMemory() = default;
+
+KSharedMemory::~KSharedMemory() {
+ kernel.GetSystemResourceLimit()->Release(LimitableResource::PhysicalMemoryMax, size);
+}
Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_,
Svc::MemoryPermission owner_permission_,
@@ -46,8 +49,7 @@ Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* o
R_UNLESS(physical_address != 0, ResultOutOfMemory);
//! Insert the result into our page group.
- page_group.emplace(kernel, &kernel.GetSystemSystemResource().GetBlockInfoManager());
- page_group->AddBlock(physical_address, num_pages);
+ page_group.emplace(physical_address, num_pages);
// Commit our reservation.
memory_reservation.Commit();
@@ -60,7 +62,7 @@ Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* o
is_initialized = true;
// Clear all pages in the memory.
- for (const auto& block : *page_group) {
+ for (const auto& block : page_group->Nodes()) {
std::memset(device_memory_.GetPointer<void>(block.GetAddress()), 0, block.GetSize());
}
@@ -69,8 +71,13 @@ Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* o
void KSharedMemory::Finalize() {
// Close and finalize the page group.
- page_group->Close();
- page_group->Finalize();
+ // page_group->Close();
+ // page_group->Finalize();
+
+ //! HACK: Manually close.
+ for (const auto& block : page_group->Nodes()) {
+ kernel.MemoryManager().Close(block.GetAddress(), block.GetNumPages());
+ }
// Release the memory reservation.
resource_limit->Release(LimitableResource::PhysicalMemoryMax, size);
diff --git a/src/core/hle/kernel/memory_types.h b/src/core/hle/kernel/memory_types.h
index 92b8b37ac..3975507bd 100644
--- a/src/core/hle/kernel/memory_types.h
+++ b/src/core/hle/kernel/memory_types.h
@@ -14,7 +14,4 @@ constexpr std::size_t PageSize{1 << PageBits};
using Page = std::array<u8, PageSize>;
-using KPhysicalAddress = PAddr;
-using KProcessAddress = VAddr;
-
} // namespace Kernel
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index aca442196..788ee2160 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1485,7 +1485,7 @@ static Result MapProcessMemory(Core::System& system, VAddr dst_address, Handle p
ResultInvalidMemoryRegion);
// Create a new page group.
- KPageGroup pg{system.Kernel(), dst_pt.GetBlockInfoManager()};
+ KPageGroup pg;
R_TRY(src_pt.MakeAndOpenPageGroup(
std::addressof(pg), src_address, size / PageSize, KMemoryState::FlagCanMapProcess,
KMemoryState::FlagCanMapProcess, KMemoryPermission::None, KMemoryPermission::None,
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp
index 4fa9f51a6..5d32adf64 100644
--- a/src/core/hle/service/nifm/nifm.cpp
+++ b/src/core/hle/service/nifm/nifm.cpp
@@ -22,15 +22,19 @@ namespace {
namespace Service::NIFM {
+// This is nn::nifm::RequestState
enum class RequestState : u32 {
NotSubmitted = 1,
- Error = 1, ///< The duplicate 1 is intentional; it means both not submitted and error on HW.
- Pending = 2,
- Connected = 3,
+ Invalid = 1, ///< The duplicate 1 is intentional; it means both not submitted and error on HW.
+ OnHold = 2,
+ Accepted = 3,
+ Blocking = 4,
};
-enum class InternetConnectionType : u8 {
- WiFi = 1,
+// This is nn::nifm::NetworkInterfaceType
+enum class NetworkInterfaceType : u32 {
+ Invalid = 0,
+ WiFi_Ieee80211 = 1,
Ethernet = 2,
};
@@ -42,14 +46,23 @@ enum class InternetConnectionStatus : u8 {
Connected,
};
+// This is nn::nifm::NetworkProfileType
+enum class NetworkProfileType : u32 {
+ User,
+ SsidList,
+ Temporary,
+};
+
+// This is nn::nifm::IpAddressSetting
struct IpAddressSetting {
bool is_automatic{};
- Network::IPv4Address current_address{};
+ Network::IPv4Address ip_address{};
Network::IPv4Address subnet_mask{};
- Network::IPv4Address gateway{};
+ Network::IPv4Address default_gateway{};
};
static_assert(sizeof(IpAddressSetting) == 0xD, "IpAddressSetting has incorrect size.");
+// This is nn::nifm::DnsSetting
struct DnsSetting {
bool is_automatic{};
Network::IPv4Address primary_dns{};
@@ -57,18 +70,26 @@ struct DnsSetting {
};
static_assert(sizeof(DnsSetting) == 0x9, "DnsSetting has incorrect size.");
+// This is nn::nifm::AuthenticationSetting
+struct AuthenticationSetting {
+ bool is_enabled{};
+ std::array<char, 0x20> user{};
+ std::array<char, 0x20> password{};
+};
+static_assert(sizeof(AuthenticationSetting) == 0x41, "AuthenticationSetting has incorrect size.");
+
+// This is nn::nifm::ProxySetting
struct ProxySetting {
- bool enabled{};
+ bool is_enabled{};
INSERT_PADDING_BYTES(1);
u16 port{};
std::array<char, 0x64> proxy_server{};
- bool automatic_auth_enabled{};
- std::array<char, 0x20> user{};
- std::array<char, 0x20> password{};
+ AuthenticationSetting authentication{};
INSERT_PADDING_BYTES(1);
};
static_assert(sizeof(ProxySetting) == 0xAA, "ProxySetting has incorrect size.");
+// This is nn::nifm::IpSettingData
struct IpSettingData {
IpAddressSetting ip_address_setting{};
DnsSetting dns_setting{};
@@ -101,6 +122,7 @@ static_assert(sizeof(NifmWirelessSettingData) == 0x70,
"NifmWirelessSettingData has incorrect size.");
#pragma pack(push, 1)
+// This is nn::nifm::detail::sf::NetworkProfileData
struct SfNetworkProfileData {
IpSettingData ip_setting_data{};
u128 uuid{};
@@ -114,13 +136,14 @@ struct SfNetworkProfileData {
};
static_assert(sizeof(SfNetworkProfileData) == 0x17C, "SfNetworkProfileData has incorrect size.");
+// This is nn::nifm::NetworkProfileData
struct NifmNetworkProfileData {
u128 uuid{};
std::array<char, 0x40> network_name{};
- u32 unknown_1{};
- u32 unknown_2{};
- u8 unknown_3{};
- u8 unknown_4{};
+ NetworkProfileType network_profile_type{};
+ NetworkInterfaceType network_interface_type{};
+ bool is_auto_connect{};
+ bool is_large_capacity{};
INSERT_PADDING_BYTES(2);
NifmWirelessSettingData wireless_setting_data{};
IpSettingData ip_setting_data{};
@@ -184,6 +207,7 @@ public:
event1 = CreateKEvent(service_context, "IRequest:Event1");
event2 = CreateKEvent(service_context, "IRequest:Event2");
+ state = RequestState::NotSubmitted;
}
~IRequest() override {
@@ -196,7 +220,7 @@ private:
LOG_WARNING(Service_NIFM, "(STUBBED) called");
if (state == RequestState::NotSubmitted) {
- UpdateState(RequestState::Pending);
+ UpdateState(RequestState::OnHold);
}
IPC::ResponseBuilder rb{ctx, 2};
@@ -219,14 +243,14 @@ private:
switch (state) {
case RequestState::NotSubmitted:
return has_connection ? ResultSuccess : ResultNetworkCommunicationDisabled;
- case RequestState::Pending:
+ case RequestState::OnHold:
if (has_connection) {
- UpdateState(RequestState::Connected);
+ UpdateState(RequestState::Accepted);
} else {
- UpdateState(RequestState::Error);
+ UpdateState(RequestState::Invalid);
}
return ResultPendingConnection;
- case RequestState::Connected:
+ case RequestState::Accepted:
default:
return ResultSuccess;
}
@@ -338,9 +362,9 @@ void IGeneralService::GetCurrentNetworkProfile(Kernel::HLERequestContext& ctx) {
.ip_setting_data{
.ip_address_setting{
.is_automatic{true},
- .current_address{Network::TranslateIPv4(net_iface->ip_address)},
+ .ip_address{Network::TranslateIPv4(net_iface->ip_address)},
.subnet_mask{Network::TranslateIPv4(net_iface->subnet_mask)},
- .gateway{Network::TranslateIPv4(net_iface->gateway)},
+ .default_gateway{Network::TranslateIPv4(net_iface->gateway)},
},
.dns_setting{
.is_automatic{true},
@@ -348,12 +372,14 @@ void IGeneralService::GetCurrentNetworkProfile(Kernel::HLERequestContext& ctx) {
.secondary_dns{1, 0, 0, 1},
},
.proxy_setting{
- .enabled{false},
+ .is_enabled{false},
.port{},
.proxy_server{},
- .automatic_auth_enabled{},
- .user{},
- .password{},
+ .authentication{
+ .is_enabled{},
+ .user{},
+ .password{},
+ },
},
.mtu{1500},
},
@@ -370,7 +396,7 @@ void IGeneralService::GetCurrentNetworkProfile(Kernel::HLERequestContext& ctx) {
// When we're connected to a room, spoof the hosts IP address
if (auto room_member = network.GetRoomMember().lock()) {
if (room_member->IsConnected()) {
- network_profile_data.ip_setting_data.ip_address_setting.current_address =
+ network_profile_data.ip_setting_data.ip_address_setting.ip_address =
room_member->GetFakeIpAddress();
}
}
@@ -444,9 +470,9 @@ void IGeneralService::GetCurrentIpConfigInfo(Kernel::HLERequestContext& ctx) {
return IpConfigInfo{
.ip_address_setting{
.is_automatic{true},
- .current_address{Network::TranslateIPv4(net_iface->ip_address)},
+ .ip_address{Network::TranslateIPv4(net_iface->ip_address)},
.subnet_mask{Network::TranslateIPv4(net_iface->subnet_mask)},
- .gateway{Network::TranslateIPv4(net_iface->gateway)},
+ .default_gateway{Network::TranslateIPv4(net_iface->gateway)},
},
.dns_setting{
.is_automatic{true},
@@ -459,7 +485,7 @@ void IGeneralService::GetCurrentIpConfigInfo(Kernel::HLERequestContext& ctx) {
// When we're connected to a room, spoof the hosts IP address
if (auto room_member = network.GetRoomMember().lock()) {
if (room_member->IsConnected()) {
- ip_config_info.ip_address_setting.current_address = room_member->GetFakeIpAddress();
+ ip_config_info.ip_address_setting.ip_address = room_member->GetFakeIpAddress();
}
}
@@ -480,7 +506,7 @@ void IGeneralService::GetInternetConnectionStatus(Kernel::HLERequestContext& ctx
LOG_WARNING(Service_NIFM, "(STUBBED) called");
struct Output {
- InternetConnectionType type{InternetConnectionType::WiFi};
+ u8 type{static_cast<u8>(NetworkInterfaceType::WiFi_Ieee80211)};
u8 wifi_strength{3};
InternetConnectionStatus state{InternetConnectionStatus::Connected};
};
diff --git a/src/dedicated_room/CMakeLists.txt b/src/dedicated_room/CMakeLists.txt
index 5bbe1d4b5..136109a0c 100644
--- a/src/dedicated_room/CMakeLists.txt
+++ b/src/dedicated_room/CMakeLists.txt
@@ -1,8 +1,6 @@
# SPDX-FileCopyrightText: 2017 Citra Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules)
-
add_executable(yuzu-room
precompiled_headers.h
yuzu_room.cpp
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 4a7d35617..dfc675cc8 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -5,7 +5,6 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules)
# Set the RPATH for Qt Libraries
# This must be done before the `yuzu` target is created
diff --git a/src/yuzu/debugger/controller.cpp b/src/yuzu/debugger/controller.cpp
index e4bf16a04..19f3775a3 100644
--- a/src/yuzu/debugger/controller.cpp
+++ b/src/yuzu/debugger/controller.cpp
@@ -93,7 +93,7 @@ void ControllerDialog::ControllerUpdate(Core::HID::ControllerTriggerType type) {
case Core::HID::ControllerTriggerType::Button:
case Core::HID::ControllerTriggerType::Stick: {
const auto buttons_values = controller->GetButtonsValues();
- const auto stick_values = controller->GetSticksValues();
+ const auto stick_values = controller->GetSticks();
u64 buttons = 0;
std::size_t index = 0;
for (const auto& button : buttons_values) {
@@ -101,12 +101,12 @@ void ControllerDialog::ControllerUpdate(Core::HID::ControllerTriggerType type) {
index++;
}
const InputCommon::TasInput::TasAnalog left_axis = {
- .x = stick_values[Settings::NativeAnalog::LStick].x.value,
- .y = stick_values[Settings::NativeAnalog::LStick].y.value,
+ .x = stick_values.left.x / 32767.f,
+ .y = stick_values.left.y / 32767.f,
};
const InputCommon::TasInput::TasAnalog right_axis = {
- .x = stick_values[Settings::NativeAnalog::RStick].x.value,
- .y = stick_values[Settings::NativeAnalog::RStick].y.value,
+ .x = stick_values.right.x / 32767.f,
+ .y = stick_values.right.y / 32767.f,
};
input_subsystem->GetTas()->RecordInput(buttons, left_axis, right_axis);
break;
diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt
index 61b6cc4e0..46eddf423 100644
--- a/src/yuzu_cmd/CMakeLists.txt
+++ b/src/yuzu_cmd/CMakeLists.txt
@@ -1,8 +1,6 @@
# SPDX-FileCopyrightText: 2018 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules)
-
# Credits to Samantas5855 and others for this function.
function(create_resource file output filename)
# Read hex data from file