From fb49ec19c1fb6030fcc960077e82c998290d0ab8 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 17 Mar 2023 21:26:04 -0400 Subject: kernel: use KTypedAddress for addresses --- src/common/CMakeLists.txt | 1 + src/common/typed_address.h | 320 +++++++++++++++++ src/core/CMakeLists.txt | 1 + src/core/arm/arm_interface.cpp | 10 +- src/core/arm/arm_interface.h | 8 +- src/core/arm/dynarmic/arm_dynarmic_32.cpp | 6 +- src/core/arm/dynarmic/arm_dynarmic_32.h | 6 +- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 8 +- src/core/arm/dynarmic/arm_dynarmic_64.h | 6 +- src/core/core.cpp | 4 +- src/core/core.h | 4 +- src/core/debugger/gdbstub.cpp | 36 +- src/core/device_memory.h | 14 +- .../kernel/board/nintendo/nx/k_memory_layout.cpp | 12 +- .../hle/kernel/board/nintendo/nx/k_memory_layout.h | 4 +- .../kernel/board/nintendo/nx/k_system_control.cpp | 2 +- .../kernel/board/nintendo/nx/k_system_control.h | 4 +- src/core/hle/kernel/code_set.h | 6 +- src/core/hle/kernel/init/init_slab_setup.cpp | 21 +- src/core/hle/kernel/initial_process.h | 2 +- src/core/hle/kernel/k_address_arbiter.cpp | 32 +- src/core/hle/kernel/k_address_arbiter.h | 14 +- src/core/hle/kernel/k_client_session.cpp | 3 +- src/core/hle/kernel/k_code_memory.cpp | 11 +- src/core/hle/kernel/k_code_memory.h | 16 +- src/core/hle/kernel/k_condition_variable.cpp | 22 +- src/core/hle/kernel/k_condition_variable.h | 8 +- src/core/hle/kernel/k_device_address_space.cpp | 8 +- src/core/hle/kernel/k_device_address_space.h | 13 +- src/core/hle/kernel/k_dynamic_page_manager.h | 19 +- src/core/hle/kernel/k_dynamic_slab_heap.h | 6 +- src/core/hle/kernel/k_memory_block.h | 22 +- src/core/hle/kernel/k_memory_block_manager.cpp | 68 ++-- src/core/hle/kernel/k_memory_block_manager.h | 32 +- src/core/hle/kernel/k_memory_layout.cpp | 13 +- src/core/hle/kernel/k_memory_layout.h | 78 ++-- src/core/hle/kernel/k_memory_manager.cpp | 51 +-- src/core/hle/kernel/k_memory_manager.h | 48 +-- src/core/hle/kernel/k_memory_region.h | 8 +- src/core/hle/kernel/k_page_buffer.cpp | 4 +- src/core/hle/kernel/k_page_buffer.h | 2 +- src/core/hle/kernel/k_page_group.h | 2 +- src/core/hle/kernel/k_page_heap.cpp | 40 +-- src/core/hle/kernel/k_page_heap.h | 48 +-- src/core/hle/kernel/k_page_table.cpp | 392 +++++++++++---------- src/core/hle/kernel/k_page_table.h | 241 +++++++------ src/core/hle/kernel/k_page_table_manager.h | 14 +- src/core/hle/kernel/k_page_table_slab_heap.h | 12 +- src/core/hle/kernel/k_process.cpp | 35 +- src/core/hle/kernel/k_process.h | 43 +-- src/core/hle/kernel/k_scheduler.cpp | 2 +- src/core/hle/kernel/k_session_request.cpp | 15 +- src/core/hle/kernel/k_session_request.h | 55 +-- src/core/hle/kernel/k_shared_memory.cpp | 5 +- src/core/hle/kernel/k_shared_memory.h | 8 +- src/core/hle/kernel/k_system_resource.h | 2 +- src/core/hle/kernel/k_thread.cpp | 28 +- src/core/hle/kernel/k_thread.h | 58 +-- src/core/hle/kernel/k_thread_local_page.cpp | 6 +- src/core/hle/kernel/k_thread_local_page.h | 25 +- src/core/hle/kernel/k_transfer_memory.cpp | 2 +- src/core/hle/kernel/k_transfer_memory.h | 6 +- src/core/hle/kernel/k_typed_address.h | 12 + src/core/hle/kernel/kernel.cpp | 108 +++--- src/core/hle/kernel/kernel.h | 3 +- src/core/hle/kernel/memory_types.h | 4 +- src/core/hle/kernel/svc/svc_address_arbiter.cpp | 8 +- src/core/hle/kernel/svc/svc_code_memory.cpp | 4 +- src/core/hle/kernel/svc/svc_condition_variable.cpp | 4 +- src/core/hle/kernel/svc/svc_debug_string.cpp | 2 +- src/core/hle/kernel/svc/svc_exception.cpp | 2 +- src/core/hle/kernel/svc/svc_info.cpp | 10 +- src/core/hle/kernel/svc/svc_lock.cpp | 4 +- src/core/hle/kernel/svc/svc_memory.cpp | 13 +- src/core/hle/kernel/svc/svc_physical_memory.cpp | 6 +- src/core/hle/kernel/svc/svc_port.cpp | 2 +- src/core/hle/kernel/svc/svc_process.cpp | 2 +- src/core/hle/kernel/svc/svc_process_memory.cpp | 12 +- src/core/hle/kernel/svc/svc_query_memory.cpp | 2 +- src/core/hle/kernel/svc/svc_shared_memory.cpp | 4 +- src/core/hle/kernel/svc/svc_synchronization.cpp | 2 +- src/core/hle/kernel/svc/svc_thread.cpp | 8 +- src/core/hle/kernel/svc/svc_transfer_memory.cpp | 2 +- src/core/hle/kernel/svc_types.h | 4 +- .../service/hid/controllers/console_sixaxis.cpp | 2 +- .../hle/service/hid/controllers/console_sixaxis.h | 6 +- src/core/hle/service/hid/controllers/palma.cpp | 2 +- src/core/hle/service/hid/controllers/palma.h | 6 +- src/core/hle/service/hid/hidbus/hidbus_base.cpp | 2 +- src/core/hle/service/hid/hidbus/hidbus_base.h | 6 +- .../hid/irsensor/image_transfer_processor.cpp | 2 +- .../hid/irsensor/image_transfer_processor.h | 6 +- src/core/hle/service/jit/jit.cpp | 6 +- src/core/hle/service/ldr/ldr.cpp | 5 +- src/core/loader/deconstructed_rom_directory.cpp | 2 +- src/core/loader/kip.cpp | 2 +- src/core/loader/nso.cpp | 2 +- src/core/memory.cpp | 319 +++++++++-------- src/core/memory.h | 88 ++--- src/core/memory/cheat_engine.cpp | 6 +- src/core/reporter.cpp | 4 +- 101 files changed, 1574 insertions(+), 1102 deletions(-) create mode 100644 src/common/typed_address.h create mode 100644 src/core/hle/kernel/k_typed_address.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 61ab68864..90805babe 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -132,6 +132,7 @@ add_library(common STATIC time_zone.h tiny_mt.h tree.h + typed_address.h uint128.h unique_function.h uuid.cpp diff --git a/src/common/typed_address.h b/src/common/typed_address.h new file mode 100644 index 000000000..cf7bbeae1 --- /dev/null +++ b/src/common/typed_address.h @@ -0,0 +1,320 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include + +#include "common/common_types.h" + +namespace Common { + +template +class TypedAddress { +public: + // Constructors. + constexpr inline TypedAddress() : m_address(0) {} + constexpr inline TypedAddress(uint64_t a) : m_address(a) {} + + template + constexpr inline explicit TypedAddress(const U* ptr) + : m_address(reinterpret_cast(ptr)) {} + + // Copy constructor. + constexpr inline TypedAddress(const TypedAddress& rhs) = default; + + // Assignment operator. + constexpr inline TypedAddress& operator=(const TypedAddress& rhs) = default; + + // Arithmetic operators. + template + constexpr inline TypedAddress operator+(I rhs) const { + static_assert(std::is_integral_v); + return m_address + rhs; + } + + constexpr inline TypedAddress operator+(TypedAddress rhs) const { + return m_address + rhs.m_address; + } + + constexpr inline TypedAddress operator++() { + return ++m_address; + } + + constexpr inline TypedAddress operator++(int) { + return m_address++; + } + + template + constexpr inline TypedAddress operator-(I rhs) const { + static_assert(std::is_integral_v); + return m_address - rhs; + } + + constexpr inline ptrdiff_t operator-(TypedAddress rhs) const { + return m_address - rhs.m_address; + } + + constexpr inline TypedAddress operator--() { + return --m_address; + } + + constexpr inline TypedAddress operator--(int) { + return m_address--; + } + + template + constexpr inline TypedAddress operator+=(I rhs) { + static_assert(std::is_integral_v); + m_address += rhs; + return *this; + } + + template + constexpr inline TypedAddress operator-=(I rhs) { + static_assert(std::is_integral_v); + m_address -= rhs; + return *this; + } + + // Logical operators. + constexpr inline uint64_t operator&(uint64_t mask) const { + return m_address & mask; + } + + constexpr inline uint64_t operator|(uint64_t mask) const { + return m_address | mask; + } + + template + constexpr inline TypedAddress operator|=(I rhs) { + static_assert(std::is_integral_v); + m_address |= rhs; + return *this; + } + + constexpr inline uint64_t operator<<(int shift) const { + return m_address << shift; + } + + constexpr inline uint64_t operator>>(int shift) const { + return m_address >> shift; + } + + template + constexpr inline size_t operator/(U size) const { + return m_address / size; + } + + constexpr explicit operator bool() const { + return m_address != 0; + } + + // constexpr inline uint64_t operator%(U align) const { return m_address % align; } + + // Comparison operators. + constexpr bool operator==(const TypedAddress&) const = default; + constexpr bool operator!=(const TypedAddress&) const = default; + constexpr auto operator<=>(const TypedAddress&) const = default; + + // For convenience, also define comparison operators versus uint64_t. + constexpr inline bool operator==(uint64_t rhs) const { + return m_address == rhs; + } + + constexpr inline bool operator!=(uint64_t rhs) const { + return m_address != rhs; + } + + // Allow getting the address explicitly, for use in accessors. + constexpr inline uint64_t GetValue() const { + return m_address; + } + +private: + uint64_t m_address{}; +}; + +struct PhysicalAddressTag {}; +struct VirtualAddressTag {}; +struct ProcessAddressTag {}; + +using PhysicalAddress = TypedAddress; +using VirtualAddress = TypedAddress; +using ProcessAddress = TypedAddress; + +// Define accessors. +template +concept IsTypedAddress = std::same_as || std::same_as || + std::same_as; + +template +constexpr inline T Null = [] { + if constexpr (std::is_same::value) { + return 0; + } else { + static_assert(std::is_same::value || + std::is_same::value || + std::is_same::value); + return T(0); + } +}(); + +// Basic type validations. +static_assert(sizeof(PhysicalAddress) == sizeof(uint64_t)); +static_assert(sizeof(VirtualAddress) == sizeof(uint64_t)); +static_assert(sizeof(ProcessAddress) == sizeof(uint64_t)); + +static_assert(std::is_trivially_copyable_v); +static_assert(std::is_trivially_copyable_v); +static_assert(std::is_trivially_copyable_v); + +static_assert(std::is_trivially_copy_constructible_v); +static_assert(std::is_trivially_copy_constructible_v); +static_assert(std::is_trivially_copy_constructible_v); + +static_assert(std::is_trivially_move_constructible_v); +static_assert(std::is_trivially_move_constructible_v); +static_assert(std::is_trivially_move_constructible_v); + +static_assert(std::is_trivially_copy_assignable_v); +static_assert(std::is_trivially_copy_assignable_v); +static_assert(std::is_trivially_copy_assignable_v); + +static_assert(std::is_trivially_move_assignable_v); +static_assert(std::is_trivially_move_assignable_v); +static_assert(std::is_trivially_move_assignable_v); + +static_assert(std::is_trivially_destructible_v); +static_assert(std::is_trivially_destructible_v); +static_assert(std::is_trivially_destructible_v); + +static_assert(Null == 0); +static_assert(Null == Null); +static_assert(Null == Null); +static_assert(Null == Null); + +// Constructor/assignment validations. +static_assert([] { + const PhysicalAddress a(5); + PhysicalAddress b(a); + return b; +}() == PhysicalAddress(5)); +static_assert([] { + const PhysicalAddress a(5); + PhysicalAddress b(10); + b = a; + return b; +}() == PhysicalAddress(5)); + +// Arithmetic validations. +static_assert(PhysicalAddress(10) + 5 == PhysicalAddress(15)); +static_assert(PhysicalAddress(10) - 5 == PhysicalAddress(5)); +static_assert([] { + PhysicalAddress v(10); + v += 5; + return v; +}() == PhysicalAddress(15)); +static_assert([] { + PhysicalAddress v(10); + v -= 5; + return v; +}() == PhysicalAddress(5)); +static_assert(PhysicalAddress(10)++ == PhysicalAddress(10)); +static_assert(++PhysicalAddress(10) == PhysicalAddress(11)); +static_assert(PhysicalAddress(10)-- == PhysicalAddress(10)); +static_assert(--PhysicalAddress(10) == PhysicalAddress(9)); + +// Logical validations. +static_assert((PhysicalAddress(0b11111111) >> 1) == 0b01111111); +static_assert((PhysicalAddress(0b10101010) >> 1) == 0b01010101); +static_assert((PhysicalAddress(0b11111111) << 1) == 0b111111110); +static_assert((PhysicalAddress(0b01010101) << 1) == 0b10101010); +static_assert((PhysicalAddress(0b11111111) & 0b01010101) == 0b01010101); +static_assert((PhysicalAddress(0b11111111) & 0b10101010) == 0b10101010); +static_assert((PhysicalAddress(0b01010101) & 0b10101010) == 0b00000000); +static_assert((PhysicalAddress(0b00000000) | 0b01010101) == 0b01010101); +static_assert((PhysicalAddress(0b11111111) | 0b01010101) == 0b11111111); +static_assert((PhysicalAddress(0b10101010) | 0b01010101) == 0b11111111); + +// Comparisons. +static_assert(PhysicalAddress(0) == PhysicalAddress(0)); +static_assert(PhysicalAddress(0) != PhysicalAddress(1)); +static_assert(PhysicalAddress(0) < PhysicalAddress(1)); +static_assert(PhysicalAddress(0) <= PhysicalAddress(1)); +static_assert(PhysicalAddress(1) > PhysicalAddress(0)); +static_assert(PhysicalAddress(1) >= PhysicalAddress(0)); + +static_assert(!(PhysicalAddress(0) == PhysicalAddress(1))); +static_assert(!(PhysicalAddress(0) != PhysicalAddress(0))); +static_assert(!(PhysicalAddress(1) < PhysicalAddress(0))); +static_assert(!(PhysicalAddress(1) <= PhysicalAddress(0))); +static_assert(!(PhysicalAddress(0) > PhysicalAddress(1))); +static_assert(!(PhysicalAddress(0) >= PhysicalAddress(1))); + +} // namespace Common + +template +constexpr inline uint64_t GetInteger(Common::TypedAddress address) { + return address.GetValue(); +} + +template <> +struct fmt::formatter { + constexpr auto parse(fmt::format_parse_context& ctx) { + return ctx.begin(); + } + template + auto format(const Common::PhysicalAddress& addr, FormatContext& ctx) { + return fmt::format_to(ctx.out(), "{:#x}", static_cast(addr.GetValue())); + } +}; + +template <> +struct fmt::formatter { + constexpr auto parse(fmt::format_parse_context& ctx) { + return ctx.begin(); + } + template + auto format(const Common::ProcessAddress& addr, FormatContext& ctx) { + return fmt::format_to(ctx.out(), "{:#x}", static_cast(addr.GetValue())); + } +}; + +template <> +struct fmt::formatter { + constexpr auto parse(fmt::format_parse_context& ctx) { + return ctx.begin(); + } + template + auto format(const Common::VirtualAddress& addr, FormatContext& ctx) { + return fmt::format_to(ctx.out(), "{:#x}", static_cast(addr.GetValue())); + } +}; + +namespace std { + +template <> +struct hash { + size_t operator()(const Common::PhysicalAddress& k) const noexcept { + return k.GetValue(); + } +}; + +template <> +struct hash { + size_t operator()(const Common::ProcessAddress& k) const noexcept { + return k.GetValue(); + } +}; + +template <> +struct hash { + size_t operator()(const Common::VirtualAddress& k) const noexcept { + return k.GetValue(); + } +}; + +} // namespace std diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 378e6c023..4e677f287 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -278,6 +278,7 @@ add_library(core STATIC hle/kernel/k_trace.h hle/kernel/k_transfer_memory.cpp hle/kernel/k_transfer_memory.h + hle/kernel/k_typed_address.h hle/kernel/k_worker_task.h hle/kernel/k_worker_task_manager.cpp hle/kernel/k_worker_task_manager.h diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index 4a331d4c1..be3f55cd2 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp @@ -168,21 +168,21 @@ void ARM_Interface::LoadWatchpointArray(const WatchpointArray& wp) { } const Kernel::DebugWatchpoint* ARM_Interface::MatchingWatchpoint( - VAddr addr, u64 size, Kernel::DebugWatchpointType access_type) const { + u64 addr, u64 size, Kernel::DebugWatchpointType access_type) const { if (!watchpoints) { return nullptr; } - const VAddr start_address{addr}; - const VAddr end_address{addr + size}; + const u64 start_address{addr}; + const u64 end_address{addr + size}; for (size_t i = 0; i < Core::Hardware::NUM_WATCHPOINTS; i++) { const auto& watch{(*watchpoints)[i]}; - if (end_address <= watch.start_address) { + if (end_address <= GetInteger(watch.start_address)) { continue; } - if (start_address >= watch.end_address) { + if (start_address >= GetInteger(watch.end_address)) { continue; } if ((access_type & watch.type) == Kernel::DebugWatchpointType::None) { diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index c40771c97..8e40702cc 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -78,7 +78,7 @@ public: * @param addr Start address of the cache range to clear * @param size Size of the cache range to clear, starting at addr */ - virtual void InvalidateCacheRange(VAddr addr, std::size_t size) = 0; + virtual void InvalidateCacheRange(u64 addr, std::size_t size) = 0; /** * Notifies CPU emulation that the current page table has changed. @@ -149,9 +149,9 @@ public: */ virtual void SetPSTATE(u32 pstate) = 0; - virtual VAddr GetTlsAddress() const = 0; + virtual u64 GetTlsAddress() const = 0; - virtual void SetTlsAddress(VAddr address) = 0; + virtual void SetTlsAddress(u64 address) = 0; /** * Gets the value within the TPIDR_EL0 (read/write software thread ID) register. @@ -214,7 +214,7 @@ protected: static void SymbolicateBacktrace(Core::System& system, std::vector& out); const Kernel::DebugWatchpoint* MatchingWatchpoint( - VAddr addr, u64 size, Kernel::DebugWatchpointType access_type) const; + u64 addr, u64 size, Kernel::DebugWatchpointType access_type) const; virtual Dynarmic::HaltReason RunJit() = 0; virtual Dynarmic::HaltReason StepJit() = 0; diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 2a7570073..aa92d3fc3 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -155,7 +155,7 @@ public: return std::max(parent.system.CoreTiming().GetDowncount(), 0); } - bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) { + bool CheckMemoryAccess(u64 addr, u64 size, Kernel::DebugWatchpointType type) { if (!check_memory_access) { return true; } @@ -397,7 +397,7 @@ u64 ARM_Dynarmic_32::GetTlsAddress() const { return cp15->uro; } -void ARM_Dynarmic_32::SetTlsAddress(VAddr address) { +void ARM_Dynarmic_32::SetTlsAddress(u64 address) { cp15->uro = static_cast(address); } @@ -439,7 +439,7 @@ void ARM_Dynarmic_32::ClearInstructionCache() { jit.load()->ClearCache(); } -void ARM_Dynarmic_32::InvalidateCacheRange(VAddr addr, std::size_t size) { +void ARM_Dynarmic_32::InvalidateCacheRange(u64 addr, std::size_t size) { jit.load()->InvalidateCacheRange(static_cast(addr), size); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index d24ba2289..bce695daf 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h @@ -41,8 +41,8 @@ public: void SetVectorReg(int index, u128 value) override; u32 GetPSTATE() const override; void SetPSTATE(u32 pstate) override; - VAddr GetTlsAddress() const override; - void SetTlsAddress(VAddr address) override; + u64 GetTlsAddress() const override; + void SetTlsAddress(u64 address) override; void SetTPIDR_EL0(u64 value) override; u64 GetTPIDR_EL0() const override; @@ -60,7 +60,7 @@ public: void ClearExclusiveState() override; void ClearInstructionCache() override; - void InvalidateCacheRange(VAddr addr, std::size_t size) override; + void InvalidateCacheRange(u64 addr, std::size_t size) override; void PageTableChanged(Common::PageTable& new_page_table, std::size_t new_address_space_size_in_bits) override; diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 7229fdc2a..67073c84d 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -117,7 +117,7 @@ public: } void InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op, - VAddr value) override { + u64 value) override { switch (op) { case Dynarmic::A64::InstructionCacheOperation::InvalidateByVAToPoU: { static constexpr u64 ICACHE_LINE_SIZE = 64; @@ -199,7 +199,7 @@ public: return parent.system.CoreTiming().GetClockTicks(); } - bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) { + bool CheckMemoryAccess(u64 addr, u64 size, Kernel::DebugWatchpointType type) { if (!check_memory_access) { return true; } @@ -452,7 +452,7 @@ u64 ARM_Dynarmic_64::GetTlsAddress() const { return cb->tpidrro_el0; } -void ARM_Dynarmic_64::SetTlsAddress(VAddr address) { +void ARM_Dynarmic_64::SetTlsAddress(u64 address) { cb->tpidrro_el0 = address; } @@ -500,7 +500,7 @@ void ARM_Dynarmic_64::ClearInstructionCache() { jit.load()->ClearCache(); } -void ARM_Dynarmic_64::InvalidateCacheRange(VAddr addr, std::size_t size) { +void ARM_Dynarmic_64::InvalidateCacheRange(u64 addr, std::size_t size) { jit.load()->InvalidateCacheRange(addr, size); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index ed1a5eb96..e83599e82 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h @@ -38,8 +38,8 @@ public: void SetVectorReg(int index, u128 value) override; u32 GetPSTATE() const override; void SetPSTATE(u32 pstate) override; - VAddr GetTlsAddress() const override; - void SetTlsAddress(VAddr address) override; + u64 GetTlsAddress() const override; + void SetTlsAddress(u64 address) override; void SetTPIDR_EL0(u64 value) override; u64 GetTPIDR_EL0() const override; @@ -53,7 +53,7 @@ public: void ClearExclusiveState() override; void ClearInstructionCache() override; - void InvalidateCacheRange(VAddr addr, std::size_t size) override; + void InvalidateCacheRange(u64 addr, std::size_t size) override; void PageTableChanged(Common::PageTable& new_page_table, std::size_t new_address_space_size_in_bits) override; diff --git a/src/core/core.cpp b/src/core/core.cpp index d2b597068..f6273ac39 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -564,7 +564,7 @@ void System::InvalidateCpuInstructionCaches() { impl->kernel.InvalidateAllInstructionCaches(); } -void System::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) { +void System::InvalidateCpuInstructionCacheRange(u64 addr, std::size_t size) { impl->kernel.InvalidateCpuInstructionCacheRange(addr, size); } @@ -794,7 +794,7 @@ FileSys::VirtualFilesystem System::GetFilesystem() const { } void System::RegisterCheatList(const std::vector& list, - const std::array& build_id, VAddr main_region_begin, + const std::array& build_id, u64 main_region_begin, u64 main_region_size) { impl->cheat_engine = std::make_unique(*this, list, build_id); impl->cheat_engine->SetMainMemoryParameters(main_region_begin, main_region_size); diff --git a/src/core/core.h b/src/core/core.h index 5843696d4..7032240be 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -172,7 +172,7 @@ public: */ void InvalidateCpuInstructionCaches(); - void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); + void InvalidateCpuInstructionCacheRange(u64 addr, std::size_t size); /// Shutdown the main emulated process. void ShutdownMainProcess(); @@ -353,7 +353,7 @@ public: [[nodiscard]] FileSys::VirtualFilesystem GetFilesystem() const; void RegisterCheatList(const std::vector& list, - const std::array& build_id, VAddr main_region_begin, + const std::array& build_id, u64 main_region_begin, u64 main_region_size); void SetAppletFrontendSet(Service::AM::Applets::AppletFrontendSet&& set); diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp index b2fe6bd7d..5cfb66b93 100644 --- a/src/core/debugger/gdbstub.cpp +++ b/src/core/debugger/gdbstub.cpp @@ -118,14 +118,14 @@ void GDBStub::Watchpoint(Kernel::KThread* thread, const Kernel::DebugWatchpoint& switch (watch.type) { case Kernel::DebugWatchpointType::Read: - SendReply(fmt::format("{}rwatch:{:x};", status, watch.start_address)); + SendReply(fmt::format("{}rwatch:{:x};", status, GetInteger(watch.start_address))); break; case Kernel::DebugWatchpointType::Write: - SendReply(fmt::format("{}watch:{:x};", status, watch.start_address)); + SendReply(fmt::format("{}watch:{:x};", status, GetInteger(watch.start_address))); break; case Kernel::DebugWatchpointType::ReadOrWrite: default: - SendReply(fmt::format("{}awatch:{:x};", status, watch.start_address)); + SendReply(fmt::format("{}awatch:{:x};", status, GetInteger(watch.start_address))); break; } } @@ -554,8 +554,9 @@ void GDBStub::HandleQuery(std::string_view command) { if (main != modules.end()) { SendReply(fmt::format("TextSeg={:x}", main->first)); } else { - SendReply(fmt::format("TextSeg={:x}", - system.ApplicationProcess()->PageTable().GetCodeRegionStart())); + SendReply(fmt::format( + "TextSeg={:x}", + GetInteger(system.ApplicationProcess()->PageTable().GetCodeRegionStart()))); } } else if (command.starts_with("Xfer:libraries:read::")) { Loader::AppLoader::Modules modules; @@ -757,17 +758,20 @@ void GDBStub::HandleRcmd(const std::vector& command) { reply = fmt::format("Process: {:#x} ({})\n" "Program Id: {:#018x}\n", process->GetProcessId(), process->GetName(), process->GetProgramId()); - reply += - fmt::format("Layout:\n" - " Alias: {:#012x} - {:#012x}\n" - " Heap: {:#012x} - {:#012x}\n" - " Aslr: {:#012x} - {:#012x}\n" - " Stack: {:#012x} - {:#012x}\n" - "Modules:\n", - page_table.GetAliasRegionStart(), page_table.GetAliasRegionEnd(), - page_table.GetHeapRegionStart(), page_table.GetHeapRegionEnd(), - page_table.GetAliasCodeRegionStart(), page_table.GetAliasCodeRegionEnd(), - page_table.GetStackRegionStart(), page_table.GetStackRegionEnd()); + reply += fmt::format("Layout:\n" + " Alias: {:#012x} - {:#012x}\n" + " Heap: {:#012x} - {:#012x}\n" + " Aslr: {:#012x} - {:#012x}\n" + " Stack: {:#012x} - {:#012x}\n" + "Modules:\n", + GetInteger(page_table.GetAliasRegionStart()), + GetInteger(page_table.GetAliasRegionEnd()), + GetInteger(page_table.GetHeapRegionStart()), + GetInteger(page_table.GetHeapRegionEnd()), + GetInteger(page_table.GetAliasCodeRegionStart()), + GetInteger(page_table.GetAliasCodeRegionEnd()), + GetInteger(page_table.GetStackRegionStart()), + GetInteger(page_table.GetStackRegionEnd())); for (const auto& [vaddr, name] : modules) { reply += fmt::format(" {:#012x} - {:#012x} {}\n", vaddr, diff --git a/src/core/device_memory.h b/src/core/device_memory.h index 90510733c..13388b73e 100644 --- a/src/core/device_memory.h +++ b/src/core/device_memory.h @@ -3,8 +3,8 @@ #pragma once -#include "common/common_types.h" #include "common/host_memory.h" +#include "common/typed_address.h" namespace Core { @@ -25,20 +25,22 @@ public: DeviceMemory(const DeviceMemory&) = delete; template - PAddr GetPhysicalAddr(const T* ptr) const { + Common::PhysicalAddress GetPhysicalAddr(const T* ptr) const { return (reinterpret_cast(ptr) - reinterpret_cast(buffer.BackingBasePointer())) + DramMemoryMap::Base; } template - T* GetPointer(PAddr addr) { - return reinterpret_cast(buffer.BackingBasePointer() + (addr - DramMemoryMap::Base)); + T* GetPointer(Common::PhysicalAddress addr) { + return reinterpret_cast(buffer.BackingBasePointer() + + (GetInteger(addr) - DramMemoryMap::Base)); } template - const T* GetPointer(PAddr addr) const { - return reinterpret_cast(buffer.BackingBasePointer() + (addr - DramMemoryMap::Base)); + const T* GetPointer(Common::PhysicalAddress addr) const { + return reinterpret_cast(buffer.BackingBasePointer() + + (GetInteger(addr) - DramMemoryMap::Base)); } Common::HostMemory buffer; diff --git a/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.cpp b/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.cpp index 098ba6eac..24eb3f886 100644 --- a/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.cpp +++ b/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.cpp @@ -76,22 +76,24 @@ void SetupDevicePhysicalMemoryRegions(KMemoryLayout& memory_layout) { void SetupDramPhysicalMemoryRegions(KMemoryLayout& memory_layout) { const size_t intended_memory_size = KSystemControl::Init::GetIntendedMemorySize(); - const PAddr physical_memory_base_address = + const KPhysicalAddress physical_memory_base_address = KSystemControl::Init::GetKernelPhysicalBaseAddress(DramPhysicalAddress); // Insert blocks into the tree. ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( - physical_memory_base_address, intended_memory_size, KMemoryRegionType_Dram)); + GetInteger(physical_memory_base_address), intended_memory_size, KMemoryRegionType_Dram)); ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( - physical_memory_base_address, ReservedEarlyDramSize, KMemoryRegionType_DramReservedEarly)); + GetInteger(physical_memory_base_address), ReservedEarlyDramSize, + KMemoryRegionType_DramReservedEarly)); // Insert the KTrace block at the end of Dram, if KTrace is enabled. static_assert(!IsKTraceEnabled || KTraceBufferSize > 0); if constexpr (IsKTraceEnabled) { - const PAddr ktrace_buffer_phys_addr = + const KPhysicalAddress ktrace_buffer_phys_addr = physical_memory_base_address + intended_memory_size - KTraceBufferSize; ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( - ktrace_buffer_phys_addr, KTraceBufferSize, KMemoryRegionType_KernelTraceBuffer)); + GetInteger(ktrace_buffer_phys_addr), KTraceBufferSize, + KMemoryRegionType_KernelTraceBuffer)); } } diff --git a/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.h b/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.h index d02ee61c3..f8fee4f5b 100644 --- a/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.h +++ b/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.h @@ -3,10 +3,10 @@ #pragma once -#include "common/common_types.h" +#include "core/hle/kernel/k_typed_address.h" namespace Kernel { -constexpr inline PAddr MainMemoryAddress = 0x80000000; +constexpr inline KPhysicalAddress MainMemoryAddress = 0x80000000; } // namespace Kernel diff --git a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp index 5b8a248c8..42d1fcc28 100644 --- a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp +++ b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp @@ -61,7 +61,7 @@ size_t KSystemControl::Init::GetIntendedMemorySize() { } } -PAddr KSystemControl::Init::GetKernelPhysicalBaseAddress(u64 base_address) { +KPhysicalAddress KSystemControl::Init::GetKernelPhysicalBaseAddress(KPhysicalAddress base_address) { const size_t real_dram_size = KSystemControl::Init::GetRealMemorySize(); const size_t intended_dram_size = KSystemControl::Init::GetIntendedMemorySize(); if (intended_dram_size * 2 < real_dram_size) { diff --git a/src/core/hle/kernel/board/nintendo/nx/k_system_control.h b/src/core/hle/kernel/board/nintendo/nx/k_system_control.h index 4b717d091..b477e8193 100644 --- a/src/core/hle/kernel/board/nintendo/nx/k_system_control.h +++ b/src/core/hle/kernel/board/nintendo/nx/k_system_control.h @@ -3,7 +3,7 @@ #pragma once -#include "common/common_types.h" +#include "core/hle/kernel/k_typed_address.h" namespace Kernel::Board::Nintendo::Nx { @@ -18,7 +18,7 @@ public: // Initialization. static std::size_t GetRealMemorySize(); static std::size_t GetIntendedMemorySize(); - static PAddr GetKernelPhysicalBaseAddress(u64 base_address); + static KPhysicalAddress GetKernelPhysicalBaseAddress(KPhysicalAddress base_address); static bool ShouldIncreaseThreadResourceLimit(); static std::size_t GetApplicationPoolSize(); static std::size_t GetAppletPoolSize(); diff --git a/src/core/hle/kernel/code_set.h b/src/core/hle/kernel/code_set.h index 5220dbcb6..af1af2b78 100644 --- a/src/core/hle/kernel/code_set.h +++ b/src/core/hle/kernel/code_set.h @@ -5,7 +5,7 @@ #include -#include "common/common_types.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/kernel/physical_memory.h" namespace Kernel { @@ -36,7 +36,7 @@ struct CodeSet final { std::size_t offset = 0; /// The address to map this segment to. - VAddr addr = 0; + KProcessAddress addr = 0; /// The size of this segment in bytes. u32 size = 0; @@ -82,7 +82,7 @@ struct CodeSet final { std::array segments; /// The entry point address for this code set. - VAddr entrypoint = 0; + KProcessAddress entrypoint = 0; }; } // namespace Kernel diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp index 5e4090e2b..1f2db673c 100644 --- a/src/core/hle/kernel/init/init_slab_setup.cpp +++ b/src/core/hle/kernel/init/init_slab_setup.cpp @@ -4,7 +4,6 @@ #include "common/alignment.h" #include "common/assert.h" #include "common/common_funcs.h" -#include "common/common_types.h" #include "core/core.h" #include "core/device_memory.h" #include "core/hardware_properties.h" @@ -30,6 +29,7 @@ #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_thread_local_page.h" #include "core/hle/kernel/k_transfer_memory.h" +#include "core/hle/kernel/k_typed_address.h" namespace Kernel::Init { @@ -104,17 +104,18 @@ static_assert(KernelPageBufferAdditionalSize == /// Helper function to translate from the slab virtual address to the reserved location in physical /// memory. -static PAddr TranslateSlabAddrToPhysical(KMemoryLayout& memory_layout, VAddr slab_addr) { - slab_addr -= memory_layout.GetSlabRegionAddress(); - return slab_addr + Core::DramMemoryMap::SlabHeapBase; +static KPhysicalAddress TranslateSlabAddrToPhysical(KMemoryLayout& memory_layout, + KVirtualAddress slab_addr) { + slab_addr -= GetInteger(memory_layout.GetSlabRegionAddress()); + return GetInteger(slab_addr) + Core::DramMemoryMap::SlabHeapBase; } template -VAddr InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout, VAddr address, - size_t num_objects) { +KVirtualAddress InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout, + KVirtualAddress address, size_t num_objects) { const size_t size = Common::AlignUp(sizeof(T) * num_objects, alignof(void*)); - VAddr start = Common::AlignUp(address, alignof(T)); + KVirtualAddress start = Common::AlignUp(GetInteger(address), alignof(T)); // This should use the virtual memory address passed in, but currently, we do not setup the // kernel virtual memory layout. Instead, we simply map these at a region of physical memory @@ -195,7 +196,7 @@ void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) { auto& kernel = system.Kernel(); // Get the start of the slab region, since that's where we'll be working. - VAddr address = memory_layout.GetSlabRegionAddress(); + KVirtualAddress address = memory_layout.GetSlabRegionAddress(); // Initialize slab type array to be in sorted order. std::array slab_types; @@ -228,7 +229,7 @@ void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) { } // Track the gaps, so that we can free them to the unused slab tree. - VAddr gap_start = address; + KVirtualAddress gap_start = address; size_t gap_size = 0; for (size_t i = 0; i < slab_gaps.size(); i++) { @@ -280,7 +281,7 @@ void KPageBufferSlabHeap::Initialize(Core::System& system) { // Allocate memory for the slab. constexpr auto AllocateOption = KMemoryManager::EncodeOption( KMemoryManager::Pool::System, KMemoryManager::Direction::FromFront); - const PAddr slab_address = + const KPhysicalAddress slab_address = kernel.MemoryManager().AllocateAndOpenContinuous(num_pages, 1, AllocateOption); ASSERT(slab_address != 0); diff --git a/src/core/hle/kernel/initial_process.h b/src/core/hle/kernel/initial_process.h index af0fb23b6..82195f4f7 100644 --- a/src/core/hle/kernel/initial_process.h +++ b/src/core/hle/kernel/initial_process.h @@ -14,7 +14,7 @@ using namespace Common::Literals; constexpr std::size_t InitialProcessBinarySizeMax = 12_MiB; -static inline PAddr GetInitialProcessBinaryPhysicalAddress() { +static inline KPhysicalAddress GetInitialProcessBinaryPhysicalAddress() { return Kernel::Board::Nintendo::Nx::KSystemControl::Init::GetKernelPhysicalBaseAddress( MainMemoryAddress); } diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp index 30a4e6edb..274928dcf 100644 --- a/src/core/hle/kernel/k_address_arbiter.cpp +++ b/src/core/hle/kernel/k_address_arbiter.cpp @@ -8,6 +8,7 @@ #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_thread_queue.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/svc_results.h" #include "core/memory.h" @@ -20,12 +21,12 @@ KAddressArbiter::~KAddressArbiter() = default; namespace { -bool ReadFromUser(Core::System& system, s32* out, VAddr address) { - *out = system.Memory().Read32(address); +bool ReadFromUser(Core::System& system, s32* out, KProcessAddress address) { + *out = system.Memory().Read32(GetInteger(address)); return true; } -bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 value) { +bool DecrementIfLessThan(Core::System& system, s32* out, KProcessAddress address, s32 value) { auto& monitor = system.Monitor(); const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); @@ -35,7 +36,8 @@ bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 valu // TODO(bunnei): We should call CanAccessAtomic(..) here. // Load the value from the address. - const s32 current_value = static_cast(monitor.ExclusiveRead32(current_core, address)); + const s32 current_value = + static_cast(monitor.ExclusiveRead32(current_core, GetInteger(address))); // Compare it to the desired one. if (current_value < value) { @@ -43,7 +45,8 @@ bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 valu const s32 decrement_value = current_value - 1; // Decrement and try to store. - if (!monitor.ExclusiveWrite32(current_core, address, static_cast(decrement_value))) { + if (!monitor.ExclusiveWrite32(current_core, GetInteger(address), + static_cast(decrement_value))) { // If we failed to store, try again. DecrementIfLessThan(system, out, address, value); } @@ -57,7 +60,8 @@ bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 valu return true; } -bool UpdateIfEqual(Core::System& system, s32* out, VAddr address, s32 value, s32 new_value) { +bool UpdateIfEqual(Core::System& system, s32* out, KProcessAddress address, s32 value, + s32 new_value) { auto& monitor = system.Monitor(); const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); @@ -67,14 +71,16 @@ bool UpdateIfEqual(Core::System& system, s32* out, VAddr address, s32 value, s32 // TODO(bunnei): We should call CanAccessAtomic(..) here. // Load the value from the address. - const s32 current_value = static_cast(monitor.ExclusiveRead32(current_core, address)); + const s32 current_value = + static_cast(monitor.ExclusiveRead32(current_core, GetInteger(address))); // Compare it to the desired one. if (current_value == value) { // If equal, we want to try to write the new value. // Try to store. - if (!monitor.ExclusiveWrite32(current_core, address, static_cast(new_value))) { + if (!monitor.ExclusiveWrite32(current_core, GetInteger(address), + static_cast(new_value))) { // If we failed to store, try again. UpdateIfEqual(system, out, address, value, new_value); } @@ -110,7 +116,7 @@ private: } // namespace -Result KAddressArbiter::Signal(VAddr addr, s32 count) { +Result KAddressArbiter::Signal(uint64_t addr, s32 count) { // Perform signaling. s32 num_waiters{}; { @@ -133,7 +139,7 @@ Result KAddressArbiter::Signal(VAddr addr, s32 count) { R_SUCCEED(); } -Result KAddressArbiter::SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 count) { +Result KAddressArbiter::SignalAndIncrementIfEqual(uint64_t addr, s32 value, s32 count) { // Perform signaling. s32 num_waiters{}; { @@ -162,7 +168,7 @@ Result KAddressArbiter::SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 cou R_SUCCEED(); } -Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 value, s32 count) { +Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(uint64_t addr, s32 value, s32 count) { // Perform signaling. s32 num_waiters{}; { @@ -225,7 +231,7 @@ Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 val R_SUCCEED(); } -Result KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout) { +Result KAddressArbiter::WaitIfLessThan(uint64_t addr, s32 value, bool decrement, s64 timeout) { // Prepare to wait. KThread* cur_thread = GetCurrentThreadPointer(m_kernel); KHardwareTimer* timer{}; @@ -280,7 +286,7 @@ Result KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s6 return cur_thread->GetWaitResult(); } -Result KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { +Result KAddressArbiter::WaitIfEqual(uint64_t addr, s32 value, s64 timeout) { // Prepare to wait. KThread* cur_thread = GetCurrentThreadPointer(m_kernel); KHardwareTimer* timer{}; diff --git a/src/core/hle/kernel/k_address_arbiter.h b/src/core/hle/kernel/k_address_arbiter.h index 9a8c1ae94..3b70e1ab2 100644 --- a/src/core/hle/kernel/k_address_arbiter.h +++ b/src/core/hle/kernel/k_address_arbiter.h @@ -25,7 +25,7 @@ public: explicit KAddressArbiter(Core::System& system); ~KAddressArbiter(); - Result SignalToAddress(VAddr addr, Svc::SignalType type, s32 value, s32 count) { + Result SignalToAddress(uint64_t addr, Svc::SignalType type, s32 value, s32 count) { switch (type) { case Svc::SignalType::Signal: R_RETURN(this->Signal(addr, count)); @@ -38,7 +38,7 @@ public: } } - Result WaitForAddress(VAddr addr, Svc::ArbitrationType type, s32 value, s64 timeout) { + Result WaitForAddress(uint64_t addr, Svc::ArbitrationType type, s32 value, s64 timeout) { switch (type) { case Svc::ArbitrationType::WaitIfLessThan: R_RETURN(WaitIfLessThan(addr, value, false, timeout)); @@ -52,11 +52,11 @@ public: } private: - Result Signal(VAddr addr, s32 count); - Result SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 count); - Result SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 value, s32 count); - Result WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout); - Result WaitIfEqual(VAddr addr, s32 value, s64 timeout); + Result Signal(uint64_t addr, s32 count); + Result SignalAndIncrementIfEqual(uint64_t addr, s32 value, s32 count); + Result SignalAndModifyByWaitingCountIfEqual(uint64_t addr, s32 value, s32 count); + Result WaitIfLessThan(uint64_t addr, s32 value, bool decrement, s64 timeout); + Result WaitIfEqual(uint64_t addr, s32 value, s64 timeout); private: ThreadTree m_tree; diff --git a/src/core/hle/kernel/k_client_session.cpp b/src/core/hle/kernel/k_client_session.cpp index d998b2be2..72b66270d 100644 --- a/src/core/hle/kernel/k_client_session.cpp +++ b/src/core/hle/kernel/k_client_session.cpp @@ -29,7 +29,8 @@ Result KClientSession::SendSyncRequest() { SCOPE_EXIT({ request->Close(); }); // Initialize the request. - request->Initialize(nullptr, GetCurrentThread(m_kernel).GetTlsAddress(), MessageBufferSize); + request->Initialize(nullptr, GetInteger(GetCurrentThread(m_kernel).GetTlsAddress()), + MessageBufferSize); // Send the request. R_RETURN(m_parent->GetServerSession().OnRequest(request)); diff --git a/src/core/hle/kernel/k_code_memory.cpp b/src/core/hle/kernel/k_code_memory.cpp index 89df6b5d8..3583bee44 100644 --- a/src/core/hle/kernel/k_code_memory.cpp +++ b/src/core/hle/kernel/k_code_memory.cpp @@ -19,7 +19,8 @@ namespace Kernel { KCodeMemory::KCodeMemory(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel}, m_lock(kernel) {} -Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr, size_t size) { +Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, KProcessAddress addr, + size_t size) { // Set members. m_owner = GetCurrentProcessPointer(m_kernel); @@ -63,7 +64,7 @@ void KCodeMemory::Finalize() { m_owner->Close(); } -Result KCodeMemory::Map(VAddr address, size_t size) { +Result KCodeMemory::Map(KProcessAddress address, size_t size) { // Validate the size. R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); @@ -83,7 +84,7 @@ Result KCodeMemory::Map(VAddr address, size_t size) { R_SUCCEED(); } -Result KCodeMemory::Unmap(VAddr address, size_t size) { +Result KCodeMemory::Unmap(KProcessAddress address, size_t size) { // Validate the size. R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); @@ -100,7 +101,7 @@ Result KCodeMemory::Unmap(VAddr address, size_t size) { R_SUCCEED(); } -Result KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermission perm) { +Result KCodeMemory::MapToOwner(KProcessAddress address, size_t size, Svc::MemoryPermission perm) { // Validate the size. R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); @@ -134,7 +135,7 @@ Result KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermission R_SUCCEED(); } -Result KCodeMemory::UnmapFromOwner(VAddr address, size_t size) { +Result KCodeMemory::UnmapFromOwner(KProcessAddress address, size_t size) { // Validate the size. R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); diff --git a/src/core/hle/kernel/k_code_memory.h b/src/core/hle/kernel/k_code_memory.h index 23cbb283b..26fe6b3dc 100644 --- a/src/core/hle/kernel/k_code_memory.h +++ b/src/core/hle/kernel/k_code_memory.h @@ -5,12 +5,12 @@ #include -#include "common/common_types.h" #include "core/device_memory.h" #include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/k_light_lock.h" #include "core/hle/kernel/k_page_group.h" #include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/kernel/slab_helpers.h" #include "core/hle/kernel/svc_types.h" #include "core/hle/result.h" @@ -31,13 +31,13 @@ class KCodeMemory final public: explicit KCodeMemory(KernelCore& kernel); - Result Initialize(Core::DeviceMemory& device_memory, VAddr address, size_t size); + Result Initialize(Core::DeviceMemory& device_memory, KProcessAddress address, size_t size); void Finalize() override; - Result Map(VAddr address, size_t size); - Result Unmap(VAddr address, size_t size); - Result MapToOwner(VAddr address, size_t size, Svc::MemoryPermission perm); - Result UnmapFromOwner(VAddr address, size_t size); + Result Map(KProcessAddress address, size_t size); + Result Unmap(KProcessAddress address, size_t size); + Result MapToOwner(KProcessAddress address, size_t size, Svc::MemoryPermission perm); + Result UnmapFromOwner(KProcessAddress address, size_t size); bool IsInitialized() const override { return m_is_initialized; @@ -47,7 +47,7 @@ public: KProcess* GetOwner() const override { return m_owner; } - VAddr GetSourceAddress() const { + KProcessAddress GetSourceAddress() const { return m_address; } size_t GetSize() const { @@ -57,7 +57,7 @@ public: private: std::optional m_page_group{}; KProcess* m_owner{}; - VAddr m_address{}; + KProcessAddress m_address{}; KLightLock m_lock; bool m_is_initialized{}; bool m_is_owner_mapped{}; diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index 58b8609d8..c6634313f 100644 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp @@ -18,23 +18,23 @@ namespace Kernel { namespace { -bool ReadFromUser(Core::System& system, u32* out, VAddr address) { - *out = system.Memory().Read32(address); +bool ReadFromUser(Core::System& system, u32* out, KProcessAddress address) { + *out = system.Memory().Read32(GetInteger(address)); return true; } -bool WriteToUser(Core::System& system, VAddr address, const u32* p) { - system.Memory().Write32(address, *p); +bool WriteToUser(Core::System& system, KProcessAddress address, const u32* p) { + system.Memory().Write32(GetInteger(address), *p); return true; } -bool UpdateLockAtomic(Core::System& system, u32* out, VAddr address, u32 if_zero, +bool UpdateLockAtomic(Core::System& system, u32* out, KProcessAddress address, u32 if_zero, u32 new_orr_mask) { auto& monitor = system.Monitor(); const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); // Load the value from the address. - const auto expected = monitor.ExclusiveRead32(current_core, address); + const auto expected = monitor.ExclusiveRead32(current_core, GetInteger(address)); // Orr in the new mask. u32 value = expected | new_orr_mask; @@ -45,7 +45,7 @@ bool UpdateLockAtomic(Core::System& system, u32* out, VAddr address, u32 if_zero } // Try to store. - if (!monitor.ExclusiveWrite32(current_core, address, value)) { + if (!monitor.ExclusiveWrite32(current_core, GetInteger(address), value)) { // If we failed to store, try again. return UpdateLockAtomic(system, out, address, if_zero, new_orr_mask); } @@ -102,7 +102,7 @@ KConditionVariable::KConditionVariable(Core::System& system) KConditionVariable::~KConditionVariable() = default; -Result KConditionVariable::SignalToAddress(VAddr addr) { +Result KConditionVariable::SignalToAddress(KProcessAddress addr) { KThread* owner_thread = GetCurrentThreadPointer(m_kernel); // Signal the address. @@ -143,7 +143,7 @@ Result KConditionVariable::SignalToAddress(VAddr addr) { } } -Result KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value) { +Result KConditionVariable::WaitForAddress(Handle handle, KProcessAddress addr, u32 value) { KThread* cur_thread = GetCurrentThreadPointer(m_kernel); ThreadQueueImplForKConditionVariableWaitForAddress wait_queue(m_kernel); @@ -191,7 +191,7 @@ void KConditionVariable::SignalImpl(KThread* thread) { ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); // Update the tag. - VAddr address = thread->GetAddressKey(); + KProcessAddress address = thread->GetAddressKey(); u32 own_tag = thread->GetAddressKeyValue(); u32 prev_tag{}; @@ -262,7 +262,7 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) { } } -Result KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) { +Result KConditionVariable::Wait(KProcessAddress addr, u64 key, u32 value, s64 timeout) { // Prepare to wait. KThread* cur_thread = GetCurrentThreadPointer(m_kernel); KHardwareTimer* timer{}; diff --git a/src/core/hle/kernel/k_condition_variable.h b/src/core/hle/kernel/k_condition_variable.h index fbd2c1fc0..8c2f3ae51 100644 --- a/src/core/hle/kernel/k_condition_variable.h +++ b/src/core/hle/kernel/k_condition_variable.h @@ -4,10 +4,10 @@ #pragma once #include "common/assert.h" -#include "common/common_types.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_thread.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/kernel/kernel.h" #include "core/hle/result.h" @@ -25,12 +25,12 @@ public: ~KConditionVariable(); // Arbitration - Result SignalToAddress(VAddr addr); - Result WaitForAddress(Handle handle, VAddr addr, u32 value); + Result SignalToAddress(KProcessAddress addr); + Result WaitForAddress(Handle handle, KProcessAddress addr, u32 value); // Condition variable void Signal(u64 cv_key, s32 count); - Result Wait(VAddr addr, u64 key, u32 value, s64 timeout); + Result Wait(KProcessAddress addr, u64 key, u32 value, s64 timeout); private: void SignalImpl(KThread* thread); diff --git a/src/core/hle/kernel/k_device_address_space.cpp b/src/core/hle/kernel/k_device_address_space.cpp index a2fc4fe1f..f48896715 100644 --- a/src/core/hle/kernel/k_device_address_space.cpp +++ b/src/core/hle/kernel/k_device_address_space.cpp @@ -54,8 +54,8 @@ Result KDeviceAddressSpace::Detach(Svc::DeviceName device_name) { R_SUCCEED(); } -Result KDeviceAddressSpace::Map(KPageTable* page_table, VAddr process_address, size_t size, - u64 device_address, u32 option, bool is_aligned) { +Result KDeviceAddressSpace::Map(KPageTable* page_table, KProcessAddress process_address, + size_t size, u64 device_address, u32 option, bool is_aligned) { // Check that the address falls within the space. R_UNLESS((m_space_address <= device_address && device_address + size - 1 <= m_space_address + m_space_size - 1), @@ -113,8 +113,8 @@ Result KDeviceAddressSpace::Map(KPageTable* page_table, VAddr process_address, s R_SUCCEED(); } -Result KDeviceAddressSpace::Unmap(KPageTable* page_table, VAddr process_address, size_t size, - u64 device_address) { +Result KDeviceAddressSpace::Unmap(KPageTable* page_table, KProcessAddress process_address, + size_t size, u64 device_address) { // Check that the address falls within the space. R_UNLESS((m_space_address <= device_address && device_address + size - 1 <= m_space_address + m_space_size - 1), diff --git a/src/core/hle/kernel/k_device_address_space.h b/src/core/hle/kernel/k_device_address_space.h index b4a014c38..18556e3cc 100644 --- a/src/core/hle/kernel/k_device_address_space.h +++ b/src/core/hle/kernel/k_device_address_space.h @@ -5,8 +5,8 @@ #include -#include "common/common_types.h" #include "core/hle/kernel/k_page_table.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/kernel/slab_helpers.h" #include "core/hle/result.h" @@ -31,23 +31,24 @@ public: Result Attach(Svc::DeviceName device_name); Result Detach(Svc::DeviceName device_name); - Result MapByForce(KPageTable* page_table, VAddr process_address, size_t size, + Result MapByForce(KPageTable* page_table, KProcessAddress process_address, size_t size, u64 device_address, u32 option) { R_RETURN(this->Map(page_table, process_address, size, device_address, option, false)); } - Result MapAligned(KPageTable* page_table, VAddr process_address, size_t size, + Result MapAligned(KPageTable* page_table, KProcessAddress process_address, size_t size, u64 device_address, u32 option) { R_RETURN(this->Map(page_table, process_address, size, device_address, option, true)); } - Result Unmap(KPageTable* page_table, VAddr process_address, size_t size, u64 device_address); + Result Unmap(KPageTable* page_table, KProcessAddress process_address, size_t size, + u64 device_address); static void Initialize(); private: - Result Map(KPageTable* page_table, VAddr process_address, size_t size, u64 device_address, - u32 option, bool is_aligned); + Result Map(KPageTable* page_table, KProcessAddress process_address, size_t size, + u64 device_address, u32 option, bool is_aligned); private: KLightLock m_lock; diff --git a/src/core/hle/kernel/k_dynamic_page_manager.h b/src/core/hle/kernel/k_dynamic_page_manager.h index ac80d60a1..ad11e84b7 100644 --- a/src/core/hle/kernel/k_dynamic_page_manager.h +++ b/src/core/hle/kernel/k_dynamic_page_manager.h @@ -6,9 +6,9 @@ #include #include "common/alignment.h" -#include "common/common_types.h" #include "core/hle/kernel/k_page_bitmap.h" #include "core/hle/kernel/k_spin_lock.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/kernel/memory_types.h" #include "core/hle/kernel/svc_results.h" @@ -26,23 +26,23 @@ public: KDynamicPageManager() = default; template - T* GetPointer(VAddr addr) { + T* GetPointer(KVirtualAddress addr) { return reinterpret_cast(m_backing_memory.data() + (addr - m_address)); } template - const T* GetPointer(VAddr addr) const { + const T* GetPointer(KVirtualAddress addr) const { return reinterpret_cast(m_backing_memory.data() + (addr - m_address)); } - Result Initialize(VAddr memory, size_t size, size_t align) { + Result Initialize(KVirtualAddress memory, size_t size, size_t align) { // We need to have positive size. R_UNLESS(size > 0, ResultOutOfMemory); m_backing_memory.resize(size); // Set addresses. m_address = memory; - m_aligned_address = Common::AlignDown(memory, align); + m_aligned_address = Common::AlignDown(GetInteger(memory), align); // Calculate extents. const size_t managed_size = m_address + size - m_aligned_address; @@ -79,7 +79,7 @@ public: R_SUCCEED(); } - VAddr GetAddress() const { + KVirtualAddress GetAddress() const { return m_address; } size_t GetSize() const { @@ -145,7 +145,8 @@ public: KScopedSpinLock lk(m_lock); // Set the bit for the free page. - size_t offset = (reinterpret_cast(pb) - m_aligned_address) / sizeof(PageBuffer); + size_t offset = + (reinterpret_cast(pb) - GetInteger(m_aligned_address)) / sizeof(PageBuffer); m_page_bitmap.SetBit(offset); // Decrement our used count. @@ -158,8 +159,8 @@ private: size_t m_used{}; size_t m_peak{}; size_t m_count{}; - VAddr m_address{}; - VAddr m_aligned_address{}; + KVirtualAddress m_address{}; + KVirtualAddress m_aligned_address{}; size_t m_size{}; // TODO(bunnei): Back by host memory until we emulate kernel virtual address space. diff --git a/src/core/hle/kernel/k_dynamic_slab_heap.h b/src/core/hle/kernel/k_dynamic_slab_heap.h index 3a0ddd050..76ed4cac1 100644 --- a/src/core/hle/kernel/k_dynamic_slab_heap.h +++ b/src/core/hle/kernel/k_dynamic_slab_heap.h @@ -19,7 +19,7 @@ class KDynamicSlabHeap : protected impl::KSlabHeapImpl { public: constexpr KDynamicSlabHeap() = default; - constexpr VAddr GetAddress() const { + constexpr KVirtualAddress GetAddress() const { return m_address; } constexpr size_t GetSize() const { @@ -35,7 +35,7 @@ public: return m_count.load(); } - constexpr bool IsInRange(VAddr addr) const { + constexpr bool IsInRange(KVirtualAddress addr) const { return this->GetAddress() <= addr && addr <= this->GetAddress() + this->GetSize() - 1; } @@ -115,7 +115,7 @@ private: std::atomic m_used{}; std::atomic m_peak{}; std::atomic m_count{}; - VAddr m_address{}; + KVirtualAddress m_address{}; size_t m_size{}; }; diff --git a/src/core/hle/kernel/k_memory_block.h b/src/core/hle/kernel/k_memory_block.h index e01929da6..41a29da24 100644 --- a/src/core/hle/kernel/k_memory_block.h +++ b/src/core/hle/kernel/k_memory_block.h @@ -5,8 +5,8 @@ #include "common/alignment.h" #include "common/assert.h" -#include "common/common_types.h" #include "common/intrusive_red_black_tree.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/kernel/memory_types.h" #include "core/hle/kernel/svc_types.h" @@ -282,7 +282,7 @@ class KMemoryBlock : public Common::IntrusiveRedBlackTreeBaseNode private: u16 m_device_disable_merge_left_count{}; u16 m_device_disable_merge_right_count{}; - VAddr m_address{}; + KProcessAddress m_address{}; size_t m_num_pages{}; KMemoryState m_memory_state{KMemoryState::None}; u16 m_ipc_lock_count{}; @@ -306,7 +306,7 @@ public: } public: - constexpr VAddr GetAddress() const { + constexpr KProcessAddress GetAddress() const { return m_address; } @@ -318,11 +318,11 @@ public: return this->GetNumPages() * PageSize; } - constexpr VAddr GetEndAddress() const { + constexpr KProcessAddress GetEndAddress() const { return this->GetAddress() + this->GetSize(); } - constexpr VAddr GetLastAddress() const { + constexpr KProcessAddress GetLastAddress() const { return this->GetEndAddress() - 1; } @@ -348,7 +348,7 @@ public: constexpr KMemoryInfo GetMemoryInfo() const { return { - .m_address = this->GetAddress(), + .m_address = GetInteger(this->GetAddress()), .m_size = this->GetSize(), .m_state = m_memory_state, .m_device_disable_merge_left_count = m_device_disable_merge_left_count, @@ -366,12 +366,12 @@ public: public: explicit KMemoryBlock() = default; - constexpr KMemoryBlock(VAddr addr, size_t np, KMemoryState ms, KMemoryPermission p, + constexpr KMemoryBlock(KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) : Common::IntrusiveRedBlackTreeBaseNode(), m_address(addr), m_num_pages(np), m_memory_state(ms), m_permission(p), m_attribute(attr) {} - constexpr void Initialize(VAddr addr, size_t np, KMemoryState ms, KMemoryPermission p, + constexpr void Initialize(KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) { m_device_disable_merge_left_count = 0; m_device_disable_merge_right_count = 0; @@ -408,7 +408,7 @@ public: KMemoryBlockDisableMergeAttribute::None; } - constexpr bool Contains(VAddr addr) const { + constexpr bool Contains(KProcessAddress addr) const { return this->GetAddress() <= addr && addr <= this->GetEndAddress(); } @@ -443,10 +443,10 @@ public: } } - constexpr void Split(KMemoryBlock* block, VAddr addr) { + constexpr void Split(KMemoryBlock* block, KProcessAddress addr) { ASSERT(this->GetAddress() < addr); ASSERT(this->Contains(addr)); - ASSERT(Common::IsAligned(addr, PageSize)); + ASSERT(Common::IsAligned(GetInteger(addr), PageSize)); block->m_address = m_address; block->m_num_pages = (addr - this->GetAddress()) / PageSize; diff --git a/src/core/hle/kernel/k_memory_block_manager.cpp b/src/core/hle/kernel/k_memory_block_manager.cpp index cf4c1e371..ab75f550e 100644 --- a/src/core/hle/kernel/k_memory_block_manager.cpp +++ b/src/core/hle/kernel/k_memory_block_manager.cpp @@ -7,7 +7,8 @@ namespace Kernel { KMemoryBlockManager::KMemoryBlockManager() = default; -Result KMemoryBlockManager::Initialize(VAddr st, VAddr nd, KMemoryBlockSlabManager* slab_manager) { +Result KMemoryBlockManager::Initialize(KProcessAddress st, KProcessAddress nd, + KMemoryBlockSlabManager* slab_manager) { // Allocate a block to encapsulate the address space, insert it into the tree. KMemoryBlock* start_block = slab_manager->Allocate(); R_UNLESS(start_block != nullptr, ResultOutOfResource); @@ -15,8 +16,8 @@ Result KMemoryBlockManager::Initialize(VAddr st, VAddr nd, KMemoryBlockSlabManag // Set our start and end. m_start_address = st; m_end_address = nd; - ASSERT(Common::IsAligned(m_start_address, PageSize)); - ASSERT(Common::IsAligned(m_end_address, PageSize)); + ASSERT(Common::IsAligned(GetInteger(m_start_address), PageSize)); + ASSERT(Common::IsAligned(GetInteger(m_end_address), PageSize)); // Initialize and insert the block. start_block->Initialize(m_start_address, (m_end_address - m_start_address) / PageSize, @@ -40,12 +41,13 @@ void KMemoryBlockManager::Finalize(KMemoryBlockSlabManager* slab_manager, ASSERT(m_memory_block_tree.empty()); } -VAddr KMemoryBlockManager::FindFreeArea(VAddr region_start, size_t region_num_pages, - size_t num_pages, size_t alignment, size_t offset, - size_t guard_pages) const { +KProcessAddress KMemoryBlockManager::FindFreeArea(KProcessAddress region_start, + size_t region_num_pages, size_t num_pages, + size_t alignment, size_t offset, + size_t guard_pages) const { if (num_pages > 0) { - const VAddr region_end = region_start + region_num_pages * PageSize; - const VAddr region_last = region_end - 1; + const KProcessAddress region_end = region_start + region_num_pages * PageSize; + const KProcessAddress region_last = region_end - 1; for (const_iterator it = this->FindIterator(region_start); it != m_memory_block_tree.cend(); it++) { const KMemoryInfo info = it->GetMemoryInfo(); @@ -56,17 +58,19 @@ VAddr KMemoryBlockManager::FindFreeArea(VAddr region_start, size_t region_num_pa continue; } - VAddr area = (info.GetAddress() <= region_start) ? region_start : info.GetAddress(); + KProcessAddress area = + (info.GetAddress() <= GetInteger(region_start)) ? region_start : info.GetAddress(); area += guard_pages * PageSize; - const VAddr offset_area = Common::AlignDown(area, alignment) + offset; + const KProcessAddress offset_area = + Common::AlignDown(GetInteger(area), alignment) + offset; area = (area <= offset_area) ? offset_area : offset_area + alignment; - const VAddr area_end = area + num_pages * PageSize + guard_pages * PageSize; - const VAddr area_last = area_end - 1; + const KProcessAddress area_end = area + num_pages * PageSize + guard_pages * PageSize; + const KProcessAddress area_last = area_end - 1; - if (info.GetAddress() <= area && area < area_last && area_last <= region_last && - area_last <= info.GetLastAddress()) { + if (info.GetAddress() <= GetInteger(area) && area < area_last && + area_last <= region_last && area_last <= info.GetLastAddress()) { return area; } } @@ -76,7 +80,7 @@ VAddr KMemoryBlockManager::FindFreeArea(VAddr region_start, size_t region_num_pa } void KMemoryBlockManager::CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator* allocator, - VAddr address, size_t num_pages) { + KProcessAddress address, size_t num_pages) { // Find the iterator now that we've updated. iterator it = this->FindIterator(address); if (address != m_start_address) { @@ -104,18 +108,18 @@ void KMemoryBlockManager::CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator* } } -void KMemoryBlockManager::Update(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address, - size_t num_pages, KMemoryState state, KMemoryPermission perm, - KMemoryAttribute attr, +void KMemoryBlockManager::Update(KMemoryBlockManagerUpdateAllocator* allocator, + KProcessAddress address, size_t num_pages, KMemoryState state, + KMemoryPermission perm, KMemoryAttribute attr, KMemoryBlockDisableMergeAttribute set_disable_attr, KMemoryBlockDisableMergeAttribute clear_disable_attr) { // Ensure for auditing that we never end up with an invalid tree. KScopedMemoryBlockManagerAuditor auditor(this); - ASSERT(Common::IsAligned(address, PageSize)); + ASSERT(Common::IsAligned(GetInteger(address), PageSize)); ASSERT((attr & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)) == KMemoryAttribute::None); - VAddr cur_address = address; + KProcessAddress cur_address = address; size_t remaining_pages = num_pages; iterator it = this->FindIterator(address); @@ -168,17 +172,17 @@ void KMemoryBlockManager::Update(KMemoryBlockManagerUpdateAllocator* allocator, } void KMemoryBlockManager::UpdateIfMatch(KMemoryBlockManagerUpdateAllocator* allocator, - VAddr address, size_t num_pages, KMemoryState test_state, - KMemoryPermission test_perm, KMemoryAttribute test_attr, - KMemoryState state, KMemoryPermission perm, - KMemoryAttribute attr) { + KProcessAddress address, size_t num_pages, + KMemoryState test_state, KMemoryPermission test_perm, + KMemoryAttribute test_attr, KMemoryState state, + KMemoryPermission perm, KMemoryAttribute attr) { // Ensure for auditing that we never end up with an invalid tree. KScopedMemoryBlockManagerAuditor auditor(this); - ASSERT(Common::IsAligned(address, PageSize)); + ASSERT(Common::IsAligned(GetInteger(address), PageSize)); ASSERT((attr & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)) == KMemoryAttribute::None); - VAddr cur_address = address; + KProcessAddress cur_address = address; size_t remaining_pages = num_pages; iterator it = this->FindIterator(address); @@ -230,18 +234,18 @@ void KMemoryBlockManager::UpdateIfMatch(KMemoryBlockManagerUpdateAllocator* allo this->CoalesceForUpdate(allocator, address, num_pages); } -void KMemoryBlockManager::UpdateLock(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address, - size_t num_pages, MemoryBlockLockFunction lock_func, - KMemoryPermission perm) { +void KMemoryBlockManager::UpdateLock(KMemoryBlockManagerUpdateAllocator* allocator, + KProcessAddress address, size_t num_pages, + MemoryBlockLockFunction lock_func, KMemoryPermission perm) { // Ensure for auditing that we never end up with an invalid tree. KScopedMemoryBlockManagerAuditor auditor(this); - ASSERT(Common::IsAligned(address, PageSize)); + ASSERT(Common::IsAligned(GetInteger(address), PageSize)); - VAddr cur_address = address; + KProcessAddress cur_address = address; size_t remaining_pages = num_pages; iterator it = this->FindIterator(address); - const VAddr end_address = address + (num_pages * PageSize); + const KProcessAddress end_address = address + (num_pages * PageSize); while (remaining_pages > 0) { const size_t remaining_size = remaining_pages * PageSize; diff --git a/src/core/hle/kernel/k_memory_block_manager.h b/src/core/hle/kernel/k_memory_block_manager.h index d382722a6..7c0bd16f0 100644 --- a/src/core/hle/kernel/k_memory_block_manager.h +++ b/src/core/hle/kernel/k_memory_block_manager.h @@ -7,9 +7,9 @@ #include #include "common/common_funcs.h" -#include "common/common_types.h" #include "core/hle/kernel/k_dynamic_resource_manager.h" #include "core/hle/kernel/k_memory_block.h" +#include "core/hle/kernel/k_typed_address.h" namespace Kernel { @@ -85,9 +85,10 @@ public: public: KMemoryBlockManager(); - using HostUnmapCallback = std::function; + using HostUnmapCallback = std::function; - Result Initialize(VAddr st, VAddr nd, KMemoryBlockSlabManager* slab_manager); + Result Initialize(KProcessAddress st, KProcessAddress nd, + KMemoryBlockSlabManager* slab_manager); void Finalize(KMemoryBlockSlabManager* slab_manager, HostUnmapCallback&& host_unmap_callback); iterator end() { @@ -100,27 +101,28 @@ public: return m_memory_block_tree.cend(); } - VAddr FindFreeArea(VAddr region_start, size_t region_num_pages, size_t num_pages, - size_t alignment, size_t offset, size_t guard_pages) const; + KProcessAddress FindFreeArea(KProcessAddress region_start, size_t region_num_pages, + size_t num_pages, size_t alignment, size_t offset, + size_t guard_pages) const; - void Update(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address, size_t num_pages, - KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr, + void Update(KMemoryBlockManagerUpdateAllocator* allocator, KProcessAddress address, + size_t num_pages, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr, KMemoryBlockDisableMergeAttribute set_disable_attr, KMemoryBlockDisableMergeAttribute clear_disable_attr); - void UpdateLock(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address, size_t num_pages, - MemoryBlockLockFunction lock_func, KMemoryPermission perm); + void UpdateLock(KMemoryBlockManagerUpdateAllocator* allocator, KProcessAddress address, + size_t num_pages, MemoryBlockLockFunction lock_func, KMemoryPermission perm); - void UpdateIfMatch(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address, + void UpdateIfMatch(KMemoryBlockManagerUpdateAllocator* allocator, KProcessAddress address, size_t num_pages, KMemoryState test_state, KMemoryPermission test_perm, KMemoryAttribute test_attr, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr); - iterator FindIterator(VAddr address) const { + iterator FindIterator(KProcessAddress address) const { return m_memory_block_tree.find(KMemoryBlock( address, 1, KMemoryState::Free, KMemoryPermission::None, KMemoryAttribute::None)); } - const KMemoryBlock* FindBlock(VAddr address) const { + const KMemoryBlock* FindBlock(KProcessAddress address) const { if (const_iterator it = this->FindIterator(address); it != m_memory_block_tree.end()) { return std::addressof(*it); } @@ -132,12 +134,12 @@ public: bool CheckState() const; private: - void CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address, + void CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator* allocator, KProcessAddress address, size_t num_pages); MemoryBlockTree m_memory_block_tree; - VAddr m_start_address{}; - VAddr m_end_address{}; + KProcessAddress m_start_address{}; + KProcessAddress m_end_address{}; }; class KScopedMemoryBlockManagerAuditor { diff --git a/src/core/hle/kernel/k_memory_layout.cpp b/src/core/hle/kernel/k_memory_layout.cpp index 9ff751119..af40092c0 100644 --- a/src/core/hle/kernel/k_memory_layout.cpp +++ b/src/core/hle/kernel/k_memory_layout.cpp @@ -85,7 +85,8 @@ bool KMemoryRegionTree::Insert(u64 address, size_t size, u32 type_id, u32 new_at return true; } -VAddr KMemoryRegionTree::GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id) { +KVirtualAddress KMemoryRegionTree::GetRandomAlignedRegion(size_t size, size_t alignment, + u32 type_id) { // We want to find the total extents of the type id. const auto extents = this->GetDerivedRegionExtents(static_cast(type_id)); @@ -130,11 +131,13 @@ KMemoryLayout::KMemoryLayout() m_virtual_linear_tree{m_memory_region_allocator}, m_physical_linear_tree{ m_memory_region_allocator} {} -void KMemoryLayout::InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start, - VAddr linear_virtual_start) { +void KMemoryLayout::InitializeLinearMemoryRegionTrees(KPhysicalAddress aligned_linear_phys_start, + KVirtualAddress linear_virtual_start) { // Set static differences. - m_linear_phys_to_virt_diff = linear_virtual_start - aligned_linear_phys_start; - m_linear_virt_to_phys_diff = aligned_linear_phys_start - linear_virtual_start; + m_linear_phys_to_virt_diff = + GetInteger(linear_virtual_start) - GetInteger(aligned_linear_phys_start); + m_linear_virt_to_phys_diff = + GetInteger(aligned_linear_phys_start) - GetInteger(linear_virtual_start); // Initialize linear trees. for (auto& region : GetPhysicalMemoryRegionTree()) { diff --git a/src/core/hle/kernel/k_memory_layout.h b/src/core/hle/kernel/k_memory_layout.h index 551b7a0e4..54a71df56 100644 --- a/src/core/hle/kernel/k_memory_layout.h +++ b/src/core/hle/kernel/k_memory_layout.h @@ -10,6 +10,7 @@ #include "core/device_memory.h" #include "core/hle/kernel/k_memory_region.h" #include "core/hle/kernel/k_memory_region_type.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/kernel/memory_types.h" namespace Kernel { @@ -69,10 +70,11 @@ constexpr std::size_t KernelResourceSize = KernelPageTableHeapSize + KernelIniti //! NB: Use KThread::GetAddressKeyIsKernel(). //! See explanation for deviation of GetAddressKey. -bool IsKernelAddressKey(VAddr key) = delete; +bool IsKernelAddressKey(KProcessAddress key) = delete; -constexpr bool IsKernelAddress(VAddr address) { - return KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd; +constexpr bool IsKernelAddress(KProcessAddress address) { + return KernelVirtualAddressSpaceBase <= GetInteger(address) && + address < KernelVirtualAddressSpaceEnd; } class KMemoryLayout final { @@ -104,38 +106,38 @@ public: return m_physical_linear_tree; } - VAddr GetLinearVirtualAddress(PAddr address) const { - return address + m_linear_phys_to_virt_diff; + KVirtualAddress GetLinearVirtualAddress(KPhysicalAddress address) const { + return GetInteger(address) + m_linear_phys_to_virt_diff; } - PAddr GetLinearPhysicalAddress(VAddr address) const { - return address + m_linear_virt_to_phys_diff; + KPhysicalAddress GetLinearPhysicalAddress(KVirtualAddress address) const { + return GetInteger(address) + m_linear_virt_to_phys_diff; } - const KMemoryRegion* FindVirtual(VAddr address) const { + const KMemoryRegion* FindVirtual(KVirtualAddress address) const { return Find(address, GetVirtualMemoryRegionTree()); } - const KMemoryRegion* FindPhysical(PAddr address) const { + const KMemoryRegion* FindPhysical(KPhysicalAddress address) const { return Find(address, GetPhysicalMemoryRegionTree()); } - const KMemoryRegion* FindVirtualLinear(VAddr address) const { + const KMemoryRegion* FindVirtualLinear(KVirtualAddress address) const { return Find(address, GetVirtualLinearMemoryRegionTree()); } - const KMemoryRegion* FindPhysicalLinear(PAddr address) const { + const KMemoryRegion* FindPhysicalLinear(KPhysicalAddress address) const { return Find(address, GetPhysicalLinearMemoryRegionTree()); } - VAddr GetMainStackTopAddress(s32 core_id) const { + KVirtualAddress GetMainStackTopAddress(s32 core_id) const { return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscMainStack); } - VAddr GetIdleStackTopAddress(s32 core_id) const { + KVirtualAddress GetIdleStackTopAddress(s32 core_id) const { return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscIdleStack); } - VAddr GetExceptionStackTopAddress(s32 core_id) const { + KVirtualAddress GetExceptionStackTopAddress(s32 core_id) const { return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscExceptionStack); } - VAddr GetSlabRegionAddress() const { + KVirtualAddress GetSlabRegionAddress() const { return Dereference(GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_KernelSlab)) .GetAddress(); } @@ -143,10 +145,10 @@ public: const KMemoryRegion& GetDeviceRegion(KMemoryRegionType type) const { return Dereference(GetPhysicalMemoryRegionTree().FindFirstDerived(type)); } - PAddr GetDevicePhysicalAddress(KMemoryRegionType type) const { + KPhysicalAddress GetDevicePhysicalAddress(KMemoryRegionType type) const { return GetDeviceRegion(type).GetAddress(); } - VAddr GetDeviceVirtualAddress(KMemoryRegionType type) const { + KVirtualAddress GetDeviceVirtualAddress(KMemoryRegionType type) const { return GetDeviceRegion(type).GetPairAddress(); } @@ -175,11 +177,11 @@ public: KMemoryRegionType_VirtualDramKernelSecureAppletMemory)); } - const KMemoryRegion& GetVirtualLinearRegion(VAddr address) const { + const KMemoryRegion& GetVirtualLinearRegion(KVirtualAddress address) const { return Dereference(FindVirtualLinear(address)); } - const KMemoryRegion& GetPhysicalLinearRegion(PAddr address) const { + const KMemoryRegion& GetPhysicalLinearRegion(KPhysicalAddress address) const { return Dereference(FindPhysicalLinear(address)); } @@ -193,29 +195,32 @@ public: return GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_DTB); } - bool IsHeapPhysicalAddress(const KMemoryRegion*& region, PAddr address) const { + bool IsHeapPhysicalAddress(const KMemoryRegion*& region, KPhysicalAddress address) const { return IsTypedAddress(region, address, GetPhysicalLinearMemoryRegionTree(), KMemoryRegionType_DramUserPool); } - bool IsHeapVirtualAddress(const KMemoryRegion*& region, VAddr address) const { + bool IsHeapVirtualAddress(const KMemoryRegion*& region, KVirtualAddress address) const { return IsTypedAddress(region, address, GetVirtualLinearMemoryRegionTree(), KMemoryRegionType_VirtualDramUserPool); } - bool IsHeapPhysicalAddress(const KMemoryRegion*& region, PAddr address, size_t size) const { + bool IsHeapPhysicalAddress(const KMemoryRegion*& region, KPhysicalAddress address, + size_t size) const { return IsTypedAddress(region, address, size, GetPhysicalLinearMemoryRegionTree(), KMemoryRegionType_DramUserPool); } - bool IsHeapVirtualAddress(const KMemoryRegion*& region, VAddr address, size_t size) const { + bool IsHeapVirtualAddress(const KMemoryRegion*& region, KVirtualAddress address, + size_t size) const { return IsTypedAddress(region, address, size, GetVirtualLinearMemoryRegionTree(), KMemoryRegionType_VirtualDramUserPool); } - bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, PAddr address) const { + bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, + KPhysicalAddress address) const { return IsTypedAddress(region, address, GetPhysicalLinearMemoryRegionTree(), static_cast(KMemoryRegionAttr_LinearMapped)); } - bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, PAddr address, + bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, KPhysicalAddress address, size_t size) const { return IsTypedAddress(region, address, size, GetPhysicalLinearMemoryRegionTree(), static_cast(KMemoryRegionAttr_LinearMapped)); @@ -234,8 +239,8 @@ public: return std::make_pair(total_size, kernel_size); } - void InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start, - VAddr linear_virtual_start); + void InitializeLinearMemoryRegionTrees(KPhysicalAddress aligned_linear_phys_start, + KVirtualAddress linear_virtual_start); static size_t GetResourceRegionSizeForInit(bool use_extra_resource); auto GetKernelRegionExtents() const { @@ -261,8 +266,8 @@ public: auto GetLinearRegionVirtualExtents() const { const auto physical = GetLinearRegionPhysicalExtents(); - return KMemoryRegion(GetLinearVirtualAddress(physical.GetAddress()), - GetLinearVirtualAddress(physical.GetLastAddress()), 0, + return KMemoryRegion(GetInteger(GetLinearVirtualAddress(physical.GetAddress())), + GetInteger(GetLinearVirtualAddress(physical.GetLastAddress())), 0, KMemoryRegionType_None); } @@ -334,12 +339,12 @@ private: static bool IsTypedAddress(const KMemoryRegion*& region, AddressType address, const KMemoryRegionTree& tree, KMemoryRegionType type) { // Check if the cached region already contains the address. - if (region != nullptr && region->Contains(address)) { + if (region != nullptr && region->Contains(GetInteger(address))) { return true; } // Find the containing region, and update the cache. - if (const KMemoryRegion* found = tree.Find(address); + if (const KMemoryRegion* found = tree.Find(GetInteger(address)); found != nullptr && found->IsDerivedFrom(type)) { region = found; return true; @@ -352,11 +357,12 @@ private: static bool IsTypedAddress(const KMemoryRegion*& region, AddressType address, size_t size, const KMemoryRegionTree& tree, KMemoryRegionType type) { // Get the end of the checked region. - const u64 last_address = address + size - 1; + const u64 last_address = GetInteger(address) + size - 1; // Walk the tree to verify the region is correct. - const KMemoryRegion* cur = - (region != nullptr && region->Contains(address)) ? region : tree.Find(address); + const KMemoryRegion* cur = (region != nullptr && region->Contains(GetInteger(address))) + ? region + : tree.Find(GetInteger(address)); while (cur != nullptr && cur->IsDerivedFrom(type)) { if (last_address <= cur->GetLastAddress()) { region = cur; @@ -370,7 +376,7 @@ private: template static const KMemoryRegion* Find(AddressType address, const KMemoryRegionTree& tree) { - return tree.Find(address); + return tree.Find(GetInteger(address)); } static KMemoryRegion& Dereference(KMemoryRegion* region) { @@ -383,7 +389,7 @@ private: return *region; } - VAddr GetStackTopAddress(s32 core_id, KMemoryRegionType type) const { + KVirtualAddress GetStackTopAddress(s32 core_id, KMemoryRegionType type) const { const auto& region = Dereference( GetVirtualMemoryRegionTree().FindByTypeAndAttribute(type, static_cast(core_id))); ASSERT(region.GetEndAddress() != 0); diff --git a/src/core/hle/kernel/k_memory_manager.cpp b/src/core/hle/kernel/k_memory_manager.cpp index cd6ea388e..74d8169e0 100644 --- a/src/core/hle/kernel/k_memory_manager.cpp +++ b/src/core/hle/kernel/k_memory_manager.cpp @@ -5,7 +5,6 @@ #include "common/alignment.h" #include "common/assert.h" -#include "common/common_types.h" #include "common/scope_exit.h" #include "core/core.h" #include "core/device_memory.h" @@ -44,10 +43,10 @@ KMemoryManager::KMemoryManager(Core::System& system) KLightLock{system.Kernel()}, } {} -void KMemoryManager::Initialize(VAddr management_region, size_t management_region_size) { +void KMemoryManager::Initialize(KVirtualAddress management_region, size_t management_region_size) { // Clear the management region to zero. - const VAddr management_region_end = management_region + management_region_size; + const KVirtualAddress management_region_end = management_region + management_region_size; // std::memset(GetVoidPointer(management_region), 0, management_region_size); // Reset our manager count. @@ -56,7 +55,7 @@ void KMemoryManager::Initialize(VAddr management_region, size_t management_regio // Traverse the virtual memory layout tree, initializing each manager as appropriate. while (m_num_managers != MaxManagerCount) { // Locate the region that should initialize the current manager. - PAddr region_address = 0; + KPhysicalAddress region_address = 0; size_t region_size = 0; Pool region_pool = Pool::Count; for (const auto& it : m_system.Kernel().MemoryLayout().GetPhysicalMemoryRegionTree()) { @@ -70,8 +69,8 @@ void KMemoryManager::Initialize(VAddr management_region, size_t management_regio continue; } - const PAddr cur_start = it.GetAddress(); - const PAddr cur_end = it.GetEndAddress(); + const KPhysicalAddress cur_start = it.GetAddress(); + const KPhysicalAddress cur_end = it.GetEndAddress(); // Validate the region. ASSERT(cur_end != 0); @@ -119,17 +118,17 @@ void KMemoryManager::Initialize(VAddr management_region, size_t management_regio // Free each region to its corresponding heap. size_t reserved_sizes[MaxManagerCount] = {}; - const PAddr ini_start = GetInitialProcessBinaryPhysicalAddress(); - const PAddr ini_end = ini_start + InitialProcessBinarySizeMax; - const PAddr ini_last = ini_end - 1; + const KPhysicalAddress ini_start = GetInitialProcessBinaryPhysicalAddress(); + const KPhysicalAddress ini_end = ini_start + InitialProcessBinarySizeMax; + const KPhysicalAddress ini_last = ini_end - 1; for (const auto& it : m_system.Kernel().MemoryLayout().GetPhysicalMemoryRegionTree()) { if (it.IsDerivedFrom(KMemoryRegionType_DramUserPool)) { // Get the manager for the region. auto& manager = m_managers[it.GetAttributes()]; - const PAddr cur_start = it.GetAddress(); - const PAddr cur_last = it.GetLastAddress(); - const PAddr cur_end = it.GetEndAddress(); + const KPhysicalAddress cur_start = it.GetAddress(); + const KPhysicalAddress cur_last = it.GetLastAddress(); + const KPhysicalAddress cur_end = it.GetEndAddress(); if (cur_start <= ini_start && ini_last <= cur_last) { // Free memory before the ini to the heap. @@ -175,7 +174,8 @@ void KMemoryManager::FinalizeOptimizedMemory(u64 process_id, Pool pool) { UNREACHABLE(); } -PAddr KMemoryManager::AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option) { +KPhysicalAddress KMemoryManager::AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, + u32 option) { // Early return if we're allocating no pages. if (num_pages == 0) { return 0; @@ -190,7 +190,7 @@ PAddr KMemoryManager::AllocateAndOpenContinuous(size_t num_pages, size_t align_p // Loop, trying to iterate from each block. Impl* chosen_manager = nullptr; - PAddr allocated_block = 0; + KPhysicalAddress allocated_block = 0; for (chosen_manager = this->GetFirstManager(pool, dir); chosen_manager != nullptr; chosen_manager = this->GetNextManager(chosen_manager, dir)) { allocated_block = chosen_manager->AllocateAligned(heap_index, num_pages, align_pages); @@ -239,7 +239,7 @@ Result KMemoryManager::AllocatePageGroupImpl(KPageGroup* out, size_t num_pages, cur_manager = this->GetNextManager(cur_manager, dir)) { while (num_pages >= pages_per_alloc) { // Allocate a block. - PAddr allocated_block = cur_manager->AllocateBlock(index, random); + KPhysicalAddress allocated_block = cur_manager->AllocateBlock(index, random); if (allocated_block == 0) { break; } @@ -286,7 +286,7 @@ Result KMemoryManager::AllocateAndOpen(KPageGroup* out, size_t num_pages, u32 op // Open the first reference to the pages. for (const auto& block : *out) { - PAddr cur_address = block.GetAddress(); + KPhysicalAddress cur_address = block.GetAddress(); size_t remaining_pages = block.GetNumPages(); while (remaining_pages > 0) { // Get the manager for the current address. @@ -337,7 +337,7 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32 // Iterate over the allocated blocks. for (const auto& block : *out) { // Get the block extents. - const PAddr block_address = block.GetAddress(); + const KPhysicalAddress block_address = block.GetAddress(); const size_t block_pages = block.GetNumPages(); // If it has no pages, we don't need to do anything. @@ -348,7 +348,7 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32 // Fill all the pages that we need to fill. bool any_new = false; { - PAddr cur_address = block_address; + KPhysicalAddress cur_address = block_address; size_t remaining_pages = block_pages; while (remaining_pages > 0) { // Get the manager for the current address. @@ -369,7 +369,7 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32 // If there are new pages, update tracking for the allocation. if (any_new) { // Update tracking for the allocation. - PAddr cur_address = block_address; + KPhysicalAddress cur_address = block_address; size_t remaining_pages = block_pages; while (remaining_pages > 0) { // Get the manager for the current address. @@ -400,8 +400,9 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32 R_SUCCEED(); } -size_t KMemoryManager::Impl::Initialize(PAddr address, size_t size, VAddr management, - VAddr management_end, Pool p) { +size_t KMemoryManager::Impl::Initialize(KPhysicalAddress address, size_t size, + KVirtualAddress management, KVirtualAddress management_end, + Pool p) { // Calculate management sizes. const size_t ref_count_size = (size / PageSize) * sizeof(u16); const size_t optimize_map_size = CalculateOptimizedProcessOverheadSize(size); @@ -417,7 +418,7 @@ size_t KMemoryManager::Impl::Initialize(PAddr address, size_t size, VAddr manage m_management_region = management; m_page_reference_counts.resize( Kernel::Board::Nintendo::Nx::KSystemControl::Init::GetIntendedMemorySize() / PageSize); - ASSERT(Common::IsAligned(m_management_region, PageSize)); + ASSERT(Common::IsAligned(GetInteger(m_management_region), PageSize)); // Initialize the manager's KPageHeap. m_heap.Initialize(address, size, management + manager_size, page_heap_size); @@ -425,15 +426,15 @@ size_t KMemoryManager::Impl::Initialize(PAddr address, size_t size, VAddr manage return total_management_size; } -void KMemoryManager::Impl::TrackUnoptimizedAllocation(PAddr block, size_t num_pages) { +void KMemoryManager::Impl::TrackUnoptimizedAllocation(KPhysicalAddress block, size_t num_pages) { UNREACHABLE(); } -void KMemoryManager::Impl::TrackOptimizedAllocation(PAddr block, size_t num_pages) { +void KMemoryManager::Impl::TrackOptimizedAllocation(KPhysicalAddress block, size_t num_pages) { UNREACHABLE(); } -bool KMemoryManager::Impl::ProcessOptimizedAllocation(PAddr block, size_t num_pages, +bool KMemoryManager::Impl::ProcessOptimizedAllocation(KPhysicalAddress block, size_t num_pages, u8 fill_pattern) { UNREACHABLE(); } diff --git a/src/core/hle/kernel/k_memory_manager.h b/src/core/hle/kernel/k_memory_manager.h index 401d4e644..7e4b41319 100644 --- a/src/core/hle/kernel/k_memory_manager.h +++ b/src/core/hle/kernel/k_memory_manager.h @@ -7,10 +7,10 @@ #include #include "common/common_funcs.h" -#include "common/common_types.h" #include "core/hle/kernel/k_light_lock.h" #include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_page_heap.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/result.h" namespace Core { @@ -50,21 +50,21 @@ public: explicit KMemoryManager(Core::System& system); - void Initialize(VAddr management_region, size_t management_region_size); + void Initialize(KVirtualAddress management_region, size_t management_region_size); Result InitializeOptimizedMemory(u64 process_id, Pool pool); void FinalizeOptimizedMemory(u64 process_id, Pool pool); - PAddr AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option); + KPhysicalAddress AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option); Result AllocateAndOpen(KPageGroup* out, size_t num_pages, u32 option); Result AllocateForProcess(KPageGroup* out, size_t num_pages, u32 option, u64 process_id, u8 fill_pattern); - Pool GetPool(PAddr address) const { + Pool GetPool(KPhysicalAddress address) const { return this->GetManager(address).GetPool(); } - void Open(PAddr address, size_t num_pages) { + void Open(KPhysicalAddress address, size_t num_pages) { // Repeatedly open references until we've done so for all pages. while (num_pages) { auto& manager = this->GetManager(address); @@ -80,7 +80,7 @@ public: } } - void OpenFirst(PAddr address, size_t num_pages) { + void OpenFirst(KPhysicalAddress address, size_t num_pages) { // Repeatedly open references until we've done so for all pages. while (num_pages) { auto& manager = this->GetManager(address); @@ -96,7 +96,7 @@ public: } } - void Close(PAddr address, size_t num_pages) { + void Close(KPhysicalAddress address, size_t num_pages) { // Repeatedly close references until we've done so for all pages. while (num_pages) { auto& manager = this->GetManager(address); @@ -199,16 +199,16 @@ private: public: Impl() = default; - size_t Initialize(PAddr address, size_t size, VAddr management, VAddr management_end, - Pool p); + size_t Initialize(KPhysicalAddress address, size_t size, KVirtualAddress management, + KVirtualAddress management_end, Pool p); - PAddr AllocateBlock(s32 index, bool random) { + KPhysicalAddress AllocateBlock(s32 index, bool random) { return m_heap.AllocateBlock(index, random); } - PAddr AllocateAligned(s32 index, size_t num_pages, size_t align_pages) { + KPhysicalAddress AllocateAligned(s32 index, size_t num_pages, size_t align_pages) { return m_heap.AllocateAligned(index, num_pages, align_pages); } - void Free(PAddr addr, size_t num_pages) { + void Free(KPhysicalAddress addr, size_t num_pages) { m_heap.Free(addr, num_pages); } @@ -220,10 +220,10 @@ private: UNIMPLEMENTED(); } - void TrackUnoptimizedAllocation(PAddr block, size_t num_pages); - void TrackOptimizedAllocation(PAddr block, size_t num_pages); + void TrackUnoptimizedAllocation(KPhysicalAddress block, size_t num_pages); + void TrackOptimizedAllocation(KPhysicalAddress block, size_t num_pages); - bool ProcessOptimizedAllocation(PAddr block, size_t num_pages, u8 fill_pattern); + bool ProcessOptimizedAllocation(KPhysicalAddress block, size_t num_pages, u8 fill_pattern); constexpr Pool GetPool() const { return m_pool; @@ -231,7 +231,7 @@ private: constexpr size_t GetSize() const { return m_heap.GetSize(); } - constexpr PAddr GetEndAddress() const { + constexpr KPhysicalAddress GetEndAddress() const { return m_heap.GetEndAddress(); } @@ -243,10 +243,10 @@ private: UNIMPLEMENTED(); } - constexpr size_t GetPageOffset(PAddr address) const { + constexpr size_t GetPageOffset(KPhysicalAddress address) const { return m_heap.GetPageOffset(address); } - constexpr size_t GetPageOffsetToEnd(PAddr address) const { + constexpr size_t GetPageOffsetToEnd(KPhysicalAddress address) const { return m_heap.GetPageOffsetToEnd(address); } @@ -263,7 +263,7 @@ private: return m_prev; } - void OpenFirst(PAddr address, size_t num_pages) { + void OpenFirst(KPhysicalAddress address, size_t num_pages) { size_t index = this->GetPageOffset(address); const size_t end = index + num_pages; while (index < end) { @@ -274,7 +274,7 @@ private: } } - void Open(PAddr address, size_t num_pages) { + void Open(KPhysicalAddress address, size_t num_pages) { size_t index = this->GetPageOffset(address); const size_t end = index + num_pages; while (index < end) { @@ -285,7 +285,7 @@ private: } } - void Close(PAddr address, size_t num_pages) { + void Close(KPhysicalAddress address, size_t num_pages) { size_t index = this->GetPageOffset(address); const size_t end = index + num_pages; @@ -323,18 +323,18 @@ private: KPageHeap m_heap; std::vector m_page_reference_counts; - VAddr m_management_region{}; + KVirtualAddress m_management_region{}; Pool m_pool{}; Impl* m_next{}; Impl* m_prev{}; }; private: - Impl& GetManager(PAddr address) { + Impl& GetManager(KPhysicalAddress address) { return m_managers[m_memory_layout.GetPhysicalLinearRegion(address).GetAttributes()]; } - const Impl& GetManager(PAddr address) const { + const Impl& GetManager(KPhysicalAddress address) const { return m_managers[m_memory_layout.GetPhysicalLinearRegion(address).GetAttributes()]; } diff --git a/src/core/hle/kernel/k_memory_region.h b/src/core/hle/kernel/k_memory_region.h index cfe86fb82..e3044f022 100644 --- a/src/core/hle/kernel/k_memory_region.h +++ b/src/core/hle/kernel/k_memory_region.h @@ -5,9 +5,9 @@ #include "common/assert.h" #include "common/common_funcs.h" -#include "common/common_types.h" #include "common/intrusive_red_black_tree.h" #include "core/hle/kernel/k_memory_region_type.h" +#include "core/hle/kernel/k_typed_address.h" namespace Kernel { @@ -243,10 +243,10 @@ public: void InsertDirectly(u64 address, u64 last_address, u32 attr = 0, u32 type_id = 0); bool Insert(u64 address, size_t size, u32 type_id, u32 new_attr = 0, u32 old_attr = 0); - VAddr GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id); + KVirtualAddress GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id); - VAddr GetRandomAlignedRegionWithGuard(size_t size, size_t alignment, u32 type_id, - size_t guard_size) { + KVirtualAddress GetRandomAlignedRegionWithGuard(size_t size, size_t alignment, u32 type_id, + size_t guard_size) { return this->GetRandomAlignedRegion(size + 2 * guard_size, alignment, type_id) + guard_size; } diff --git a/src/core/hle/kernel/k_page_buffer.cpp b/src/core/hle/kernel/k_page_buffer.cpp index 0c16dded4..e9830e6d9 100644 --- a/src/core/hle/kernel/k_page_buffer.cpp +++ b/src/core/hle/kernel/k_page_buffer.cpp @@ -10,8 +10,8 @@ namespace Kernel { -KPageBuffer* KPageBuffer::FromPhysicalAddress(Core::System& system, PAddr phys_addr) { - ASSERT(Common::IsAligned(phys_addr, PageSize)); +KPageBuffer* KPageBuffer::FromPhysicalAddress(Core::System& system, KPhysicalAddress phys_addr) { + ASSERT(Common::IsAligned(GetInteger(phys_addr), PageSize)); return system.DeviceMemory().GetPointer(phys_addr); } diff --git a/src/core/hle/kernel/k_page_buffer.h b/src/core/hle/kernel/k_page_buffer.h index b7a3ccb4a..f6a7f1e39 100644 --- a/src/core/hle/kernel/k_page_buffer.h +++ b/src/core/hle/kernel/k_page_buffer.h @@ -26,7 +26,7 @@ public: explicit KPageBuffer(KernelCore&) {} KPageBuffer() = default; - static KPageBuffer* FromPhysicalAddress(Core::System& system, PAddr phys_addr); + static KPageBuffer* FromPhysicalAddress(Core::System& system, KPhysicalAddress phys_addr); private: alignas(PageSize) std::array m_buffer{}; diff --git a/src/core/hle/kernel/k_page_group.h b/src/core/hle/kernel/k_page_group.h index c07f17663..b32909f05 100644 --- a/src/core/hle/kernel/k_page_group.h +++ b/src/core/hle/kernel/k_page_group.h @@ -22,7 +22,7 @@ public: constexpr explicit KBlockInfo() : m_next(nullptr) {} constexpr void Initialize(KPhysicalAddress addr, size_t np) { - ASSERT(Common::IsAligned(addr, PageSize)); + ASSERT(Common::IsAligned(GetInteger(addr), PageSize)); ASSERT(static_cast(np) == np); m_page_index = static_cast(addr / PageSize); diff --git a/src/core/hle/kernel/k_page_heap.cpp b/src/core/hle/kernel/k_page_heap.cpp index 7b02c7d8b..95762b5a2 100644 --- a/src/core/hle/kernel/k_page_heap.cpp +++ b/src/core/hle/kernel/k_page_heap.cpp @@ -6,14 +6,14 @@ namespace Kernel { -void KPageHeap::Initialize(PAddr address, size_t size, VAddr management_address, - size_t management_size, const size_t* block_shifts, - size_t num_block_shifts) { +void KPageHeap::Initialize(KPhysicalAddress address, size_t size, + KVirtualAddress management_address, size_t management_size, + const size_t* block_shifts, size_t num_block_shifts) { // Check our assumptions. - ASSERT(Common::IsAligned(address, PageSize)); + ASSERT(Common::IsAligned(GetInteger(address), PageSize)); ASSERT(Common::IsAligned(size, PageSize)); ASSERT(0 < num_block_shifts && num_block_shifts <= NumMemoryBlockPageShifts); - const VAddr management_end = management_address + management_size; + const KVirtualAddress management_end = management_address + management_size; // Set our members. m_heap_address = address; @@ -31,7 +31,7 @@ void KPageHeap::Initialize(PAddr address, size_t size, VAddr management_address, } // Ensure we didn't overextend our bounds. - ASSERT(VAddr(cur_bitmap_storage) <= management_end); + ASSERT(KVirtualAddress(cur_bitmap_storage) <= management_end); } size_t KPageHeap::GetNumFreePages() const { @@ -44,11 +44,11 @@ size_t KPageHeap::GetNumFreePages() const { return num_free; } -PAddr KPageHeap::AllocateByLinearSearch(s32 index) { +KPhysicalAddress KPageHeap::AllocateByLinearSearch(s32 index) { const size_t needed_size = m_blocks[index].GetSize(); for (s32 i = index; i < static_cast(m_num_blocks); i++) { - if (const PAddr addr = m_blocks[i].PopBlock(false); addr != 0) { + if (const KPhysicalAddress addr = m_blocks[i].PopBlock(false); addr != 0) { if (const size_t allocated_size = m_blocks[i].GetSize(); allocated_size > needed_size) { this->Free(addr + needed_size, (allocated_size - needed_size) / PageSize); } @@ -59,7 +59,7 @@ PAddr KPageHeap::AllocateByLinearSearch(s32 index) { return 0; } -PAddr KPageHeap::AllocateByRandom(s32 index, size_t num_pages, size_t align_pages) { +KPhysicalAddress KPageHeap::AllocateByRandom(s32 index, size_t num_pages, size_t align_pages) { // Get the size and required alignment. const size_t needed_size = num_pages * PageSize; const size_t align_size = align_pages * PageSize; @@ -110,7 +110,7 @@ PAddr KPageHeap::AllocateByRandom(s32 index, size_t num_pages, size_t align_page } // Pop a block from the index we selected. - if (PAddr addr = m_blocks[index].PopBlock(true); addr != 0) { + if (KPhysicalAddress addr = m_blocks[index].PopBlock(true); addr != 0) { // Determine how much size we have left over. if (const size_t leftover_size = m_blocks[index].GetSize() - needed_size; leftover_size > 0) { @@ -141,13 +141,13 @@ PAddr KPageHeap::AllocateByRandom(s32 index, size_t num_pages, size_t align_page return 0; } -void KPageHeap::FreeBlock(PAddr block, s32 index) { +void KPageHeap::FreeBlock(KPhysicalAddress block, s32 index) { do { block = m_blocks[index++].PushBlock(block); } while (block != 0); } -void KPageHeap::Free(PAddr addr, size_t num_pages) { +void KPageHeap::Free(KPhysicalAddress addr, size_t num_pages) { // Freeing no pages is a no-op. if (num_pages == 0) { return; @@ -155,16 +155,16 @@ void KPageHeap::Free(PAddr addr, size_t num_pages) { // Find the largest block size that we can free, and free as many as possible. s32 big_index = static_cast(m_num_blocks) - 1; - const PAddr start = addr; - const PAddr end = addr + num_pages * PageSize; - PAddr before_start = start; - PAddr before_end = start; - PAddr after_start = end; - PAddr after_end = end; + const KPhysicalAddress start = addr; + const KPhysicalAddress end = addr + num_pages * PageSize; + KPhysicalAddress before_start = start; + KPhysicalAddress before_end = start; + KPhysicalAddress after_start = end; + KPhysicalAddress after_end = end; while (big_index >= 0) { const size_t block_size = m_blocks[big_index].GetSize(); - const PAddr big_start = Common::AlignUp(start, block_size); - const PAddr big_end = Common::AlignDown(end, block_size); + const KPhysicalAddress big_start = Common::AlignUp(GetInteger(start), block_size); + const KPhysicalAddress big_end = Common::AlignDown(GetInteger(end), block_size); if (big_start < big_end) { // Free as many big blocks as we can. for (auto block = big_start; block < big_end; block += block_size) { diff --git a/src/core/hle/kernel/k_page_heap.h b/src/core/hle/kernel/k_page_heap.h index 9021edcf7..c55225bac 100644 --- a/src/core/hle/kernel/k_page_heap.h +++ b/src/core/hle/kernel/k_page_heap.h @@ -8,8 +8,8 @@ #include "common/alignment.h" #include "common/common_funcs.h" -#include "common/common_types.h" #include "core/hle/kernel/k_page_bitmap.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/kernel/memory_types.h" namespace Kernel { @@ -18,24 +18,24 @@ class KPageHeap { public: KPageHeap() = default; - constexpr PAddr GetAddress() const { + constexpr KPhysicalAddress GetAddress() const { return m_heap_address; } constexpr size_t GetSize() const { return m_heap_size; } - constexpr PAddr GetEndAddress() const { + constexpr KPhysicalAddress GetEndAddress() const { return this->GetAddress() + this->GetSize(); } - constexpr size_t GetPageOffset(PAddr block) const { + constexpr size_t GetPageOffset(KPhysicalAddress block) const { return (block - this->GetAddress()) / PageSize; } - constexpr size_t GetPageOffsetToEnd(PAddr block) const { + constexpr size_t GetPageOffsetToEnd(KPhysicalAddress block) const { return (this->GetEndAddress() - block) / PageSize; } - void Initialize(PAddr heap_address, size_t heap_size, VAddr management_address, - size_t management_size) { + void Initialize(KPhysicalAddress heap_address, size_t heap_size, + KVirtualAddress management_address, size_t management_size) { return this->Initialize(heap_address, heap_size, management_address, management_size, MemoryBlockPageShifts.data(), NumMemoryBlockPageShifts); } @@ -53,7 +53,7 @@ public: m_initial_used_size = m_heap_size - free_size - reserved_size; } - PAddr AllocateBlock(s32 index, bool random) { + KPhysicalAddress AllocateBlock(s32 index, bool random) { if (random) { const size_t block_pages = m_blocks[index].GetNumPages(); return this->AllocateByRandom(index, block_pages, block_pages); @@ -62,12 +62,12 @@ public: } } - PAddr AllocateAligned(s32 index, size_t num_pages, size_t align_pages) { + KPhysicalAddress AllocateAligned(s32 index, size_t num_pages, size_t align_pages) { // TODO: linear search support? return this->AllocateByRandom(index, num_pages, align_pages); } - void Free(PAddr addr, size_t num_pages); + void Free(KPhysicalAddress addr, size_t num_pages); static size_t CalculateManagementOverheadSize(size_t region_size) { return CalculateManagementOverheadSize(region_size, MemoryBlockPageShifts.data(), @@ -125,24 +125,25 @@ private: return this->GetNumFreeBlocks() * this->GetNumPages(); } - u64* Initialize(PAddr addr, size_t size, size_t bs, size_t nbs, u64* bit_storage) { + u64* Initialize(KPhysicalAddress addr, size_t size, size_t bs, size_t nbs, + u64* bit_storage) { // Set shifts. m_block_shift = bs; m_next_block_shift = nbs; // Align up the address. - PAddr end = addr + size; + KPhysicalAddress end = addr + size; const size_t align = (m_next_block_shift != 0) ? (u64(1) << m_next_block_shift) : (u64(1) << m_block_shift); - addr = Common::AlignDown(addr, align); - end = Common::AlignUp(end, align); + addr = Common::AlignDown(GetInteger(addr), align); + end = Common::AlignUp(GetInteger(end), align); m_heap_address = addr; m_end_offset = (end - addr) / (u64(1) << m_block_shift); return m_bitmap.Initialize(bit_storage, m_end_offset); } - PAddr PushBlock(PAddr address) { + KPhysicalAddress PushBlock(KPhysicalAddress address) { // Set the bit for the free block. size_t offset = (address - m_heap_address) >> this->GetShift(); m_bitmap.SetBit(offset); @@ -161,7 +162,7 @@ private: return {}; } - PAddr PopBlock(bool random) { + KPhysicalAddress PopBlock(bool random) { // Find a free block. s64 soffset = m_bitmap.FindFreeBlock(random); if (soffset < 0) { @@ -187,18 +188,19 @@ private: private: KPageBitmap m_bitmap; - PAddr m_heap_address{}; + KPhysicalAddress m_heap_address{}; uintptr_t m_end_offset{}; size_t m_block_shift{}; size_t m_next_block_shift{}; }; private: - void Initialize(PAddr heap_address, size_t heap_size, VAddr management_address, - size_t management_size, const size_t* block_shifts, size_t num_block_shifts); + void Initialize(KPhysicalAddress heap_address, size_t heap_size, + KVirtualAddress management_address, size_t management_size, + const size_t* block_shifts, size_t num_block_shifts); size_t GetNumFreePages() const; - void FreeBlock(PAddr block, s32 index); + void FreeBlock(KPhysicalAddress block, s32 index); static constexpr size_t NumMemoryBlockPageShifts{7}; static constexpr std::array MemoryBlockPageShifts{ @@ -206,14 +208,14 @@ private: }; private: - PAddr AllocateByLinearSearch(s32 index); - PAddr AllocateByRandom(s32 index, size_t num_pages, size_t align_pages); + KPhysicalAddress AllocateByLinearSearch(s32 index); + KPhysicalAddress AllocateByRandom(s32 index, size_t num_pages, size_t align_pages); static size_t CalculateManagementOverheadSize(size_t region_size, const size_t* block_shifts, size_t num_block_shifts); private: - PAddr m_heap_address{}; + KPhysicalAddress m_heap_address{}; size_t m_heap_size{}; size_t m_initial_used_size{}; size_t m_num_blocks{}; diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index 2e13d5d0d..cb39387ea 100644 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp @@ -106,7 +106,7 @@ KPageTable::~KPageTable() = default; Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, bool enable_das_merge, bool from_back, - KMemoryManager::Pool pool, VAddr code_addr, + KMemoryManager::Pool pool, KProcessAddress code_addr, size_t code_size, KSystemResource* system_resource, KResourceLimit* resource_limit) { @@ -119,8 +119,8 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type // Set our width and heap/alias sizes m_address_space_width = GetAddressSpaceWidthFromType(as_type); - const VAddr start = 0; - const VAddr end{1ULL << m_address_space_width}; + const KProcessAddress start = 0; + const KProcessAddress end{1ULL << m_address_space_width}; size_t alias_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Alias)}; size_t heap_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Heap)}; @@ -135,8 +135,8 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type // Set code regions and determine remaining constexpr size_t RegionAlignment{2_MiB}; - VAddr process_code_start{}; - VAddr process_code_end{}; + KProcessAddress process_code_start{}; + KProcessAddress process_code_end{}; size_t stack_region_size{}; size_t kernel_map_region_size{}; @@ -149,8 +149,8 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type::Map39Bit); m_alias_code_region_start = m_code_region_start; m_alias_code_region_end = m_code_region_end; - process_code_start = Common::AlignDown(code_addr, RegionAlignment); - process_code_end = Common::AlignUp(code_addr + code_size, RegionAlignment); + process_code_start = Common::AlignDown(GetInteger(code_addr), RegionAlignment); + process_code_end = Common::AlignUp(GetInteger(code_addr) + code_size, RegionAlignment); } else { stack_region_size = 0; kernel_map_region_size = 0; @@ -178,7 +178,7 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type m_resource_limit = resource_limit; // Determine the region we can place our undetermineds in - VAddr alloc_start{}; + KProcessAddress alloc_start{}; size_t alloc_size{}; if ((process_code_start - m_code_region_start) >= (end - process_code_end)) { alloc_start = m_code_region_start; @@ -292,7 +292,7 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type : KMemoryManager::Direction::FromFront); // Ensure that we regions inside our address space - auto IsInAddressSpace = [&](VAddr addr) { + auto IsInAddressSpace = [&](KProcessAddress addr) { return m_address_space_start <= addr && addr <= m_address_space_end; }; ASSERT(IsInAddressSpace(m_alias_region_start)); @@ -305,14 +305,14 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type ASSERT(IsInAddressSpace(m_kernel_map_region_end)); // Ensure that we selected regions that don't overlap - const VAddr alias_start{m_alias_region_start}; - const VAddr alias_last{m_alias_region_end - 1}; - const VAddr heap_start{m_heap_region_start}; - const VAddr heap_last{m_heap_region_end - 1}; - const VAddr stack_start{m_stack_region_start}; - const VAddr stack_last{m_stack_region_end - 1}; - const VAddr kmap_start{m_kernel_map_region_start}; - const VAddr kmap_last{m_kernel_map_region_end - 1}; + const KProcessAddress alias_start{m_alias_region_start}; + const KProcessAddress alias_last{m_alias_region_end - 1}; + const KProcessAddress heap_start{m_heap_region_start}; + const KProcessAddress heap_last{m_heap_region_end - 1}; + const KProcessAddress stack_start{m_stack_region_start}; + const KProcessAddress stack_last{m_stack_region_end - 1}; + const KProcessAddress kmap_start{m_kernel_map_region_start}; + const KProcessAddress kmap_last{m_kernel_map_region_end - 1}; ASSERT(alias_last < heap_start || heap_last < alias_start); ASSERT(alias_last < stack_start || stack_last < alias_start); ASSERT(alias_last < kmap_start || kmap_last < alias_start); @@ -334,9 +334,10 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type void KPageTable::Finalize() { // Finalize memory blocks. - m_memory_block_manager.Finalize(m_memory_block_slab_manager, [&](VAddr addr, u64 size) { - m_system.Memory().UnmapRegion(*m_page_table_impl, addr, size); - }); + m_memory_block_manager.Finalize( + m_memory_block_slab_manager, [&](KProcessAddress addr, u64 size) { + m_system.Memory().UnmapRegion(*m_page_table_impl, addr, size); + }); // Release any insecure mapped memory. if (m_mapped_insecure_memory) { @@ -352,7 +353,7 @@ void KPageTable::Finalize() { m_page_table_impl.reset(); } -Result KPageTable::MapProcessCode(VAddr addr, size_t num_pages, KMemoryState state, +Result KPageTable::MapProcessCode(KProcessAddress addr, size_t num_pages, KMemoryState state, KMemoryPermission perm) { const u64 size{num_pages * PageSize}; @@ -388,7 +389,8 @@ Result KPageTable::MapProcessCode(VAddr addr, size_t num_pages, KMemoryState sta R_SUCCEED(); } -Result KPageTable::MapCodeMemory(VAddr dst_address, VAddr src_address, size_t size) { +Result KPageTable::MapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, + size_t size) { // Validate the mapping request. R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode), ResultInvalidMemoryRegion); @@ -473,7 +475,8 @@ Result KPageTable::MapCodeMemory(VAddr dst_address, VAddr src_address, size_t si R_SUCCEED(); } -Result KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, size_t size, +Result KPageTable::UnmapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, + size_t size, ICacheInvalidationStrategy icache_invalidation_strategy) { // Validate the mapping request. R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode), @@ -525,7 +528,7 @@ Result KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, size_t SCOPE_EXIT({ if (reprotected_pages && any_code_pages) { if (icache_invalidation_strategy == ICacheInvalidationStrategy::InvalidateRange) { - m_system.InvalidateCpuInstructionCacheRange(dst_address, size); + m_system.InvalidateCpuInstructionCacheRange(GetInteger(dst_address), size); } else { m_system.InvalidateCpuInstructionCaches(); } @@ -575,9 +578,10 @@ Result KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, size_t R_SUCCEED(); } -VAddr KPageTable::FindFreeArea(VAddr region_start, size_t region_num_pages, size_t num_pages, - size_t alignment, size_t offset, size_t guard_pages) { - VAddr address = 0; +KProcessAddress KPageTable::FindFreeArea(KProcessAddress region_start, size_t region_num_pages, + size_t num_pages, size_t alignment, size_t offset, + size_t guard_pages) { + KProcessAddress address = 0; if (num_pages <= region_num_pages) { if (this->IsAslrEnabled()) { @@ -593,7 +597,7 @@ VAddr KPageTable::FindFreeArea(VAddr region_start, size_t region_num_pages, size return address; } -Result KPageTable::MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages) { +Result KPageTable::MakePageGroup(KPageGroup& pg, KProcessAddress addr, size_t num_pages) { ASSERT(this->IsLockedByCurrentThread()); const size_t size = num_pages * PageSize; @@ -604,11 +608,11 @@ Result KPageTable::MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages) { // Begin traversal. Common::PageTable::TraversalContext context; Common::PageTable::TraversalEntry next_entry; - R_UNLESS(m_page_table_impl->BeginTraversal(next_entry, context, addr), + R_UNLESS(m_page_table_impl->BeginTraversal(next_entry, context, GetInteger(addr)), ResultInvalidCurrentMemory); // Prepare tracking variables. - PAddr cur_addr = next_entry.phys_addr; + KPhysicalAddress cur_addr = next_entry.phys_addr; size_t cur_size = next_entry.block_size - (cur_addr & (next_entry.block_size - 1)); size_t tot_size = cur_size; @@ -646,7 +650,7 @@ 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, KProcessAddress addr, size_t num_pages) { ASSERT(this->IsLockedByCurrentThread()); const size_t size = num_pages * PageSize; @@ -659,7 +663,7 @@ bool KPageTable::IsValidPageGroup(const KPageGroup& pg, VAddr addr, size_t num_p // We're going to validate that the group we'd expect is the group we see. auto cur_it = pg.begin(); - PAddr cur_block_address = cur_it->GetAddress(); + KPhysicalAddress cur_block_address = cur_it->GetAddress(); size_t cur_block_pages = cur_it->GetNumPages(); auto UpdateCurrentIterator = [&]() { @@ -677,12 +681,12 @@ bool KPageTable::IsValidPageGroup(const KPageGroup& pg, VAddr addr, size_t num_p // Begin traversal. Common::PageTable::TraversalContext context; Common::PageTable::TraversalEntry next_entry; - if (!m_page_table_impl->BeginTraversal(next_entry, context, addr)) { + if (!m_page_table_impl->BeginTraversal(next_entry, context, GetInteger(addr))) { return false; } // Prepare tracking variables. - PAddr cur_addr = next_entry.phys_addr; + KPhysicalAddress cur_addr = next_entry.phys_addr; size_t cur_size = next_entry.block_size - (cur_addr & (next_entry.block_size - 1)); size_t tot_size = cur_size; @@ -734,8 +738,8 @@ bool KPageTable::IsValidPageGroup(const KPageGroup& pg, VAddr addr, size_t num_p return cur_block_address == cur_addr && cur_block_pages == (cur_size / PageSize); } -Result KPageTable::UnmapProcessMemory(VAddr dst_addr, size_t size, KPageTable& src_page_table, - VAddr src_addr) { +Result KPageTable::UnmapProcessMemory(KProcessAddress dst_addr, size_t size, + KPageTable& src_page_table, KProcessAddress src_addr) { // Acquire the table locks. KScopedLightLockPair lk(src_page_table.m_general_lock, m_general_lock); @@ -774,8 +778,8 @@ Result KPageTable::UnmapProcessMemory(VAddr dst_addr, size_t size, KPageTable& s } Result KPageTable::SetupForIpcClient(PageLinkedList* page_list, size_t* out_blocks_needed, - VAddr address, size_t size, KMemoryPermission test_perm, - KMemoryState dst_state) { + KProcessAddress address, size_t size, + KMemoryPermission test_perm, KMemoryState dst_state) { // Validate pre-conditions. ASSERT(this->IsLockedByCurrentThread()); ASSERT(test_perm == KMemoryPermission::UserReadWrite || @@ -790,10 +794,10 @@ Result KPageTable::SetupForIpcClient(PageLinkedList* page_list, size_t* out_bloc : KMemoryPermission::UserRead; // Get aligned extents. - const VAddr aligned_src_start = Common::AlignDown((address), PageSize); - const VAddr aligned_src_end = Common::AlignUp((address) + size, PageSize); - const VAddr mapping_src_start = Common::AlignUp((address), PageSize); - const VAddr mapping_src_end = Common::AlignDown((address) + size, PageSize); + const KProcessAddress aligned_src_start = Common::AlignDown(GetInteger(address), PageSize); + const KProcessAddress aligned_src_end = Common::AlignUp(GetInteger(address) + size, PageSize); + const KProcessAddress mapping_src_start = Common::AlignUp(GetInteger(address), PageSize); + const KProcessAddress mapping_src_end = Common::AlignDown(GetInteger(address) + size, PageSize); const auto aligned_src_last = (aligned_src_end)-1; const auto mapping_src_last = (mapping_src_end)-1; @@ -840,14 +844,15 @@ Result KPageTable::SetupForIpcClient(PageLinkedList* page_list, size_t* out_bloc test_attr_mask, KMemoryAttribute::None)); if (mapping_src_start < mapping_src_end && (mapping_src_start) < info.GetEndAddress() && - info.GetAddress() < (mapping_src_end)) { - const auto cur_start = - info.GetAddress() >= (mapping_src_start) ? info.GetAddress() : (mapping_src_start); + info.GetAddress() < GetInteger(mapping_src_end)) { + const auto cur_start = info.GetAddress() >= GetInteger(mapping_src_start) + ? info.GetAddress() + : (mapping_src_start); const auto cur_end = mapping_src_last >= info.GetLastAddress() ? info.GetEndAddress() : (mapping_src_end); const size_t cur_size = cur_end - cur_start; - if (info.GetAddress() < (mapping_src_start)) { + if (info.GetAddress() < GetInteger(mapping_src_start)) { ++blocks_needed; } if (mapping_src_last < info.GetLastAddress()) { @@ -882,30 +887,32 @@ Result KPageTable::SetupForIpcClient(PageLinkedList* page_list, size_t* out_bloc R_SUCCEED(); } -Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_addr, - KMemoryPermission test_perm, KMemoryState dst_state, - KPageTable& src_page_table, bool send) { +Result KPageTable::SetupForIpcServer(KProcessAddress* out_addr, size_t size, + KProcessAddress src_addr, KMemoryPermission test_perm, + KMemoryState dst_state, KPageTable& src_page_table, + bool send) { ASSERT(this->IsLockedByCurrentThread()); ASSERT(src_page_table.IsLockedByCurrentThread()); // Check that we can theoretically map. - const VAddr region_start = m_alias_region_start; + const KProcessAddress region_start = m_alias_region_start; const size_t region_size = m_alias_region_end - m_alias_region_start; R_UNLESS(size < region_size, ResultOutOfAddressSpace); // Get aligned source extents. - const VAddr src_start = src_addr; - const VAddr src_end = src_addr + size; - const VAddr aligned_src_start = Common::AlignDown((src_start), PageSize); - const VAddr aligned_src_end = Common::AlignUp((src_start) + size, PageSize); - const VAddr mapping_src_start = Common::AlignUp((src_start), PageSize); - const VAddr mapping_src_end = Common::AlignDown((src_start) + size, PageSize); + const KProcessAddress src_start = src_addr; + const KProcessAddress src_end = src_addr + size; + const KProcessAddress aligned_src_start = Common::AlignDown(GetInteger(src_start), PageSize); + const KProcessAddress aligned_src_end = Common::AlignUp(GetInteger(src_start) + size, PageSize); + const KProcessAddress mapping_src_start = Common::AlignUp(GetInteger(src_start), PageSize); + const KProcessAddress mapping_src_end = + Common::AlignDown(GetInteger(src_start) + size, PageSize); const size_t aligned_src_size = aligned_src_end - aligned_src_start; const size_t mapping_src_size = (mapping_src_start < mapping_src_end) ? (mapping_src_end - mapping_src_start) : 0; // Select a random address to map at. - VAddr dst_addr = + KProcessAddress dst_addr = this->FindFreeArea(region_start, region_size / PageSize, aligned_src_size / PageSize, PageSize, 0, this->GetNumGuardPages()); @@ -930,9 +937,9 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); // Ensure that we manage page references correctly. - PAddr start_partial_page = 0; - PAddr end_partial_page = 0; - VAddr cur_mapped_addr = dst_addr; + KPhysicalAddress start_partial_page = 0; + KPhysicalAddress end_partial_page = 0; + KProcessAddress cur_mapped_addr = dst_addr; // If the partial pages are mapped, an extra reference will have been opened. Otherwise, they'll // free on scope exit. @@ -977,11 +984,12 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add // Begin traversal. Common::PageTable::TraversalContext context; Common::PageTable::TraversalEntry next_entry; - bool traverse_valid = src_impl.BeginTraversal(next_entry, context, aligned_src_start); + bool traverse_valid = + src_impl.BeginTraversal(next_entry, context, GetInteger(aligned_src_start)); ASSERT(traverse_valid); // Prepare tracking variables. - PAddr cur_block_addr = next_entry.phys_addr; + KPhysicalAddress cur_block_addr = next_entry.phys_addr; size_t cur_block_size = next_entry.block_size - ((cur_block_addr) & (next_entry.block_size - 1)); size_t tot_block_size = cur_block_size; @@ -989,7 +997,7 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add // Map the start page, if we have one. if (start_partial_page != 0) { // Ensure the page holds correct data. - const VAddr start_partial_virt = + const KVirtualAddress start_partial_virt = GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), start_partial_page); if (send) { const size_t partial_offset = src_start - aligned_src_start; @@ -1002,21 +1010,23 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add clear_size = 0; } - std::memset(m_system.Memory().GetPointer(start_partial_virt), fill_val, - partial_offset); + std::memset(m_system.Memory().GetPointer(GetInteger(start_partial_virt)), + fill_val, partial_offset); std::memcpy( - m_system.Memory().GetPointer(start_partial_virt + partial_offset), + m_system.Memory().GetPointer(GetInteger(start_partial_virt) + partial_offset), m_system.Memory().GetPointer( - GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), cur_block_addr) + + GetInteger( + GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), cur_block_addr)) + partial_offset), copy_size); if (clear_size > 0) { - std::memset(m_system.Memory().GetPointer(start_partial_virt + partial_offset + - copy_size), + std::memset(m_system.Memory().GetPointer(GetInteger(start_partial_virt) + + partial_offset + copy_size), fill_val, clear_size); } } else { - std::memset(m_system.Memory().GetPointer(start_partial_virt), fill_val, PageSize); + std::memset(m_system.Memory().GetPointer(GetInteger(start_partial_virt)), + fill_val, PageSize); } // Map the page. @@ -1061,7 +1071,8 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add } // Handle the last direct-mapped page. - if (const VAddr mapped_block_end = aligned_src_start + tot_block_size - cur_block_size; + if (const KProcessAddress mapped_block_end = + aligned_src_start + tot_block_size - cur_block_size; mapped_block_end < mapping_src_end) { const size_t last_block_size = mapping_src_end - mapped_block_end; @@ -1084,18 +1095,20 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add // Map the end page, if we have one. if (end_partial_page != 0) { // Ensure the page holds correct data. - const VAddr end_partial_virt = + const KVirtualAddress end_partial_virt = GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), end_partial_page); if (send) { const size_t copy_size = src_end - mapping_src_end; - std::memcpy(m_system.Memory().GetPointer(end_partial_virt), - m_system.Memory().GetPointer(GetHeapVirtualAddress( - m_system.Kernel().MemoryLayout(), cur_block_addr)), + std::memcpy(m_system.Memory().GetPointer(GetInteger(end_partial_virt)), + m_system.Memory().GetPointer(GetInteger(GetHeapVirtualAddress( + m_system.Kernel().MemoryLayout(), cur_block_addr))), copy_size); - std::memset(m_system.Memory().GetPointer(end_partial_virt + copy_size), fill_val, - PageSize - copy_size); + std::memset( + m_system.Memory().GetPointer(GetInteger(end_partial_virt) + copy_size), + fill_val, PageSize - copy_size); } else { - std::memset(m_system.Memory().GetPointer(end_partial_virt), fill_val, PageSize); + std::memset(m_system.Memory().GetPointer(GetInteger(end_partial_virt)), fill_val, + PageSize); } // Map the page. @@ -1116,7 +1129,7 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add R_SUCCEED(); } -Result KPageTable::SetupForIpc(VAddr* out_dst_addr, size_t size, VAddr src_addr, +Result KPageTable::SetupForIpc(KProcessAddress* out_dst_addr, size_t size, KProcessAddress src_addr, KPageTable& src_page_table, KMemoryPermission test_perm, KMemoryState dst_state, bool send) { // For convenience, alias this. @@ -1142,8 +1155,8 @@ Result KPageTable::SetupForIpc(VAddr* out_dst_addr, size_t size, VAddr src_addr, R_TRY(allocator_result); // Get the mapped extents. - const VAddr src_map_start = Common::AlignUp((src_addr), PageSize); - const VAddr src_map_end = Common::AlignDown((src_addr) + size, PageSize); + const KProcessAddress src_map_start = Common::AlignUp(GetInteger(src_addr), PageSize); + const KProcessAddress src_map_end = Common::AlignDown(GetInteger(src_addr) + size, PageSize); const size_t src_map_size = src_map_end - src_map_start; // Ensure that we clean up appropriately if we fail after this. @@ -1172,7 +1185,8 @@ Result KPageTable::SetupForIpc(VAddr* out_dst_addr, size_t size, VAddr src_addr, R_SUCCEED(); } -Result KPageTable::CleanupForIpcServer(VAddr address, size_t size, KMemoryState dst_state) { +Result KPageTable::CleanupForIpcServer(KProcessAddress address, size_t size, + KMemoryState dst_state) { // Validate the address. R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory); @@ -1196,8 +1210,8 @@ Result KPageTable::CleanupForIpcServer(VAddr address, size_t size, KMemoryState KScopedPageTableUpdater updater(this); // Get aligned extents. - const VAddr aligned_start = Common::AlignDown((address), PageSize); - const VAddr aligned_end = Common::AlignUp((address) + size, PageSize); + const KProcessAddress aligned_start = Common::AlignDown(GetInteger(address), PageSize); + const KProcessAddress aligned_end = Common::AlignUp(GetInteger(address) + size, PageSize); const size_t aligned_size = aligned_end - aligned_start; const size_t aligned_num_pages = aligned_size / PageSize; @@ -1211,22 +1225,23 @@ Result KPageTable::CleanupForIpcServer(VAddr address, size_t size, KMemoryState KMemoryBlockDisableMergeAttribute::Normal); // Release from the resource limit as relevant. - const VAddr mapping_start = Common::AlignUp((address), PageSize); - const VAddr mapping_end = Common::AlignDown((address) + size, PageSize); + const KProcessAddress mapping_start = Common::AlignUp(GetInteger(address), PageSize); + const KProcessAddress mapping_end = Common::AlignDown(GetInteger(address) + size, PageSize); const size_t mapping_size = (mapping_start < mapping_end) ? mapping_end - mapping_start : 0; m_resource_limit->Release(LimitableResource::PhysicalMemoryMax, aligned_size - mapping_size); R_SUCCEED(); } -Result KPageTable::CleanupForIpcClient(VAddr address, size_t size, KMemoryState dst_state) { +Result KPageTable::CleanupForIpcClient(KProcessAddress address, size_t size, + KMemoryState dst_state) { // Validate the address. R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory); // Get aligned source extents. - const VAddr mapping_start = Common::AlignUp((address), PageSize); - const VAddr mapping_end = Common::AlignDown((address) + size, PageSize); - const VAddr mapping_last = mapping_end - 1; + const KProcessAddress mapping_start = Common::AlignUp(GetInteger(address), PageSize); + const KProcessAddress mapping_end = Common::AlignDown(GetInteger(address) + size, PageSize); + const KProcessAddress mapping_last = mapping_end - 1; const size_t mapping_size = (mapping_start < mapping_end) ? (mapping_end - mapping_start) : 0; // If nothing was mapped, we're actually done immediately. @@ -1279,7 +1294,7 @@ Result KPageTable::CleanupForIpcClient(VAddr address, size_t size, KMemoryState KMemoryInfo cur_info = start_it->GetMemoryInfo(); // Create tracking variables. - VAddr cur_address = cur_info.GetAddress(); + KProcessAddress cur_address = cur_info.GetAddress(); size_t cur_size = cur_info.GetSize(); bool cur_perm_eq = cur_info.GetPermission() == cur_info.GetOriginalPermission(); bool cur_needs_set_perm = !cur_perm_eq && cur_info.GetIpcLockCount() == 1; @@ -1352,7 +1367,7 @@ Result KPageTable::CleanupForIpcClient(VAddr address, size_t size, KMemoryState .IsSuccess()); // Create tracking variables. - VAddr cur_address = cur_info.GetAddress(); + KProcessAddress cur_address = cur_info.GetAddress(); size_t cur_size = cur_info.GetSize(); bool cur_perm_eq = cur_info.GetPermission() == cur_info.GetOriginalPermission(); bool cur_needs_set_perm = !cur_perm_eq && cur_info.GetIpcLockCount() == 1; @@ -1439,16 +1454,16 @@ Result KPageTable::CleanupForIpcClient(VAddr address, size_t size, KMemoryState } void KPageTable::CleanupForIpcClientOnServerSetupFailure([[maybe_unused]] PageLinkedList* page_list, - VAddr address, size_t size, + KProcessAddress address, size_t size, KMemoryPermission prot_perm) { ASSERT(this->IsLockedByCurrentThread()); - ASSERT(Common::IsAligned(address, PageSize)); + ASSERT(Common::IsAligned(GetInteger(address), PageSize)); ASSERT(Common::IsAligned(size, PageSize)); // Get the mapped extents. - const VAddr src_map_start = address; - const VAddr src_map_end = address + size; - const VAddr src_map_last = src_map_end - 1; + const KProcessAddress src_map_start = address; + const KProcessAddress src_map_end = address + size; + const KProcessAddress src_map_last = src_map_end - 1; // This function is only invoked when there's something to do. ASSERT(src_map_end > src_map_start); @@ -1458,8 +1473,9 @@ void KPageTable::CleanupForIpcClientOnServerSetupFailure([[maybe_unused]] PageLi while (true) { const KMemoryInfo info = it->GetMemoryInfo(); - const auto cur_start = - info.GetAddress() >= src_map_start ? info.GetAddress() : src_map_start; + const auto cur_start = info.GetAddress() >= GetInteger(src_map_start) + ? info.GetAddress() + : GetInteger(src_map_start); const auto cur_end = src_map_last <= info.GetLastAddress() ? src_map_end : info.GetEndAddress(); @@ -1469,7 +1485,7 @@ void KPageTable::CleanupForIpcClientOnServerSetupFailure([[maybe_unused]] PageLi (info.GetIpcLockCount() != 0 && (info.GetOriginalPermission() & KMemoryPermission::IpcLockChangeMask) != prot_perm)) { // Check if we actually need to fix the protections on the block. - if (cur_end == src_map_end || info.GetAddress() <= src_map_start || + if (cur_end == src_map_end || info.GetAddress() <= GetInteger(src_map_start) || (info.GetPermission() & KMemoryPermission::IpcLockChangeMask) != prot_perm) { ASSERT(Operate(cur_start, (cur_end - cur_start) / PageSize, info.GetPermission(), OperationType::ChangePermissions) @@ -1488,15 +1504,15 @@ void KPageTable::CleanupForIpcClientOnServerSetupFailure([[maybe_unused]] PageLi } } -Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) { +Result KPageTable::MapPhysicalMemory(KProcessAddress address, size_t size) { // Lock the physical memory lock. KScopedLightLock phys_lk(m_map_physical_memory_lock); // Calculate the last address for convenience. - const VAddr last_address = address + size - 1; + const KProcessAddress last_address = address + size - 1; // Define iteration variables. - VAddr cur_address; + KProcessAddress cur_address; size_t mapped_size; // The entire mapping process can be retried. @@ -1528,7 +1544,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) { // Track the memory if it's mapped. if (info.GetState() != KMemoryState::Free) { - mapped_size += VAddr(info.GetEndAddress()) - cur_address; + mapped_size += KProcessAddress(info.GetEndAddress()) - cur_address; } // Advance. @@ -1581,7 +1597,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) { const bool is_free = info.GetState() == KMemoryState::Free; if (is_free) { - if (info.GetAddress() < address) { + if (info.GetAddress() < GetInteger(address)) { ++num_allocator_blocks; } if (last_address < info.GetLastAddress()) { @@ -1599,7 +1615,8 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) { // Track the memory if it's mapped. if (!is_free) { - checked_mapped_size += VAddr(info.GetEndAddress()) - cur_address; + checked_mapped_size += + KProcessAddress(info.GetEndAddress()) - cur_address; } // Advance. @@ -1627,7 +1644,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) { // Prepare to iterate over the memory. auto pg_it = pg.begin(); - PAddr pg_phys_addr = pg_it->GetAddress(); + KPhysicalAddress pg_phys_addr = pg_it->GetAddress(); size_t pg_pages = pg_it->GetNumPages(); // Reset the current tracking address, and make sure we clean up on failure. @@ -1635,7 +1652,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) { cur_address = address; ON_RESULT_FAILURE { if (cur_address > address) { - const VAddr last_unmap_address = cur_address - 1; + const KProcessAddress last_unmap_address = cur_address - 1; // Iterate, unmapping the pages. cur_address = address; @@ -1652,7 +1669,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) { if (info.GetState() == KMemoryState::Free) { // Determine the range to unmap. const size_t cur_pages = - std::min(VAddr(info.GetEndAddress()) - cur_address, + std::min(KProcessAddress(info.GetEndAddress()) - cur_address, last_unmap_address + 1 - cur_address) / PageSize; @@ -1695,9 +1712,10 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) { // If it's unmapped, we need to map it. if (info.GetState() == KMemoryState::Free) { // Determine the range to map. - size_t map_pages = std::min(VAddr(info.GetEndAddress()) - cur_address, - last_address + 1 - cur_address) / - PageSize; + size_t map_pages = + std::min(KProcessAddress(info.GetEndAddress()) - cur_address, + last_address + 1 - cur_address) / + PageSize; // While we have pages to map, map them. while (map_pages > 0) { @@ -1754,7 +1772,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) { } } -Result KPageTable::UnmapPhysicalMemory(VAddr address, size_t size) { +Result KPageTable::UnmapPhysicalMemory(KProcessAddress address, size_t size) { // Lock the physical memory lock. KScopedLightLock phys_lk(m_map_physical_memory_lock); @@ -1762,13 +1780,13 @@ Result KPageTable::UnmapPhysicalMemory(VAddr address, size_t size) { KScopedLightLock lk(m_general_lock); // Calculate the last address for convenience. - const VAddr last_address = address + size - 1; + const KProcessAddress last_address = address + size - 1; // Define iteration variables. - VAddr map_start_address = 0; - VAddr map_last_address = 0; + KProcessAddress map_start_address = 0; + KProcessAddress map_last_address = 0; - VAddr cur_address; + KProcessAddress cur_address; size_t mapped_size; size_t num_allocator_blocks = 0; @@ -1801,7 +1819,7 @@ Result KPageTable::UnmapPhysicalMemory(VAddr address, size_t size) { map_last_address = (last_address >= info.GetLastAddress()) ? info.GetLastAddress() : last_address; - if (info.GetAddress() < address) { + if (info.GetAddress() < GetInteger(address)) { ++num_allocator_blocks; } if (last_address < info.GetLastAddress()) { @@ -1854,7 +1872,7 @@ Result KPageTable::UnmapPhysicalMemory(VAddr address, size_t size) { // If the memory state is normal, we need to unmap it. if (info.GetState() == KMemoryState::Normal) { // Determine the range to unmap. - const size_t cur_pages = std::min(VAddr(info.GetEndAddress()) - cur_address, + const size_t cur_pages = std::min(KProcessAddress(info.GetEndAddress()) - cur_address, last_address + 1 - cur_address) / PageSize; @@ -2144,13 +2162,14 @@ void KPageTable::RemapPageGroup(PageLinkedList* page_list, KProcessAddress addre const KMemoryInfo info = it->GetMemoryInfo(); // Determine the range to map. - KProcessAddress map_address = std::max(info.GetAddress(), start_address); - const KProcessAddress map_end_address = std::min(info.GetEndAddress(), end_address); + KProcessAddress map_address = std::max(info.GetAddress(), start_address); + const KProcessAddress map_end_address = + std::min(info.GetEndAddress(), end_address); ASSERT(map_end_address != map_address); // Determine if we should disable head merge. const bool disable_head_merge = - info.GetAddress() >= start_address && + info.GetAddress() >= GetInteger(start_address) && True(info.GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute::Normal); const KPageProperties map_properties = { info.GetPermission(), false, false, @@ -2214,7 +2233,7 @@ Result KPageTable::MapPages(KProcessAddress* out_addr, size_t num_pages, size_t KProcessAddress addr = this->FindFreeArea(region_start, region_num_pages, num_pages, alignment, 0, this->GetNumGuardPages()); R_UNLESS(addr != 0, ResultOutOfMemory); - ASSERT(Common::IsAligned(addr, alignment)); + ASSERT(Common::IsAligned(GetInteger(addr), alignment)); ASSERT(this->CanContain(addr, num_pages * PageSize, state)); ASSERT(this->CheckMemoryState(addr, num_pages * PageSize, KMemoryState::All, KMemoryState::Free, KMemoryPermission::None, KMemoryPermission::None, @@ -2455,7 +2474,7 @@ Result KPageTable::UnmapPageGroup(KProcessAddress address, const KPageGroup& pg, R_SUCCEED(); } -Result KPageTable::MakeAndOpenPageGroup(KPageGroup* out, VAddr address, size_t num_pages, +Result KPageTable::MakeAndOpenPageGroup(KPageGroup* out, KProcessAddress address, size_t num_pages, KMemoryState state_mask, KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm, KMemoryAttribute attr_mask, KMemoryAttribute attr) { @@ -2480,7 +2499,7 @@ Result KPageTable::MakeAndOpenPageGroup(KPageGroup* out, VAddr address, size_t n R_SUCCEED(); } -Result KPageTable::SetProcessMemoryPermission(VAddr addr, size_t size, +Result KPageTable::SetProcessMemoryPermission(KProcessAddress addr, size_t size, Svc::MemoryPermission svc_perm) { const size_t num_pages = size / PageSize; @@ -2541,23 +2560,23 @@ Result KPageTable::SetProcessMemoryPermission(VAddr addr, size_t size, // Ensure cache coherency, if we're setting pages as executable. if (is_x) { - m_system.InvalidateCpuInstructionCacheRange(addr, size); + m_system.InvalidateCpuInstructionCacheRange(GetInteger(addr), size); } R_SUCCEED(); } -KMemoryInfo KPageTable::QueryInfoImpl(VAddr addr) { +KMemoryInfo KPageTable::QueryInfoImpl(KProcessAddress addr) { KScopedLightLock lk(m_general_lock); return m_memory_block_manager.FindBlock(addr)->GetMemoryInfo(); } -KMemoryInfo KPageTable::QueryInfo(VAddr addr) { +KMemoryInfo KPageTable::QueryInfo(KProcessAddress addr) { if (!Contains(addr, 1)) { return { - .m_address = m_address_space_end, - .m_size = 0 - m_address_space_end, + .m_address = GetInteger(m_address_space_end), + .m_size = 0 - GetInteger(m_address_space_end), .m_state = static_cast(Svc::MemoryState::Inaccessible), .m_device_disable_merge_left_count = 0, .m_device_disable_merge_right_count = 0, @@ -2574,7 +2593,8 @@ KMemoryInfo KPageTable::QueryInfo(VAddr addr) { return QueryInfoImpl(addr); } -Result KPageTable::SetMemoryPermission(VAddr addr, size_t size, Svc::MemoryPermission svc_perm) { +Result KPageTable::SetMemoryPermission(KProcessAddress addr, size_t size, + Svc::MemoryPermission svc_perm) { const size_t num_pages = size / PageSize; // Lock the table. @@ -2611,7 +2631,7 @@ Result KPageTable::SetMemoryPermission(VAddr addr, size_t size, Svc::MemoryPermi R_SUCCEED(); } -Result KPageTable::SetMemoryAttribute(VAddr addr, size_t size, u32 mask, u32 attr) { +Result KPageTable::SetMemoryAttribute(KProcessAddress addr, size_t size, u32 mask, u32 attr) { const size_t num_pages = size / PageSize; ASSERT((static_cast(mask) | KMemoryAttribute::SetMask) == KMemoryAttribute::SetMask); @@ -2666,12 +2686,12 @@ Result KPageTable::SetMaxHeapSize(size_t size) { R_SUCCEED(); } -Result KPageTable::SetHeapSize(VAddr* out, size_t size) { +Result KPageTable::SetHeapSize(u64* out, size_t size) { // Lock the physical memory mutex. KScopedLightLock map_phys_mem_lk(m_map_physical_memory_lock); // Try to perform a reduction in heap, instead of an extension. - VAddr cur_address{}; + KProcessAddress cur_address{}; size_t allocation_size{}; { // Lock the table. @@ -2722,11 +2742,11 @@ Result KPageTable::SetHeapSize(VAddr* out, size_t size) { m_current_heap_end = m_heap_region_start + size; // Set the output. - *out = m_heap_region_start; + *out = GetInteger(m_heap_region_start); R_SUCCEED(); } else if (size == GetHeapSize()) { // The size requested is exactly the current size. - *out = m_heap_region_start; + *out = GetInteger(m_heap_region_start); R_SUCCEED(); } else { // We have to allocate memory. Determine how much to allocate and where while the table @@ -2799,14 +2819,14 @@ Result KPageTable::SetHeapSize(VAddr* out, size_t size) { m_current_heap_end = m_heap_region_start + size; // Set the output. - *out = m_heap_region_start; + *out = GetInteger(m_heap_region_start); R_SUCCEED(); } } -Result KPageTable::LockForMapDeviceAddressSpace(bool* out_is_io, VAddr address, size_t size, - KMemoryPermission perm, bool is_aligned, - bool check_heap) { +Result KPageTable::LockForMapDeviceAddressSpace(bool* out_is_io, KProcessAddress address, + size_t size, KMemoryPermission perm, + bool is_aligned, bool check_heap) { // Lightly validate the range before doing anything else. const size_t num_pages = size / PageSize; R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory); @@ -2842,7 +2862,8 @@ Result KPageTable::LockForMapDeviceAddressSpace(bool* out_is_io, VAddr address, R_SUCCEED(); } -Result KPageTable::LockForUnmapDeviceAddressSpace(VAddr address, size_t size, bool check_heap) { +Result KPageTable::LockForUnmapDeviceAddressSpace(KProcessAddress address, size_t size, + bool check_heap) { // Lightly validate the range before doing anything else. const size_t num_pages = size / PageSize; R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory); @@ -2876,7 +2897,7 @@ Result KPageTable::LockForUnmapDeviceAddressSpace(VAddr address, size_t size, bo R_SUCCEED(); } -Result KPageTable::UnlockForDeviceAddressSpace(VAddr address, size_t size) { +Result KPageTable::UnlockForDeviceAddressSpace(KProcessAddress address, size_t size) { // Lightly validate the range before doing anything else. const size_t num_pages = size / PageSize; R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory); @@ -2904,7 +2925,8 @@ Result KPageTable::UnlockForDeviceAddressSpace(VAddr address, size_t size) { R_SUCCEED(); } -Result KPageTable::LockForIpcUserBuffer(PAddr* out, VAddr address, size_t size) { +Result KPageTable::LockForIpcUserBuffer(KPhysicalAddress* out, KProcessAddress address, + size_t size) { R_RETURN(this->LockMemoryAndOpen( nullptr, out, address, size, KMemoryState::FlagCanIpcUserBuffer, KMemoryState::FlagCanIpcUserBuffer, KMemoryPermission::All, @@ -2913,7 +2935,7 @@ Result KPageTable::LockForIpcUserBuffer(PAddr* out, VAddr address, size_t size) KMemoryAttribute::Locked)); } -Result KPageTable::UnlockForIpcUserBuffer(VAddr address, size_t size) { +Result KPageTable::UnlockForIpcUserBuffer(KProcessAddress address, size_t size) { R_RETURN(this->UnlockMemory(address, size, KMemoryState::FlagCanIpcUserBuffer, KMemoryState::FlagCanIpcUserBuffer, KMemoryPermission::None, KMemoryPermission::None, KMemoryAttribute::All, @@ -2921,7 +2943,7 @@ Result KPageTable::UnlockForIpcUserBuffer(VAddr address, size_t size) { KMemoryAttribute::Locked, nullptr)); } -Result KPageTable::LockForCodeMemory(KPageGroup* out, VAddr addr, size_t size) { +Result KPageTable::LockForCodeMemory(KPageGroup* out, KProcessAddress addr, size_t size) { R_RETURN(this->LockMemoryAndOpen( out, nullptr, addr, size, KMemoryState::FlagCanCodeMemory, KMemoryState::FlagCanCodeMemory, KMemoryPermission::All, KMemoryPermission::UserReadWrite, KMemoryAttribute::All, @@ -2929,17 +2951,17 @@ Result KPageTable::LockForCodeMemory(KPageGroup* out, VAddr addr, size_t size) { KMemoryAttribute::Locked)); } -Result KPageTable::UnlockForCodeMemory(VAddr addr, size_t size, const KPageGroup& pg) { +Result KPageTable::UnlockForCodeMemory(KProcessAddress addr, size_t size, const KPageGroup& pg) { R_RETURN(this->UnlockMemory( addr, size, KMemoryState::FlagCanCodeMemory, KMemoryState::FlagCanCodeMemory, KMemoryPermission::None, KMemoryPermission::None, KMemoryAttribute::All, KMemoryAttribute::Locked, KMemoryPermission::UserReadWrite, KMemoryAttribute::Locked, &pg)); } -bool KPageTable::IsRegionContiguous(VAddr addr, u64 size) const { - auto start_ptr = m_system.DeviceMemory().GetPointer(addr); +bool KPageTable::IsRegionContiguous(KProcessAddress addr, u64 size) const { + auto start_ptr = m_system.DeviceMemory().GetPointer(GetInteger(addr)); for (u64 offset{}; offset < size; offset += PageSize) { - if (start_ptr != m_system.DeviceMemory().GetPointer(addr + offset)) { + if (start_ptr != m_system.DeviceMemory().GetPointer(GetInteger(addr) + offset)) { return false; } start_ptr += PageSize; @@ -2947,18 +2969,19 @@ bool KPageTable::IsRegionContiguous(VAddr addr, u64 size) const { return true; } -void KPageTable::AddRegionToPages(VAddr start, size_t num_pages, KPageGroup& page_linked_list) { - VAddr addr{start}; +void KPageTable::AddRegionToPages(KProcessAddress start, size_t num_pages, + KPageGroup& page_linked_list) { + KProcessAddress addr{start}; while (addr < start + (num_pages * PageSize)) { - const PAddr paddr{GetPhysicalAddr(addr)}; + const KPhysicalAddress paddr{GetPhysicalAddr(addr)}; ASSERT(paddr != 0); page_linked_list.AddBlock(paddr, 1); addr += PageSize; } } -VAddr KPageTable::AllocateVirtualMemory(VAddr start, size_t region_num_pages, u64 needed_num_pages, - size_t align) { +KProcessAddress KPageTable::AllocateVirtualMemory(KProcessAddress start, size_t region_num_pages, + u64 needed_num_pages, size_t align) { if (m_enable_aslr) { UNIMPLEMENTED(); } @@ -2966,11 +2989,11 @@ VAddr KPageTable::AllocateVirtualMemory(VAddr start, size_t region_num_pages, u6 IsKernel() ? 1 : 4); } -Result KPageTable::Operate(VAddr addr, size_t num_pages, const KPageGroup& page_group, +Result KPageTable::Operate(KProcessAddress addr, size_t num_pages, const KPageGroup& page_group, OperationType operation) { ASSERT(this->IsLockedByCurrentThread()); - ASSERT(Common::IsAligned(addr, PageSize)); + ASSERT(Common::IsAligned(GetInteger(addr), PageSize)); ASSERT(num_pages > 0); ASSERT(num_pages == page_group.GetNumPages()); @@ -3001,12 +3024,12 @@ Result KPageTable::Operate(VAddr addr, size_t num_pages, const KPageGroup& page_ R_SUCCEED(); } -Result KPageTable::Operate(VAddr addr, size_t num_pages, KMemoryPermission perm, - OperationType operation, PAddr map_addr) { +Result KPageTable::Operate(KProcessAddress addr, size_t num_pages, KMemoryPermission perm, + OperationType operation, KPhysicalAddress map_addr) { ASSERT(this->IsLockedByCurrentThread()); ASSERT(num_pages > 0); - ASSERT(Common::IsAligned(addr, PageSize)); + ASSERT(Common::IsAligned(GetInteger(addr), PageSize)); ASSERT(ContainsPages(addr, num_pages)); switch (operation) { @@ -3022,7 +3045,7 @@ Result KPageTable::Operate(VAddr addr, size_t num_pages, KMemoryPermission perm, case OperationType::MapFirst: case OperationType::Map: { ASSERT(map_addr); - ASSERT(Common::IsAligned(map_addr, PageSize)); + ASSERT(Common::IsAligned(GetInteger(map_addr), PageSize)); m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, num_pages * PageSize, map_addr); // Open references to pages, if we should. @@ -3060,7 +3083,7 @@ void KPageTable::FinalizeUpdate(PageLinkedList* page_list) { } } -VAddr KPageTable::GetRegionAddress(KMemoryState state) const { +KProcessAddress KPageTable::GetRegionAddress(KMemoryState state) const { switch (state) { case KMemoryState::Free: case KMemoryState::Kernel: @@ -3132,11 +3155,11 @@ size_t KPageTable::GetRegionSize(KMemoryState state) const { } } -bool KPageTable::CanContain(VAddr addr, size_t size, KMemoryState state) const { - const VAddr end = addr + size; - const VAddr last = end - 1; +bool KPageTable::CanContain(KProcessAddress addr, size_t size, KMemoryState state) const { + const KProcessAddress end = addr + size; + const KProcessAddress last = end - 1; - const VAddr region_start = this->GetRegionAddress(state); + const KProcessAddress region_start = this->GetRegionAddress(state); const size_t region_size = this->GetRegionSize(state); const bool is_in_region = @@ -3191,21 +3214,21 @@ Result KPageTable::CheckMemoryState(const KMemoryInfo& info, KMemoryState state_ R_SUCCEED(); } -Result KPageTable::CheckMemoryStateContiguous(size_t* out_blocks_needed, VAddr addr, size_t size, - KMemoryState state_mask, KMemoryState state, - KMemoryPermission perm_mask, KMemoryPermission perm, - KMemoryAttribute attr_mask, +Result KPageTable::CheckMemoryStateContiguous(size_t* out_blocks_needed, KProcessAddress addr, + size_t size, KMemoryState state_mask, + KMemoryState state, KMemoryPermission perm_mask, + KMemoryPermission perm, KMemoryAttribute attr_mask, KMemoryAttribute attr) const { ASSERT(this->IsLockedByCurrentThread()); // Get information about the first block. - const VAddr last_addr = addr + size - 1; + const KProcessAddress last_addr = addr + size - 1; KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr); KMemoryInfo info = it->GetMemoryInfo(); // If the start address isn't aligned, we need a block. const size_t blocks_for_start_align = - (Common::AlignDown(addr, PageSize) != info.GetAddress()) ? 1 : 0; + (Common::AlignDown(GetInteger(addr), PageSize) != info.GetAddress()) ? 1 : 0; while (true) { // Validate against the provided masks. @@ -3224,7 +3247,7 @@ Result KPageTable::CheckMemoryStateContiguous(size_t* out_blocks_needed, VAddr a // If the end address isn't aligned, we need a block. const size_t blocks_for_end_align = - (Common::AlignUp(addr + size, PageSize) != info.GetEndAddress()) ? 1 : 0; + (Common::AlignUp(GetInteger(addr) + size, PageSize) != info.GetEndAddress()) ? 1 : 0; if (out_blocks_needed != nullptr) { *out_blocks_needed = blocks_for_start_align + blocks_for_end_align; @@ -3235,20 +3258,20 @@ Result KPageTable::CheckMemoryStateContiguous(size_t* out_blocks_needed, VAddr a Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, KMemoryAttribute* out_attr, size_t* out_blocks_needed, - VAddr addr, size_t size, KMemoryState state_mask, + KProcessAddress addr, size_t size, KMemoryState state_mask, KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm, KMemoryAttribute attr_mask, KMemoryAttribute attr, KMemoryAttribute ignore_attr) const { ASSERT(this->IsLockedByCurrentThread()); // Get information about the first block. - const VAddr last_addr = addr + size - 1; + const KProcessAddress last_addr = addr + size - 1; KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr); KMemoryInfo info = it->GetMemoryInfo(); // If the start address isn't aligned, we need a block. const size_t blocks_for_start_align = - (Common::AlignDown(addr, PageSize) != info.GetAddress()) ? 1 : 0; + (Common::AlignDown(GetInteger(addr), PageSize) != info.GetAddress()) ? 1 : 0; // Validate all blocks in the range have correct state. const KMemoryState first_state = info.m_state; @@ -3277,7 +3300,7 @@ Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* // If the end address isn't aligned, we need a block. const size_t blocks_for_end_align = - (Common::AlignUp(addr + size, PageSize) != info.GetEndAddress()) ? 1 : 0; + (Common::AlignUp(GetInteger(addr) + size, PageSize) != info.GetEndAddress()) ? 1 : 0; // Write output state. if (out_state != nullptr) { @@ -3295,11 +3318,12 @@ Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* R_SUCCEED(); } -Result KPageTable::LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr addr, size_t size, - KMemoryState state_mask, KMemoryState state, - KMemoryPermission perm_mask, KMemoryPermission perm, - KMemoryAttribute attr_mask, KMemoryAttribute attr, - KMemoryPermission new_perm, KMemoryAttribute lock_attr) { +Result KPageTable::LockMemoryAndOpen(KPageGroup* out_pg, KPhysicalAddress* out_KPhysicalAddress, + KProcessAddress addr, size_t size, KMemoryState state_mask, + KMemoryState state, KMemoryPermission perm_mask, + KMemoryPermission perm, KMemoryAttribute attr_mask, + KMemoryAttribute attr, KMemoryPermission new_perm, + KMemoryAttribute lock_attr) { // Validate basic preconditions. ASSERT((lock_attr & attr) == KMemoryAttribute::None); ASSERT((lock_attr & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)) == @@ -3329,8 +3353,8 @@ Result KPageTable::LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr attr_mask, attr)); // Get the physical address, if we're supposed to. - if (out_paddr != nullptr) { - ASSERT(this->GetPhysicalAddressLocked(out_paddr, addr)); + if (out_KPhysicalAddress != nullptr) { + ASSERT(this->GetPhysicalAddressLocked(out_KPhysicalAddress, addr)); } // Make the page group, if we're supposed to. @@ -3361,7 +3385,7 @@ Result KPageTable::LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr R_SUCCEED(); } -Result KPageTable::UnlockMemory(VAddr addr, size_t size, KMemoryState state_mask, +Result KPageTable::UnlockMemory(KProcessAddress addr, size_t size, KMemoryState state_mask, KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm, KMemoryAttribute attr_mask, KMemoryAttribute attr, KMemoryPermission new_perm, diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h index 5c5356338..1917b2a98 100644 --- a/src/core/hle/kernel/k_page_table.h +++ b/src/core/hle/kernel/k_page_table.h @@ -6,7 +6,6 @@ #include #include "common/common_funcs.h" -#include "common/common_types.h" #include "common/page_table.h" #include "core/file_sys/program_metadata.h" #include "core/hle/kernel/k_dynamic_resource_manager.h" @@ -15,6 +14,7 @@ #include "core/hle/kernel/k_memory_block_manager.h" #include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_memory_manager.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/result.h" #include "core/memory.h" @@ -65,45 +65,47 @@ public: Result InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, - VAddr code_addr, size_t code_size, KSystemResource* system_resource, - KResourceLimit* resource_limit); + KProcessAddress code_addr, size_t code_size, + KSystemResource* system_resource, KResourceLimit* resource_limit); void Finalize(); - Result MapProcessCode(VAddr addr, size_t pages_count, KMemoryState state, + Result MapProcessCode(KProcessAddress addr, size_t pages_count, KMemoryState state, KMemoryPermission perm); - Result MapCodeMemory(VAddr dst_address, VAddr src_address, size_t size); - Result UnmapCodeMemory(VAddr dst_address, VAddr src_address, size_t size, + Result MapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size); + Result UnmapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size, ICacheInvalidationStrategy icache_invalidation_strategy); - Result UnmapProcessMemory(VAddr dst_addr, size_t size, KPageTable& src_page_table, - VAddr src_addr); - Result MapPhysicalMemory(VAddr addr, size_t size); - Result UnmapPhysicalMemory(VAddr addr, size_t size); - Result MapMemory(VAddr dst_addr, VAddr src_addr, size_t size); - Result UnmapMemory(VAddr dst_addr, VAddr src_addr, size_t size); - Result SetProcessMemoryPermission(VAddr addr, size_t size, Svc::MemoryPermission svc_perm); - KMemoryInfo QueryInfo(VAddr addr); - Result SetMemoryPermission(VAddr addr, size_t size, Svc::MemoryPermission perm); - Result SetMemoryAttribute(VAddr addr, size_t size, u32 mask, u32 attr); + Result UnmapProcessMemory(KProcessAddress dst_addr, size_t size, KPageTable& src_page_table, + KProcessAddress src_addr); + Result MapPhysicalMemory(KProcessAddress addr, size_t size); + Result UnmapPhysicalMemory(KProcessAddress addr, size_t size); + Result MapMemory(KProcessAddress dst_addr, KProcessAddress src_addr, size_t size); + Result UnmapMemory(KProcessAddress dst_addr, KProcessAddress src_addr, size_t size); + Result SetProcessMemoryPermission(KProcessAddress addr, size_t size, + Svc::MemoryPermission svc_perm); + KMemoryInfo QueryInfo(KProcessAddress addr); + Result SetMemoryPermission(KProcessAddress addr, size_t size, Svc::MemoryPermission perm); + Result SetMemoryAttribute(KProcessAddress addr, size_t size, u32 mask, u32 attr); Result SetMaxHeapSize(size_t size); - Result SetHeapSize(VAddr* out, size_t size); - Result LockForMapDeviceAddressSpace(bool* out_is_io, VAddr address, size_t size, + Result SetHeapSize(u64* out, size_t size); + Result LockForMapDeviceAddressSpace(bool* out_is_io, KProcessAddress address, size_t size, KMemoryPermission perm, bool is_aligned, bool check_heap); - Result LockForUnmapDeviceAddressSpace(VAddr address, size_t size, bool check_heap); + Result LockForUnmapDeviceAddressSpace(KProcessAddress address, size_t size, bool check_heap); - Result UnlockForDeviceAddressSpace(VAddr addr, size_t size); + Result UnlockForDeviceAddressSpace(KProcessAddress addr, size_t size); - Result LockForIpcUserBuffer(PAddr* out, VAddr address, size_t size); - Result UnlockForIpcUserBuffer(VAddr address, size_t size); + Result LockForIpcUserBuffer(KPhysicalAddress* out, KProcessAddress address, size_t size); + Result UnlockForIpcUserBuffer(KProcessAddress address, size_t size); - Result SetupForIpc(VAddr* out_dst_addr, size_t size, VAddr src_addr, KPageTable& src_page_table, - KMemoryPermission test_perm, KMemoryState dst_state, bool send); - Result CleanupForIpcServer(VAddr address, size_t size, KMemoryState dst_state); - Result CleanupForIpcClient(VAddr address, size_t size, KMemoryState dst_state); + Result SetupForIpc(KProcessAddress* out_dst_addr, size_t size, KProcessAddress src_addr, + KPageTable& src_page_table, KMemoryPermission test_perm, + KMemoryState dst_state, bool send); + Result CleanupForIpcServer(KProcessAddress address, size_t size, KMemoryState dst_state); + Result CleanupForIpcClient(KProcessAddress address, size_t size, KMemoryState dst_state); - Result LockForCodeMemory(KPageGroup* out, VAddr addr, size_t size); - Result UnlockForCodeMemory(VAddr addr, size_t size, const KPageGroup& pg); - Result MakeAndOpenPageGroup(KPageGroup* out, VAddr address, size_t num_pages, + Result LockForCodeMemory(KPageGroup* out, KProcessAddress addr, size_t size); + Result UnlockForCodeMemory(KProcessAddress addr, size_t size, const KPageGroup& pg); + Result MakeAndOpenPageGroup(KPageGroup* out, KProcessAddress address, size_t num_pages, KMemoryState state_mask, KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm, KMemoryAttribute attr_mask, KMemoryAttribute attr); @@ -120,7 +122,7 @@ public: return m_block_info_manager; } - bool CanContain(VAddr addr, size_t size, KMemoryState state) const; + bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const; Result MapPages(KProcessAddress* out_addr, size_t num_pages, size_t alignment, KPhysicalAddress phys_addr, KProcessAddress region_start, @@ -173,8 +175,8 @@ protected: m_root = n; } - void Push(Core::Memory::Memory& memory, VAddr addr) { - this->Push(memory.GetPointer(addr)); + void Push(Core::Memory::Memory& memory, KVirtualAddress addr) { + this->Push(memory.GetPointer(GetInteger(addr))); } Node* Peek() const { @@ -212,27 +214,28 @@ private: Result MapPages(KProcessAddress* out_addr, size_t num_pages, size_t alignment, KPhysicalAddress phys_addr, bool is_pa_valid, KProcessAddress region_start, size_t region_num_pages, KMemoryState state, KMemoryPermission perm); - bool IsRegionContiguous(VAddr addr, u64 size) const; - void AddRegionToPages(VAddr start, size_t num_pages, KPageGroup& page_linked_list); - KMemoryInfo QueryInfoImpl(VAddr addr); - VAddr AllocateVirtualMemory(VAddr start, size_t region_num_pages, u64 needed_num_pages, - size_t align); - Result Operate(VAddr addr, size_t num_pages, const KPageGroup& page_group, + bool IsRegionContiguous(KProcessAddress addr, u64 size) const; + void AddRegionToPages(KProcessAddress start, size_t num_pages, KPageGroup& page_linked_list); + KMemoryInfo QueryInfoImpl(KProcessAddress addr); + KProcessAddress AllocateVirtualMemory(KProcessAddress start, size_t region_num_pages, + u64 needed_num_pages, size_t align); + Result Operate(KProcessAddress addr, size_t num_pages, const KPageGroup& page_group, OperationType operation); - Result Operate(VAddr addr, size_t num_pages, KMemoryPermission perm, OperationType operation, - PAddr map_addr = 0); + Result Operate(KProcessAddress addr, size_t num_pages, KMemoryPermission perm, + OperationType operation, KPhysicalAddress map_addr = 0); void FinalizeUpdate(PageLinkedList* page_list); - VAddr GetRegionAddress(KMemoryState state) const; + KProcessAddress GetRegionAddress(KMemoryState state) const; size_t GetRegionSize(KMemoryState state) const; - VAddr FindFreeArea(VAddr region_start, size_t region_num_pages, size_t num_pages, - size_t alignment, size_t offset, size_t guard_pages); + KProcessAddress FindFreeArea(KProcessAddress region_start, size_t region_num_pages, + size_t num_pages, size_t alignment, size_t offset, + size_t guard_pages); - Result CheckMemoryStateContiguous(size_t* out_blocks_needed, VAddr addr, size_t size, + Result CheckMemoryStateContiguous(size_t* out_blocks_needed, KProcessAddress addr, size_t size, KMemoryState state_mask, KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm, KMemoryAttribute attr_mask, KMemoryAttribute attr) const; - Result CheckMemoryStateContiguous(VAddr addr, size_t size, KMemoryState state_mask, + Result CheckMemoryStateContiguous(KProcessAddress addr, size_t size, KMemoryState state_mask, KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm, KMemoryAttribute attr_mask, KMemoryAttribute attr) const { @@ -244,12 +247,12 @@ private: KMemoryPermission perm_mask, KMemoryPermission perm, KMemoryAttribute attr_mask, KMemoryAttribute attr) const; Result CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, - KMemoryAttribute* out_attr, size_t* out_blocks_needed, VAddr addr, - size_t size, KMemoryState state_mask, KMemoryState state, - KMemoryPermission perm_mask, KMemoryPermission perm, + KMemoryAttribute* out_attr, size_t* out_blocks_needed, + KProcessAddress addr, size_t size, KMemoryState state_mask, + KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm, KMemoryAttribute attr_mask, KMemoryAttribute attr, KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const; - Result CheckMemoryState(size_t* out_blocks_needed, VAddr addr, size_t size, + Result CheckMemoryState(size_t* out_blocks_needed, KProcessAddress addr, size_t size, KMemoryState state_mask, KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm, KMemoryAttribute attr_mask, KMemoryAttribute attr, @@ -258,39 +261,40 @@ private: state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr)); } - Result CheckMemoryState(VAddr addr, size_t size, KMemoryState state_mask, KMemoryState state, - KMemoryPermission perm_mask, KMemoryPermission perm, + Result CheckMemoryState(KProcessAddress addr, size_t size, KMemoryState state_mask, + KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm, KMemoryAttribute attr_mask, KMemoryAttribute attr, KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const { R_RETURN(this->CheckMemoryState(nullptr, addr, size, state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr)); } - Result LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr addr, size_t size, - KMemoryState state_mask, KMemoryState state, - KMemoryPermission perm_mask, KMemoryPermission perm, - KMemoryAttribute attr_mask, KMemoryAttribute attr, - KMemoryPermission new_perm, KMemoryAttribute lock_attr); - Result UnlockMemory(VAddr addr, size_t size, KMemoryState state_mask, KMemoryState state, - KMemoryPermission perm_mask, KMemoryPermission perm, + Result LockMemoryAndOpen(KPageGroup* out_pg, KPhysicalAddress* out_KPhysicalAddress, + KProcessAddress addr, size_t size, KMemoryState state_mask, + KMemoryState state, KMemoryPermission perm_mask, + KMemoryPermission perm, KMemoryAttribute attr_mask, + KMemoryAttribute attr, KMemoryPermission new_perm, + KMemoryAttribute lock_attr); + Result UnlockMemory(KProcessAddress addr, size_t size, KMemoryState state_mask, + KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm, KMemoryAttribute attr_mask, KMemoryAttribute attr, KMemoryPermission new_perm, KMemoryAttribute lock_attr, const KPageGroup* pg); - Result MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages); - bool IsValidPageGroup(const KPageGroup& pg, VAddr addr, size_t num_pages); + Result MakePageGroup(KPageGroup& pg, KProcessAddress addr, size_t num_pages); + bool IsValidPageGroup(const KPageGroup& pg, KProcessAddress addr, size_t num_pages); bool IsLockedByCurrentThread() const { return m_general_lock.IsLockedByCurrentThread(); } - bool IsHeapPhysicalAddress(const KMemoryLayout& layout, PAddr phys_addr) { + bool IsHeapPhysicalAddress(const KMemoryLayout& layout, KPhysicalAddress phys_addr) { ASSERT(this->IsLockedByCurrentThread()); return layout.IsHeapPhysicalAddress(m_cached_physical_heap_region, phys_addr); } - bool GetPhysicalAddressLocked(PAddr* out, VAddr virt_addr) const { + bool GetPhysicalAddressLocked(KPhysicalAddress* out, KProcessAddress virt_addr) const { ASSERT(this->IsLockedByCurrentThread()); *out = GetPhysicalAddr(virt_addr); @@ -298,12 +302,13 @@ private: return *out != 0; } - Result SetupForIpcClient(PageLinkedList* page_list, size_t* out_blocks_needed, VAddr address, - size_t size, KMemoryPermission test_perm, KMemoryState dst_state); - Result SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_addr, + Result SetupForIpcClient(PageLinkedList* page_list, size_t* out_blocks_needed, + KProcessAddress address, size_t size, KMemoryPermission test_perm, + KMemoryState dst_state); + Result SetupForIpcServer(KProcessAddress* out_addr, size_t size, KProcessAddress src_addr, KMemoryPermission test_perm, KMemoryState dst_state, KPageTable& src_page_table, bool send); - void CleanupForIpcClientOnServerSetupFailure(PageLinkedList* page_list, VAddr address, + void CleanupForIpcClientOnServerSetupFailure(PageLinkedList* page_list, KProcessAddress address, size_t size, KMemoryPermission prot_perm); Result AllocateAndMapPagesImpl(PageLinkedList* page_list, KProcessAddress address, @@ -315,61 +320,61 @@ private: mutable KLightLock m_map_physical_memory_lock; public: - constexpr VAddr GetAddressSpaceStart() const { + constexpr KProcessAddress GetAddressSpaceStart() const { return m_address_space_start; } - constexpr VAddr GetAddressSpaceEnd() const { + constexpr KProcessAddress GetAddressSpaceEnd() const { return m_address_space_end; } constexpr size_t GetAddressSpaceSize() const { return m_address_space_end - m_address_space_start; } - constexpr VAddr GetHeapRegionStart() const { + constexpr KProcessAddress GetHeapRegionStart() const { return m_heap_region_start; } - constexpr VAddr GetHeapRegionEnd() const { + constexpr KProcessAddress GetHeapRegionEnd() const { return m_heap_region_end; } constexpr size_t GetHeapRegionSize() const { return m_heap_region_end - m_heap_region_start; } - constexpr VAddr GetAliasRegionStart() const { + constexpr KProcessAddress GetAliasRegionStart() const { return m_alias_region_start; } - constexpr VAddr GetAliasRegionEnd() const { + constexpr KProcessAddress GetAliasRegionEnd() const { return m_alias_region_end; } constexpr size_t GetAliasRegionSize() const { return m_alias_region_end - m_alias_region_start; } - constexpr VAddr GetStackRegionStart() const { + constexpr KProcessAddress GetStackRegionStart() const { return m_stack_region_start; } - constexpr VAddr GetStackRegionEnd() const { + constexpr KProcessAddress GetStackRegionEnd() const { return m_stack_region_end; } constexpr size_t GetStackRegionSize() const { return m_stack_region_end - m_stack_region_start; } - constexpr VAddr GetKernelMapRegionStart() const { + constexpr KProcessAddress GetKernelMapRegionStart() const { return m_kernel_map_region_start; } - constexpr VAddr GetKernelMapRegionEnd() const { + constexpr KProcessAddress GetKernelMapRegionEnd() const { return m_kernel_map_region_end; } - constexpr VAddr GetCodeRegionStart() const { + constexpr KProcessAddress GetCodeRegionStart() const { return m_code_region_start; } - constexpr VAddr GetCodeRegionEnd() const { + constexpr KProcessAddress GetCodeRegionEnd() const { return m_code_region_end; } - constexpr VAddr GetAliasCodeRegionStart() const { + constexpr KProcessAddress GetAliasCodeRegionStart() const { return m_alias_code_region_start; } - constexpr VAddr GetAliasCodeRegionEnd() const { + constexpr KProcessAddress GetAliasCodeRegionEnd() const { return m_alias_code_region_end; } - constexpr VAddr GetAliasCodeRegionSize() const { + constexpr size_t GetAliasCodeRegionSize() const { return m_alias_code_region_end - m_alias_code_region_start; } size_t GetNormalMemorySize() { @@ -382,25 +387,25 @@ public: constexpr size_t GetHeapSize() const { return m_current_heap_end - m_heap_region_start; } - constexpr bool IsInsideAddressSpace(VAddr address, size_t size) const { + constexpr bool IsInsideAddressSpace(KProcessAddress address, size_t size) const { return m_address_space_start <= address && address + size - 1 <= m_address_space_end - 1; } - constexpr bool IsOutsideAliasRegion(VAddr address, size_t size) const { + constexpr bool IsOutsideAliasRegion(KProcessAddress address, size_t size) const { return m_alias_region_start > address || address + size - 1 > m_alias_region_end - 1; } - constexpr bool IsOutsideStackRegion(VAddr address, size_t size) const { + constexpr bool IsOutsideStackRegion(KProcessAddress address, size_t size) const { return m_stack_region_start > address || address + size - 1 > m_stack_region_end - 1; } - constexpr bool IsInvalidRegion(VAddr address, size_t size) const { + constexpr bool IsInvalidRegion(KProcessAddress address, size_t size) const { return address + size - 1 > GetAliasCodeRegionStart() + GetAliasCodeRegionSize() - 1; } - constexpr bool IsInsideHeapRegion(VAddr address, size_t size) const { + constexpr bool IsInsideHeapRegion(KProcessAddress address, size_t size) const { return address + size > m_heap_region_start && m_heap_region_end > address; } - constexpr bool IsInsideAliasRegion(VAddr address, size_t size) const { + constexpr bool IsInsideAliasRegion(KProcessAddress address, size_t size) const { return address + size > m_alias_region_start && m_alias_region_end > address; } - constexpr bool IsOutsideASLRRegion(VAddr address, size_t size) const { + constexpr bool IsOutsideASLRRegion(KProcessAddress address, size_t size) const { if (IsInvalidRegion(address, size)) { return true; } @@ -412,47 +417,53 @@ public: } return {}; } - constexpr bool IsInsideASLRRegion(VAddr address, size_t size) const { + constexpr bool IsInsideASLRRegion(KProcessAddress address, size_t size) const { return !IsOutsideASLRRegion(address, size); } constexpr size_t GetNumGuardPages() const { return IsKernel() ? 1 : 4; } - PAddr GetPhysicalAddr(VAddr addr) const { + KPhysicalAddress GetPhysicalAddr(KProcessAddress addr) const { const auto backing_addr = m_page_table_impl->backing_addr[addr >> PageBits]; ASSERT(backing_addr); - return backing_addr + addr; + return backing_addr + GetInteger(addr); } - constexpr bool Contains(VAddr addr) const { + constexpr bool Contains(KProcessAddress addr) const { return m_address_space_start <= addr && addr <= m_address_space_end - 1; } - constexpr bool Contains(VAddr addr, size_t size) const { + constexpr bool Contains(KProcessAddress addr, size_t size) const { return m_address_space_start <= addr && addr < addr + size && addr + size - 1 <= m_address_space_end - 1; } public: - static VAddr GetLinearMappedVirtualAddress(const KMemoryLayout& layout, PAddr addr) { + static KVirtualAddress GetLinearMappedVirtualAddress(const KMemoryLayout& layout, + KPhysicalAddress addr) { return layout.GetLinearVirtualAddress(addr); } - static PAddr GetLinearMappedPhysicalAddress(const KMemoryLayout& layout, VAddr addr) { + static KPhysicalAddress GetLinearMappedPhysicalAddress(const KMemoryLayout& layout, + KVirtualAddress addr) { return layout.GetLinearPhysicalAddress(addr); } - static VAddr GetHeapVirtualAddress(const KMemoryLayout& layout, PAddr addr) { + static KVirtualAddress GetHeapVirtualAddress(const KMemoryLayout& layout, + KPhysicalAddress addr) { return GetLinearMappedVirtualAddress(layout, addr); } - static PAddr GetHeapPhysicalAddress(const KMemoryLayout& layout, VAddr addr) { + static KPhysicalAddress GetHeapPhysicalAddress(const KMemoryLayout& layout, + KVirtualAddress addr) { return GetLinearMappedPhysicalAddress(layout, addr); } - static VAddr GetPageTableVirtualAddress(const KMemoryLayout& layout, PAddr addr) { + static KVirtualAddress GetPageTableVirtualAddress(const KMemoryLayout& layout, + KPhysicalAddress addr) { return GetLinearMappedVirtualAddress(layout, addr); } - static PAddr GetPageTablePhysicalAddress(const KMemoryLayout& layout, VAddr addr) { + static KPhysicalAddress GetPageTablePhysicalAddress(const KMemoryLayout& layout, + KVirtualAddress addr) { return GetLinearMappedPhysicalAddress(layout, addr); } @@ -464,7 +475,7 @@ private: return m_enable_aslr; } - constexpr bool ContainsPages(VAddr addr, size_t num_pages) const { + constexpr bool ContainsPages(KProcessAddress addr, size_t num_pages) const { return (m_address_space_start <= addr) && (num_pages <= (m_address_space_end - m_address_space_start) / PageSize) && (addr + num_pages * PageSize - 1 <= m_address_space_end - 1); @@ -489,21 +500,21 @@ private: }; private: - VAddr m_address_space_start{}; - VAddr m_address_space_end{}; - VAddr m_heap_region_start{}; - VAddr m_heap_region_end{}; - VAddr m_current_heap_end{}; - VAddr m_alias_region_start{}; - VAddr m_alias_region_end{}; - VAddr m_stack_region_start{}; - VAddr m_stack_region_end{}; - VAddr m_kernel_map_region_start{}; - VAddr m_kernel_map_region_end{}; - VAddr m_code_region_start{}; - VAddr m_code_region_end{}; - VAddr m_alias_code_region_start{}; - VAddr m_alias_code_region_end{}; + KProcessAddress m_address_space_start{}; + KProcessAddress m_address_space_end{}; + KProcessAddress m_heap_region_start{}; + KProcessAddress m_heap_region_end{}; + KProcessAddress m_current_heap_end{}; + KProcessAddress m_alias_region_start{}; + KProcessAddress m_alias_region_end{}; + KProcessAddress m_stack_region_start{}; + KProcessAddress m_stack_region_end{}; + KProcessAddress m_kernel_map_region_start{}; + KProcessAddress m_kernel_map_region_end{}; + KProcessAddress m_code_region_start{}; + KProcessAddress m_code_region_end{}; + KProcessAddress m_alias_code_region_start{}; + KProcessAddress m_alias_code_region_end{}; size_t m_max_heap_size{}; size_t m_mapped_physical_memory_size{}; diff --git a/src/core/hle/kernel/k_page_table_manager.h b/src/core/hle/kernel/k_page_table_manager.h index 91a45cde3..4b0e034d0 100644 --- a/src/core/hle/kernel/k_page_table_manager.h +++ b/src/core/hle/kernel/k_page_table_manager.h @@ -5,9 +5,9 @@ #include -#include "common/common_types.h" #include "core/hle/kernel/k_dynamic_resource_manager.h" #include "core/hle/kernel/k_page_table_slab_heap.h" +#include "core/hle/kernel/k_typed_address.h" namespace Kernel { @@ -26,23 +26,23 @@ public: BaseHeap::Initialize(page_allocator, pt_heap); } - VAddr Allocate() { - return VAddr(BaseHeap::Allocate()); + KVirtualAddress Allocate() { + return KVirtualAddress(BaseHeap::Allocate()); } - RefCount GetRefCount(VAddr addr) const { + RefCount GetRefCount(KVirtualAddress addr) const { return m_pt_heap->GetRefCount(addr); } - void Open(VAddr addr, int count) { + void Open(KVirtualAddress addr, int count) { return m_pt_heap->Open(addr, count); } - bool Close(VAddr addr, int count) { + bool Close(KVirtualAddress addr, int count) { return m_pt_heap->Close(addr, count); } - bool IsInPageTableHeap(VAddr addr) const { + bool IsInPageTableHeap(KVirtualAddress addr) const { return m_pt_heap->IsInRange(addr); } diff --git a/src/core/hle/kernel/k_page_table_slab_heap.h b/src/core/hle/kernel/k_page_table_slab_heap.h index 9a8d77316..7da0ea669 100644 --- a/src/core/hle/kernel/k_page_table_slab_heap.h +++ b/src/core/hle/kernel/k_page_table_slab_heap.h @@ -6,8 +6,8 @@ #include #include -#include "common/common_types.h" #include "core/hle/kernel/k_dynamic_slab_heap.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/kernel/slab_helpers.h" namespace Kernel { @@ -45,12 +45,12 @@ public: this->Initialize(rc); } - RefCount GetRefCount(VAddr addr) { + RefCount GetRefCount(KVirtualAddress addr) { ASSERT(this->IsInRange(addr)); return *this->GetRefCountPointer(addr); } - void Open(VAddr addr, int count) { + void Open(KVirtualAddress addr, int count) { ASSERT(this->IsInRange(addr)); *this->GetRefCountPointer(addr) += static_cast(count); @@ -58,7 +58,7 @@ public: ASSERT(this->GetRefCount(addr) > 0); } - bool Close(VAddr addr, int count) { + bool Close(KVirtualAddress addr, int count) { ASSERT(this->IsInRange(addr)); ASSERT(this->GetRefCount(addr) >= count); @@ -66,7 +66,7 @@ public: return this->GetRefCount(addr) == 0; } - bool IsInPageTableHeap(VAddr addr) const { + bool IsInPageTableHeap(KVirtualAddress addr) const { return this->IsInRange(addr); } @@ -81,7 +81,7 @@ private: } } - RefCount* GetRefCountPointer(VAddr addr) { + RefCount* GetRefCountPointer(KVirtualAddress addr) { return m_ref_counts.data() + ((addr - this->GetAddress()) / PageSize); } diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 9d18f4049..53f8139f3 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -36,8 +36,9 @@ namespace { * @param owner_process The parent process for the main thread * @param priority The priority to give the main thread */ -void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority, VAddr stack_top) { - const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); +void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority, + KProcessAddress stack_top) { + const KProcessAddress entry_point = owner_process.PageTable().GetCodeRegionStart(); ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1)); KThread* thread = KThread::Create(system.Kernel()); @@ -219,7 +220,7 @@ void KProcess::UnpinThread(KThread* thread) { KScheduler::SetSchedulerUpdateNeeded(m_kernel); } -Result KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr address, +Result KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] KProcessAddress address, [[maybe_unused]] size_t size) { // Lock ourselves, to prevent concurrent access. KScopedLightLock lk(m_state_lock); @@ -248,7 +249,7 @@ Result KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr ad R_SUCCEED(); } -void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr address, +void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] KProcessAddress address, [[maybe_unused]] size_t size) { // Lock ourselves, to prevent concurrent access. KScopedLightLock lk(m_state_lock); @@ -399,8 +400,8 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std: case FileSys::ProgramAddressSpaceType::Is32BitNoMap: m_memory_usage_capacity = - m_page_table.GetHeapRegionEnd() - m_page_table.GetHeapRegionStart() + - m_page_table.GetAliasRegionEnd() - m_page_table.GetAliasRegionStart(); + (m_page_table.GetHeapRegionEnd() - m_page_table.GetHeapRegionStart()) + + (m_page_table.GetAliasRegionEnd() - m_page_table.GetAliasRegionStart()); break; default: @@ -492,9 +493,9 @@ void KProcess::Finalize() { KSynchronizationObject::Finalize(); } -Result KProcess::CreateThreadLocalRegion(VAddr* out) { +Result KProcess::CreateThreadLocalRegion(KProcessAddress* out) { KThreadLocalPage* tlp = nullptr; - VAddr tlr = 0; + KProcessAddress tlr = 0; // See if we can get a region from a partially used TLP. { @@ -543,7 +544,7 @@ Result KProcess::CreateThreadLocalRegion(VAddr* out) { R_SUCCEED(); } -Result KProcess::DeleteThreadLocalRegion(VAddr addr) { +Result KProcess::DeleteThreadLocalRegion(KProcessAddress addr) { KThreadLocalPage* page_to_free = nullptr; // Release the region. @@ -551,10 +552,10 @@ Result KProcess::DeleteThreadLocalRegion(VAddr addr) { KScopedSchedulerLock sl{m_kernel}; // Try to find the page in the partially used list. - auto it = m_partially_used_tlp_tree.find_key(Common::AlignDown(addr, PageSize)); + auto it = m_partially_used_tlp_tree.find_key(Common::AlignDown(GetInteger(addr), PageSize)); if (it == m_partially_used_tlp_tree.end()) { // If we don't find it, it has to be in the fully used list. - it = m_fully_used_tlp_tree.find_key(Common::AlignDown(addr, PageSize)); + it = m_fully_used_tlp_tree.find_key(Common::AlignDown(GetInteger(addr), PageSize)); R_UNLESS(it != m_fully_used_tlp_tree.end(), ResultInvalidAddress); // Release the region. @@ -591,7 +592,7 @@ Result KProcess::DeleteThreadLocalRegion(VAddr addr) { R_SUCCEED(); } -bool KProcess::InsertWatchpoint(Core::System& system, VAddr addr, u64 size, +bool KProcess::InsertWatchpoint(Core::System& system, KProcessAddress addr, u64 size, DebugWatchpointType type) { const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) { return wp.type == DebugWatchpointType::None; @@ -605,7 +606,8 @@ bool KProcess::InsertWatchpoint(Core::System& system, VAddr addr, u64 size, watch->end_address = addr + size; watch->type = type; - for (VAddr page = Common::AlignDown(addr, PageSize); page < addr + size; page += PageSize) { + for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size; + page += PageSize) { m_debug_page_refcounts[page]++; system.Memory().MarkRegionDebug(page, PageSize, true); } @@ -613,7 +615,7 @@ bool KProcess::InsertWatchpoint(Core::System& system, VAddr addr, u64 size, return true; } -bool KProcess::RemoveWatchpoint(Core::System& system, VAddr addr, u64 size, +bool KProcess::RemoveWatchpoint(Core::System& system, KProcessAddress addr, u64 size, DebugWatchpointType type) { const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) { return wp.start_address == addr && wp.end_address == addr + size && wp.type == type; @@ -627,7 +629,8 @@ bool KProcess::RemoveWatchpoint(Core::System& system, VAddr addr, u64 size, watch->end_address = 0; watch->type = DebugWatchpointType::None; - for (VAddr page = Common::AlignDown(addr, PageSize); page < addr + size; page += PageSize) { + for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size; + page += PageSize) { m_debug_page_refcounts[page]--; if (!m_debug_page_refcounts[page]) { system.Memory().MarkRegionDebug(page, PageSize, false); @@ -637,7 +640,7 @@ bool KProcess::RemoveWatchpoint(Core::System& system, VAddr addr, u64 size, return true; } -void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) { +void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) { const auto ReprotectSegment = [&](const CodeSet::Segment& segment, Svc::MemoryPermission permission) { m_page_table.SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission); diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index 7b7a971b8..04b6bbb86 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h @@ -8,7 +8,6 @@ #include #include #include -#include "common/common_types.h" #include "core/hle/kernel/k_address_arbiter.h" #include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/k_condition_variable.h" @@ -16,6 +15,7 @@ #include "core/hle/kernel/k_page_table.h" #include "core/hle/kernel/k_synchronization_object.h" #include "core/hle/kernel/k_thread_local_page.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/kernel/k_worker_task.h" #include "core/hle/kernel/process_capability.h" #include "core/hle/kernel/slab_helpers.h" @@ -59,8 +59,8 @@ enum class DebugWatchpointType : u8 { DECLARE_ENUM_FLAG_OPERATORS(DebugWatchpointType); struct DebugWatchpoint { - VAddr start_address; - VAddr end_address; + KProcessAddress start_address; + KProcessAddress end_address; DebugWatchpointType type; }; @@ -135,11 +135,11 @@ public: return m_handle_table; } - Result SignalToAddress(VAddr address) { + Result SignalToAddress(KProcessAddress address) { return m_condition_var.SignalToAddress(address); } - Result WaitForAddress(Handle handle, VAddr address, u32 tag) { + Result WaitForAddress(Handle handle, KProcessAddress address, u32 tag) { return m_condition_var.WaitForAddress(handle, address, tag); } @@ -147,20 +147,21 @@ public: return m_condition_var.Signal(cv_key, count); } - Result WaitConditionVariable(VAddr address, u64 cv_key, u32 tag, s64 ns) { + Result WaitConditionVariable(KProcessAddress address, u64 cv_key, u32 tag, s64 ns) { R_RETURN(m_condition_var.Wait(address, cv_key, tag, ns)); } - Result SignalAddressArbiter(VAddr address, Svc::SignalType signal_type, s32 value, s32 count) { + Result SignalAddressArbiter(uint64_t address, Svc::SignalType signal_type, s32 value, + s32 count) { R_RETURN(m_address_arbiter.SignalToAddress(address, signal_type, value, count)); } - Result WaitAddressArbiter(VAddr address, Svc::ArbitrationType arb_type, s32 value, + Result WaitAddressArbiter(uint64_t address, Svc::ArbitrationType arb_type, s32 value, s64 timeout) { R_RETURN(m_address_arbiter.WaitForAddress(address, arb_type, value, timeout)); } - VAddr GetProcessLocalRegionAddress() const { + KProcessAddress GetProcessLocalRegionAddress() const { return m_plr_address; } @@ -352,7 +353,7 @@ public: */ void PrepareForTermination(); - void LoadModule(CodeSet code_set, VAddr base_addr); + void LoadModule(CodeSet code_set, KProcessAddress base_addr); bool IsInitialized() const override { return m_is_initialized; @@ -380,26 +381,28 @@ public: return m_state_lock; } - Result AddSharedMemory(KSharedMemory* shmem, VAddr address, size_t size); - void RemoveSharedMemory(KSharedMemory* shmem, VAddr address, size_t size); + Result AddSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size); + void RemoveSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size); /////////////////////////////////////////////////////////////////////////////////////////////// // Thread-local storage management // Marks the next available region as used and returns the address of the slot. - [[nodiscard]] Result CreateThreadLocalRegion(VAddr* out); + [[nodiscard]] Result CreateThreadLocalRegion(KProcessAddress* out); // Frees a used TLS slot identified by the given address - Result DeleteThreadLocalRegion(VAddr addr); + Result DeleteThreadLocalRegion(KProcessAddress addr); /////////////////////////////////////////////////////////////////////////////////////////////// // Debug watchpoint management // Attempts to insert a watchpoint into a free slot. Returns false if none are available. - bool InsertWatchpoint(Core::System& system, VAddr addr, u64 size, DebugWatchpointType type); + bool InsertWatchpoint(Core::System& system, KProcessAddress addr, u64 size, + DebugWatchpointType type); // Attempts to remove the watchpoint specified by the given parameters. - bool RemoveWatchpoint(Core::System& system, VAddr addr, u64 size, DebugWatchpointType type); + bool RemoveWatchpoint(Core::System& system, KProcessAddress addr, u64 size, + DebugWatchpointType type); const std::array& GetWatchpoints() const { return m_watchpoints; @@ -457,7 +460,7 @@ private: /// Resource limit descriptor for this process KResourceLimit* m_resource_limit{}; - VAddr m_system_resource_address{}; + KVirtualAddress m_system_resource_address{}; /// The ideal CPU core for this process, threads are scheduled on this core by default. u8 m_ideal_core = 0; @@ -485,7 +488,7 @@ private: KConditionVariable m_condition_var; /// Address indicating the location of the process' dedicated TLS region. - VAddr m_plr_address = 0; + KProcessAddress m_plr_address = 0; /// Random values for svcGetInfo RandomEntropy std::array m_random_entropy{}; @@ -497,7 +500,7 @@ private: std::list m_shared_memory_list; /// Address of the top of the main thread's stack - VAddr m_main_thread_stack_top{}; + KProcessAddress m_main_thread_stack_top{}; /// Size of the main thread's stack std::size_t m_main_thread_stack_size{}; @@ -527,7 +530,7 @@ private: std::array m_running_thread_idle_counts{}; std::array m_pinned_threads{}; std::array m_watchpoints{}; - std::map m_debug_page_refcounts; + std::map m_debug_page_refcounts; KThread* m_exception_thread{}; diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index ecadf2916..faa12b4f0 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -511,7 +511,7 @@ void KScheduler::Reload(KThread* thread) { auto& cpu_core = m_kernel.System().ArmInterface(m_core_id); cpu_core.LoadContext(thread->GetContext32()); cpu_core.LoadContext(thread->GetContext64()); - cpu_core.SetTlsAddress(thread->GetTlsAddress()); + cpu_core.SetTlsAddress(GetInteger(thread->GetTlsAddress())); cpu_core.SetTPIDR_EL0(thread->GetTpidrEl0()); cpu_core.LoadWatchpointArray(thread->GetOwnerProcess()->GetWatchpoints()); cpu_core.ClearExclusiveState(); diff --git a/src/core/hle/kernel/k_session_request.cpp b/src/core/hle/kernel/k_session_request.cpp index a329e5690..9a69b4ffc 100644 --- a/src/core/hle/kernel/k_session_request.cpp +++ b/src/core/hle/kernel/k_session_request.cpp @@ -6,8 +6,8 @@ namespace Kernel { -Result KSessionRequest::SessionMappings::PushMap(VAddr client, VAddr server, size_t size, - KMemoryState state, size_t index) { +Result KSessionRequest::SessionMappings::PushMap(KProcessAddress client, KProcessAddress server, + size_t size, KMemoryState state, size_t index) { // At most 15 buffers of each type (4-bit descriptor counts). ASSERT(index < ((1ul << 4) - 1) * 3); @@ -33,20 +33,21 @@ Result KSessionRequest::SessionMappings::PushMap(VAddr client, VAddr server, siz R_SUCCEED(); } -Result KSessionRequest::SessionMappings::PushSend(VAddr client, VAddr server, size_t size, - KMemoryState state) { +Result KSessionRequest::SessionMappings::PushSend(KProcessAddress client, KProcessAddress server, + size_t size, KMemoryState state) { ASSERT(m_num_recv == 0); ASSERT(m_num_exch == 0); R_RETURN(this->PushMap(client, server, size, state, m_num_send++)); } -Result KSessionRequest::SessionMappings::PushReceive(VAddr client, VAddr server, size_t size, - KMemoryState state) { +Result KSessionRequest::SessionMappings::PushReceive(KProcessAddress client, KProcessAddress server, + size_t size, KMemoryState state) { ASSERT(m_num_exch == 0); R_RETURN(this->PushMap(client, server, size, state, m_num_send + m_num_recv++)); } -Result KSessionRequest::SessionMappings::PushExchange(VAddr client, VAddr server, size_t size, +Result KSessionRequest::SessionMappings::PushExchange(KProcessAddress client, + KProcessAddress server, size_t size, KMemoryState state) { R_RETURN(this->PushMap(client, server, size, state, m_num_send + m_num_recv + m_num_exch++)); } diff --git a/src/core/hle/kernel/k_session_request.h b/src/core/hle/kernel/k_session_request.h index 5685048ba..b5f04907b 100644 --- a/src/core/hle/kernel/k_session_request.h +++ b/src/core/hle/kernel/k_session_request.h @@ -26,17 +26,17 @@ public: class Mapping { public: - constexpr void Set(VAddr c, VAddr s, size_t sz, KMemoryState st) { + constexpr void Set(KProcessAddress c, KProcessAddress s, size_t sz, KMemoryState st) { m_client_address = c; m_server_address = s; m_size = sz; m_state = st; } - constexpr VAddr GetClientAddress() const { + constexpr KProcessAddress GetClientAddress() const { return m_client_address; } - constexpr VAddr GetServerAddress() const { + constexpr KProcessAddress GetServerAddress() const { return m_server_address; } constexpr size_t GetSize() const { @@ -47,8 +47,8 @@ public: } private: - VAddr m_client_address{}; - VAddr m_server_address{}; + KProcessAddress m_client_address{}; + KProcessAddress m_server_address{}; size_t m_size{}; KMemoryState m_state{}; }; @@ -69,14 +69,17 @@ public: return m_num_exch; } - Result PushSend(VAddr client, VAddr server, size_t size, KMemoryState state); - Result PushReceive(VAddr client, VAddr server, size_t size, KMemoryState state); - Result PushExchange(VAddr client, VAddr server, size_t size, KMemoryState state); + Result PushSend(KProcessAddress client, KProcessAddress server, size_t size, + KMemoryState state); + Result PushReceive(KProcessAddress client, KProcessAddress server, size_t size, + KMemoryState state); + Result PushExchange(KProcessAddress client, KProcessAddress server, size_t size, + KMemoryState state); - VAddr GetSendClientAddress(size_t i) const { + KProcessAddress GetSendClientAddress(size_t i) const { return GetSendMapping(i).GetClientAddress(); } - VAddr GetSendServerAddress(size_t i) const { + KProcessAddress GetSendServerAddress(size_t i) const { return GetSendMapping(i).GetServerAddress(); } size_t GetSendSize(size_t i) const { @@ -86,10 +89,10 @@ public: return GetSendMapping(i).GetMemoryState(); } - VAddr GetReceiveClientAddress(size_t i) const { + KProcessAddress GetReceiveClientAddress(size_t i) const { return GetReceiveMapping(i).GetClientAddress(); } - VAddr GetReceiveServerAddress(size_t i) const { + KProcessAddress GetReceiveServerAddress(size_t i) const { return GetReceiveMapping(i).GetServerAddress(); } size_t GetReceiveSize(size_t i) const { @@ -99,10 +102,10 @@ public: return GetReceiveMapping(i).GetMemoryState(); } - VAddr GetExchangeClientAddress(size_t i) const { + KProcessAddress GetExchangeClientAddress(size_t i) const { return GetExchangeMapping(i).GetClientAddress(); } - VAddr GetExchangeServerAddress(size_t i) const { + KProcessAddress GetExchangeServerAddress(size_t i) const { return GetExchangeMapping(i).GetServerAddress(); } size_t GetExchangeSize(size_t i) const { @@ -113,7 +116,8 @@ public: } private: - Result PushMap(VAddr client, VAddr server, size_t size, KMemoryState state, size_t index); + Result PushMap(KProcessAddress client, KProcessAddress server, size_t size, + KMemoryState state, size_t index); const Mapping& GetSendMapping(size_t i) const { ASSERT(i < m_num_send); @@ -227,22 +231,25 @@ public: return m_mappings.GetExchangeCount(); } - Result PushSend(VAddr client, VAddr server, size_t size, KMemoryState state) { + Result PushSend(KProcessAddress client, KProcessAddress server, size_t size, + KMemoryState state) { return m_mappings.PushSend(client, server, size, state); } - Result PushReceive(VAddr client, VAddr server, size_t size, KMemoryState state) { + Result PushReceive(KProcessAddress client, KProcessAddress server, size_t size, + KMemoryState state) { return m_mappings.PushReceive(client, server, size, state); } - Result PushExchange(VAddr client, VAddr server, size_t size, KMemoryState state) { + Result PushExchange(KProcessAddress client, KProcessAddress server, size_t size, + KMemoryState state) { return m_mappings.PushExchange(client, server, size, state); } - VAddr GetSendClientAddress(size_t i) const { + KProcessAddress GetSendClientAddress(size_t i) const { return m_mappings.GetSendClientAddress(i); } - VAddr GetSendServerAddress(size_t i) const { + KProcessAddress GetSendServerAddress(size_t i) const { return m_mappings.GetSendServerAddress(i); } size_t GetSendSize(size_t i) const { @@ -252,10 +259,10 @@ public: return m_mappings.GetSendMemoryState(i); } - VAddr GetReceiveClientAddress(size_t i) const { + KProcessAddress GetReceiveClientAddress(size_t i) const { return m_mappings.GetReceiveClientAddress(i); } - VAddr GetReceiveServerAddress(size_t i) const { + KProcessAddress GetReceiveServerAddress(size_t i) const { return m_mappings.GetReceiveServerAddress(i); } size_t GetReceiveSize(size_t i) const { @@ -265,10 +272,10 @@ public: return m_mappings.GetReceiveMemoryState(i); } - VAddr GetExchangeClientAddress(size_t i) const { + KProcessAddress GetExchangeClientAddress(size_t i) const { return m_mappings.GetExchangeClientAddress(i); } - VAddr GetExchangeServerAddress(size_t i) const { + KProcessAddress GetExchangeServerAddress(size_t i) const { return m_mappings.GetExchangeServerAddress(i); } size_t GetExchangeSize(size_t i) const { diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp index 954e5befe..efb5699de 100644 --- a/src/core/hle/kernel/k_shared_memory.cpp +++ b/src/core/hle/kernel/k_shared_memory.cpp @@ -76,7 +76,7 @@ void KSharedMemory::Finalize() { m_resource_limit->Close(); } -Result KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t map_size, +Result KSharedMemory::Map(KProcess& target_process, KProcessAddress address, std::size_t map_size, Svc::MemoryPermission map_perm) { // Validate the size. R_UNLESS(m_size == map_size, ResultInvalidSize); @@ -94,7 +94,8 @@ Result KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t m ConvertToKMemoryPermission(map_perm))); } -Result KSharedMemory::Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size) { +Result KSharedMemory::Unmap(KProcess& target_process, KProcessAddress address, + std::size_t unmap_size) { // Validate the size. R_UNLESS(m_size == unmap_size, ResultInvalidSize); diff --git a/src/core/hle/kernel/k_shared_memory.h b/src/core/hle/kernel/k_shared_memory.h index b4c4125bb..54b23d7ac 100644 --- a/src/core/hle/kernel/k_shared_memory.h +++ b/src/core/hle/kernel/k_shared_memory.h @@ -6,11 +6,11 @@ #include #include -#include "common/common_types.h" #include "core/device_memory.h" #include "core/hle/kernel/k_memory_block.h" #include "core/hle/kernel/k_page_group.h" #include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/kernel/slab_helpers.h" #include "core/hle/result.h" @@ -37,7 +37,7 @@ public: * @param map_size Size of the shared memory block to map * @param permissions Memory block map permissions (specified by SVC field) */ - Result Map(KProcess& target_process, VAddr address, std::size_t map_size, + Result Map(KProcess& target_process, KProcessAddress address, std::size_t map_size, Svc::MemoryPermission permissions); /** @@ -46,7 +46,7 @@ public: * @param address Address in system memory to unmap shared memory block * @param unmap_size Size of the shared memory block to unmap */ - Result Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size); + Result Unmap(KProcess& target_process, KProcessAddress address, std::size_t unmap_size); /** * Gets a pointer to the shared memory block @@ -79,7 +79,7 @@ private: std::optional m_page_group{}; Svc::MemoryPermission m_owner_permission{}; Svc::MemoryPermission m_user_permission{}; - PAddr m_physical_address{}; + KPhysicalAddress m_physical_address{}; std::size_t m_size{}; KResourceLimit* m_resource_limit{}; bool m_is_initialized{}; diff --git a/src/core/hle/kernel/k_system_resource.h b/src/core/hle/kernel/k_system_resource.h index d36aaa9bd..6ea482185 100644 --- a/src/core/hle/kernel/k_system_resource.h +++ b/src/core/hle/kernel/k_system_resource.h @@ -130,7 +130,7 @@ private: KBlockInfoSlabHeap m_block_info_heap; KPageTableSlabHeap m_page_table_heap; KResourceLimit* m_resource_limit{}; - VAddr m_resource_address{}; + KVirtualAddress m_resource_address{}; size_t m_resource_size{}; }; diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index c0e3ecb45..9d101c640 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -48,8 +48,8 @@ static void ResetThreadContext32(Kernel::KThread::ThreadContext32& context, u32 context.fpscr = 0; } -static void ResetThreadContext64(Kernel::KThread::ThreadContext64& context, VAddr stack_top, - VAddr entry_point, u64 arg) { +static void ResetThreadContext64(Kernel::KThread::ThreadContext64& context, u64 stack_top, + u64 entry_point, u64 arg) { context = {}; context.cpu_registers[0] = arg; context.cpu_registers[18] = Kernel::KSystemControl::GenerateRandomU64() | 1; @@ -100,8 +100,8 @@ KThread::KThread(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel}, m_activity_pause_lock{kernel} {} KThread::~KThread() = default; -Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, s32 prio, - s32 virt_core, KProcess* owner, ThreadType type) { +Result KThread::Initialize(KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, + s32 prio, s32 virt_core, KProcess* owner, ThreadType type) { // Assert parameters are valid. ASSERT((type == ThreadType::Main) || (type == ThreadType::Dummy) || (Svc::HighestThreadPriority <= prio && prio <= Svc::LowestThreadPriority)); @@ -221,9 +221,9 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack } // Initialize thread context. - ResetThreadContext64(m_thread_context_64, user_stack_top, func, arg); - ResetThreadContext32(m_thread_context_32, static_cast(user_stack_top), - static_cast(func), static_cast(arg)); + ResetThreadContext64(m_thread_context_64, GetInteger(user_stack_top), GetInteger(func), arg); + ResetThreadContext32(m_thread_context_32, static_cast(GetInteger(user_stack_top)), + static_cast(GetInteger(func)), static_cast(arg)); // Setup the stack parameters. StackParameters& sp = this->GetStackParameters(); @@ -249,8 +249,9 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack } Result KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg, - VAddr user_stack_top, s32 prio, s32 core, KProcess* owner, - ThreadType type, std::function&& init_func) { + KProcessAddress user_stack_top, s32 prio, s32 core, + KProcess* owner, ThreadType type, + std::function&& init_func) { // Initialize the thread. R_TRY(thread->Initialize(func, arg, user_stack_top, prio, core, owner, type)); @@ -288,8 +289,8 @@ Result KThread::InitializeHighPriorityThread(Core::System& system, KThread* thre } Result KThread::InitializeUserThread(Core::System& system, KThread* thread, KThreadFunction func, - uintptr_t arg, VAddr user_stack_top, s32 prio, s32 virt_core, - KProcess* owner) { + uintptr_t arg, KProcessAddress user_stack_top, s32 prio, + s32 virt_core, KProcess* owner) { system.Kernel().GlobalSchedulerContext().AddThread(thread); R_RETURN(InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner, ThreadType::User, system.GetCpuManager().GetGuestThreadFunc())); @@ -951,7 +952,7 @@ void KThread::AddHeldLock(LockWithPriorityInheritanceInfo* lock_info) { m_held_lock_info_list.push_front(*lock_info); } -KThread::LockWithPriorityInheritanceInfo* KThread::FindHeldLock(VAddr address_key, +KThread::LockWithPriorityInheritanceInfo* KThread::FindHeldLock(KProcessAddress address_key, bool is_kernel_address_key) { ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); @@ -1087,7 +1088,8 @@ void KThread::RemoveWaiter(KThread* thread) { } } -KThread* KThread::RemoveWaiterByKey(bool* out_has_waiters, VAddr key, bool is_kernel_address_key_) { +KThread* KThread::RemoveWaiterByKey(bool* out_has_waiters, KProcessAddress key, + bool is_kernel_address_key_) { ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); // Get the relevant lock info. diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 53fa64369..0fa9672bf 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -14,7 +14,6 @@ #include -#include "common/common_types.h" #include "common/intrusive_red_black_tree.h" #include "common/spin_lock.h" #include "core/arm/arm_interface.h" @@ -23,6 +22,7 @@ #include "core/hle/kernel/k_spin_lock.h" #include "core/hle/kernel/k_synchronization_object.h" #include "core/hle/kernel/k_timer_task.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/kernel/k_worker_task.h" #include "core/hle/kernel/slab_helpers.h" #include "core/hle/kernel/svc_common.h" @@ -46,7 +46,7 @@ class KProcess; class KScheduler; class KThreadQueue; -using KThreadFunction = VAddr; +using KThreadFunction = KProcessAddress; enum class ThreadType : u32 { Main = 0, @@ -230,9 +230,9 @@ public: /* * Returns the Thread Local Storage address of the current thread - * @returns VAddr of the thread's TLS + * @returns Address of the thread's TLS */ - VAddr GetTlsAddress() const { + KProcessAddress GetTlsAddress() const { return m_tls_address; } @@ -419,8 +419,8 @@ public: KThreadFunction func, uintptr_t arg, s32 virt_core); static Result InitializeUserThread(Core::System& system, KThread* thread, KThreadFunction func, - uintptr_t arg, VAddr user_stack_top, s32 prio, s32 virt_core, - KProcess* owner); + uintptr_t arg, KProcessAddress user_stack_top, s32 prio, + s32 virt_core, KProcess* owner); static Result InitializeServiceThread(Core::System& system, KThread* thread, std::function&& thread_func, s32 prio, @@ -565,15 +565,15 @@ public: Result GetThreadContext3(std::vector& out); - KThread* RemoveUserWaiterByKey(bool* out_has_waiters, VAddr key) { + KThread* RemoveUserWaiterByKey(bool* out_has_waiters, KProcessAddress key) { return this->RemoveWaiterByKey(out_has_waiters, key, false); } - KThread* RemoveKernelWaiterByKey(bool* out_has_waiters, VAddr key) { + KThread* RemoveKernelWaiterByKey(bool* out_has_waiters, KProcessAddress key) { return this->RemoveWaiterByKey(out_has_waiters, key, true); } - VAddr GetAddressKey() const { + KProcessAddress GetAddressKey() const { return m_address_key; } @@ -591,14 +591,14 @@ public: // to cope with arbitrary host pointers making their way // into things. - void SetUserAddressKey(VAddr key, u32 val) { + void SetUserAddressKey(KProcessAddress key, u32 val) { ASSERT(m_waiting_lock_info == nullptr); m_address_key = key; m_address_key_value = val; m_is_kernel_address_key = false; } - void SetKernelAddressKey(VAddr key) { + void SetKernelAddressKey(KProcessAddress key) { ASSERT(m_waiting_lock_info == nullptr); m_address_key = key; m_is_kernel_address_key = true; @@ -637,12 +637,13 @@ public: return m_argument; } - VAddr GetUserStackTop() const { + KProcessAddress GetUserStackTop() const { return m_stack_top; } private: - KThread* RemoveWaiterByKey(bool* out_has_waiters, VAddr key, bool is_kernel_address_key); + KThread* RemoveWaiterByKey(bool* out_has_waiters, KProcessAddress key, + bool is_kernel_address_key); static constexpr size_t PriorityInheritanceCountMax = 10; union SyncObjectBuffer { @@ -695,12 +696,13 @@ private: void IncreaseBasePriority(s32 priority); - Result Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, s32 prio, + Result Initialize(KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio, s32 virt_core, KProcess* owner, ThreadType type); static Result InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg, - VAddr user_stack_top, s32 prio, s32 core, KProcess* owner, - ThreadType type, std::function&& init_func); + KProcessAddress user_stack_top, s32 prio, s32 core, + KProcess* owner, ThreadType type, + std::function&& init_func); // For core KThread implementation ThreadContext32 m_thread_context_32{}; @@ -749,7 +751,8 @@ public: public: explicit LockWithPriorityInheritanceInfo(KernelCore&) {} - static LockWithPriorityInheritanceInfo* Create(KernelCore& kernel, VAddr address_key, + static LockWithPriorityInheritanceInfo* Create(KernelCore& kernel, + KProcessAddress address_key, bool is_kernel_address_key) { // Create a new lock info. auto* new_lock = LockWithPriorityInheritanceInfo::Allocate(kernel); @@ -797,7 +800,7 @@ public: return m_tree; } - VAddr GetAddressKey() const { + KProcessAddress GetAddressKey() const { return m_address_key; } bool GetIsKernelAddressKey() const { @@ -812,7 +815,7 @@ public: private: LockWithPriorityInheritanceThreadTree m_tree{}; - VAddr m_address_key{}; + KProcessAddress m_address_key{}; KThread* m_owner{}; u32 m_waiter_count{}; bool m_is_kernel_address_key{}; @@ -827,7 +830,8 @@ public: } void AddHeldLock(LockWithPriorityInheritanceInfo* lock_info); - LockWithPriorityInheritanceInfo* FindHeldLock(VAddr address_key, bool is_kernel_address_key); + LockWithPriorityInheritanceInfo* FindHeldLock(KProcessAddress address_key, + bool is_kernel_address_key); private: using LockWithPriorityInheritanceInfoList = @@ -839,11 +843,11 @@ private: KAffinityMask m_physical_affinity_mask{}; u64 m_thread_id{}; std::atomic m_cpu_time{}; - VAddr m_address_key{}; + KProcessAddress m_address_key{}; KProcess* m_parent{}; - VAddr m_kernel_stack_top{}; + KVirtualAddress m_kernel_stack_top{}; u32* m_light_ipc_data{}; - VAddr m_tls_address{}; + KProcessAddress m_tls_address{}; KLightLock m_activity_pause_lock; s64 m_schedule_count{}; s64 m_last_scheduled_tick{}; @@ -887,16 +891,16 @@ private: // For debugging std::vector m_wait_objects_for_debugging{}; - VAddr m_mutex_wait_address_for_debugging{}; + KProcessAddress m_mutex_wait_address_for_debugging{}; ThreadWaitReasonForDebugging m_wait_reason_for_debugging{}; uintptr_t m_argument{}; - VAddr m_stack_top{}; + KProcessAddress m_stack_top{}; public: using ConditionVariableThreadTreeType = ConditionVariableThreadTree; - void SetConditionVariable(ConditionVariableThreadTree* tree, VAddr address, u64 cv_key, - u32 value) { + void SetConditionVariable(ConditionVariableThreadTree* tree, KProcessAddress address, + u64 cv_key, u32 value) { ASSERT(m_waiting_lock_info == nullptr); m_condvar_tree = tree; m_condvar_key = cv_key; diff --git a/src/core/hle/kernel/k_thread_local_page.cpp b/src/core/hle/kernel/k_thread_local_page.cpp index c2af6898a..b4a1e3cdb 100644 --- a/src/core/hle/kernel/k_thread_local_page.cpp +++ b/src/core/hle/kernel/k_thread_local_page.cpp @@ -37,7 +37,7 @@ Result KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) { Result KThreadLocalPage::Finalize() { // Get the physical address of the page. - const PAddr phys_addr = m_owner->PageTable().GetPhysicalAddr(m_virt_addr); + const KPhysicalAddress phys_addr = m_owner->PageTable().GetPhysicalAddr(m_virt_addr); ASSERT(phys_addr); // Unmap the page. @@ -49,7 +49,7 @@ Result KThreadLocalPage::Finalize() { return ResultSuccess; } -VAddr KThreadLocalPage::Reserve() { +KProcessAddress KThreadLocalPage::Reserve() { for (size_t i = 0; i < m_is_region_free.size(); i++) { if (m_is_region_free[i]) { m_is_region_free[i] = false; @@ -60,7 +60,7 @@ VAddr KThreadLocalPage::Reserve() { return 0; } -void KThreadLocalPage::Release(VAddr addr) { +void KThreadLocalPage::Release(KProcessAddress addr) { m_is_region_free[this->GetRegionIndex(addr)] = true; } diff --git a/src/core/hle/kernel/k_thread_local_page.h b/src/core/hle/kernel/k_thread_local_page.h index 71254eb55..813f32a7e 100644 --- a/src/core/hle/kernel/k_thread_local_page.h +++ b/src/core/hle/kernel/k_thread_local_page.h @@ -27,19 +27,20 @@ public: static_assert(RegionsPerPage > 0); public: - constexpr explicit KThreadLocalPage(KernelCore&, VAddr addr = {}) : m_virt_addr(addr) { + constexpr explicit KThreadLocalPage(KernelCore&, KProcessAddress addr = {}) + : m_virt_addr(addr) { m_is_region_free.fill(true); } - constexpr VAddr GetAddress() const { + constexpr KProcessAddress GetAddress() const { return m_virt_addr; } Result Initialize(KernelCore& kernel, KProcess* process); Result Finalize(); - VAddr Reserve(); - void Release(VAddr addr); + KProcessAddress Reserve(); + void Release(KProcessAddress addr); bool IsAllUsed() const { return std::ranges::all_of(m_is_region_free.begin(), m_is_region_free.end(), @@ -60,7 +61,7 @@ public: } public: - using RedBlackKeyType = VAddr; + using RedBlackKeyType = KProcessAddress; static constexpr RedBlackKeyType GetRedBlackKey(const RedBlackKeyType& v) { return v; @@ -72,8 +73,8 @@ public: template requires(std::same_as || std::same_as) static constexpr int Compare(const T& lhs, const KThreadLocalPage& rhs) { - const VAddr lval = GetRedBlackKey(lhs); - const VAddr rval = GetRedBlackKey(rhs); + const KProcessAddress lval = GetRedBlackKey(lhs); + const KProcessAddress rval = GetRedBlackKey(rhs); if (lval < rval) { return -1; @@ -85,22 +86,22 @@ public: } private: - constexpr VAddr GetRegionAddress(size_t i) const { + constexpr KProcessAddress GetRegionAddress(size_t i) const { return this->GetAddress() + i * Svc::ThreadLocalRegionSize; } - constexpr bool Contains(VAddr addr) const { + constexpr bool Contains(KProcessAddress addr) const { return this->GetAddress() <= addr && addr < this->GetAddress() + PageSize; } - constexpr size_t GetRegionIndex(VAddr addr) const { - ASSERT(Common::IsAligned(addr, Svc::ThreadLocalRegionSize)); + constexpr size_t GetRegionIndex(KProcessAddress addr) const { + ASSERT(Common::IsAligned(GetInteger(addr), Svc::ThreadLocalRegionSize)); ASSERT(this->Contains(addr)); return (addr - this->GetAddress()) / Svc::ThreadLocalRegionSize; } private: - VAddr m_virt_addr{}; + KProcessAddress m_virt_addr{}; KProcess* m_owner{}; KernelCore* m_kernel{}; std::array m_is_region_free{}; diff --git a/src/core/hle/kernel/k_transfer_memory.cpp b/src/core/hle/kernel/k_transfer_memory.cpp index 471349282..13d34125c 100644 --- a/src/core/hle/kernel/k_transfer_memory.cpp +++ b/src/core/hle/kernel/k_transfer_memory.cpp @@ -13,7 +13,7 @@ KTransferMemory::KTransferMemory(KernelCore& kernel) KTransferMemory::~KTransferMemory() = default; -Result KTransferMemory::Initialize(VAddr address, std::size_t size, +Result KTransferMemory::Initialize(KProcessAddress address, std::size_t size, Svc::MemoryPermission owner_perm) { // Set members. m_owner = GetCurrentProcessPointer(m_kernel); diff --git a/src/core/hle/kernel/k_transfer_memory.h b/src/core/hle/kernel/k_transfer_memory.h index 3d4d795a5..54f97ccb4 100644 --- a/src/core/hle/kernel/k_transfer_memory.h +++ b/src/core/hle/kernel/k_transfer_memory.h @@ -26,7 +26,7 @@ public: explicit KTransferMemory(KernelCore& kernel); ~KTransferMemory() override; - Result Initialize(VAddr address, std::size_t size, Svc::MemoryPermission owner_perm); + Result Initialize(KProcessAddress address, std::size_t size, Svc::MemoryPermission owner_perm); void Finalize() override; @@ -44,7 +44,7 @@ public: return m_owner; } - VAddr GetSourceAddress() const { + KProcessAddress GetSourceAddress() const { return m_address; } @@ -54,7 +54,7 @@ public: private: KProcess* m_owner{}; - VAddr m_address{}; + KProcessAddress m_address{}; Svc::MemoryPermission m_owner_perm{}; size_t m_size{}; bool m_is_initialized{}; diff --git a/src/core/hle/kernel/k_typed_address.h b/src/core/hle/kernel/k_typed_address.h new file mode 100644 index 000000000..d57535ba0 --- /dev/null +++ b/src/core/hle/kernel/k_typed_address.h @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/typed_address.h" + +namespace Kernel { + +using KPhysicalAddress = Common::PhysicalAddress; +using KVirtualAddress = Common::VirtualAddress; +using KProcessAddress = Common::ProcessAddress; + +} // namespace Kernel diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 98ecaf12f..29809b2c5 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -271,9 +271,9 @@ struct KernelCore::Impl { system.CoreTiming().ScheduleLoopingEvent(time_interval, time_interval, preemption_event); } - void InitializeResourceManagers(KernelCore& kernel, VAddr address, size_t size) { + void InitializeResourceManagers(KernelCore& kernel, KVirtualAddress address, size_t size) { // Ensure that the buffer is suitable for our use. - ASSERT(Common::IsAligned(address, PageSize)); + ASSERT(Common::IsAligned(GetInteger(address), PageSize)); ASSERT(Common::IsAligned(size, PageSize)); // Ensure that we have space for our reference counts. @@ -462,29 +462,30 @@ struct KernelCore::Impl { KernelPhysicalAddressSpaceBase + KernelPhysicalAddressSpaceSize - 1); // Save start and end for ease of use. - const VAddr code_start_virt_addr = KernelVirtualAddressCodeBase; - const VAddr code_end_virt_addr = KernelVirtualAddressCodeEnd; + constexpr KVirtualAddress code_start_virt_addr = KernelVirtualAddressCodeBase; + constexpr KVirtualAddress code_end_virt_addr = KernelVirtualAddressCodeEnd; // Setup the containing kernel region. constexpr size_t KernelRegionSize = 1_GiB; constexpr size_t KernelRegionAlign = 1_GiB; - constexpr VAddr kernel_region_start = - Common::AlignDown(code_start_virt_addr, KernelRegionAlign); + constexpr KVirtualAddress kernel_region_start = + Common::AlignDown(GetInteger(code_start_virt_addr), KernelRegionAlign); size_t kernel_region_size = KernelRegionSize; if (!(kernel_region_start + KernelRegionSize - 1 <= KernelVirtualAddressSpaceLast)) { - kernel_region_size = KernelVirtualAddressSpaceEnd - kernel_region_start; + kernel_region_size = KernelVirtualAddressSpaceEnd - GetInteger(kernel_region_start); } ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert( - kernel_region_start, kernel_region_size, KMemoryRegionType_Kernel)); + GetInteger(kernel_region_start), kernel_region_size, KMemoryRegionType_Kernel)); // Setup the code region. constexpr size_t CodeRegionAlign = PageSize; - constexpr VAddr code_region_start = - Common::AlignDown(code_start_virt_addr, CodeRegionAlign); - constexpr VAddr code_region_end = Common::AlignUp(code_end_virt_addr, CodeRegionAlign); + constexpr KVirtualAddress code_region_start = + Common::AlignDown(GetInteger(code_start_virt_addr), CodeRegionAlign); + constexpr KVirtualAddress code_region_end = + Common::AlignUp(GetInteger(code_end_virt_addr), CodeRegionAlign); constexpr size_t code_region_size = code_region_end - code_region_start; ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert( - code_region_start, code_region_size, KMemoryRegionType_KernelCode)); + GetInteger(code_region_start), code_region_size, KMemoryRegionType_KernelCode)); // Setup board-specific device physical regions. Init::SetupDevicePhysicalMemoryRegions(*memory_layout); @@ -520,11 +521,11 @@ struct KernelCore::Impl { ASSERT(misc_region_size > 0); // Setup the misc region. - const VAddr misc_region_start = + const KVirtualAddress misc_region_start = memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion( misc_region_size, MiscRegionAlign, KMemoryRegionType_Kernel); ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert( - misc_region_start, misc_region_size, KMemoryRegionType_KernelMisc)); + GetInteger(misc_region_start), misc_region_size, KMemoryRegionType_KernelMisc)); // Determine if we'll use extra thread resources. const bool use_extra_resources = KSystemControl::Init::ShouldIncreaseThreadResourceLimit(); @@ -532,11 +533,11 @@ struct KernelCore::Impl { // Setup the stack region. constexpr size_t StackRegionSize = 14_MiB; constexpr size_t StackRegionAlign = KernelAslrAlignment; - const VAddr stack_region_start = + const KVirtualAddress stack_region_start = memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion( StackRegionSize, StackRegionAlign, KMemoryRegionType_Kernel); ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert( - stack_region_start, StackRegionSize, KMemoryRegionType_KernelStack)); + GetInteger(stack_region_start), StackRegionSize, KMemoryRegionType_KernelStack)); // Determine the size of the resource region. const size_t resource_region_size = @@ -548,29 +549,29 @@ struct KernelCore::Impl { ASSERT(slab_region_size <= resource_region_size); // Setup the slab region. - const PAddr code_start_phys_addr = KernelPhysicalAddressCodeBase; - const PAddr code_end_phys_addr = code_start_phys_addr + code_region_size; - const PAddr slab_start_phys_addr = code_end_phys_addr; - const PAddr slab_end_phys_addr = slab_start_phys_addr + slab_region_size; + const KPhysicalAddress code_start_phys_addr = KernelPhysicalAddressCodeBase; + const KPhysicalAddress code_end_phys_addr = code_start_phys_addr + code_region_size; + const KPhysicalAddress slab_start_phys_addr = code_end_phys_addr; + const KPhysicalAddress slab_end_phys_addr = slab_start_phys_addr + slab_region_size; constexpr size_t SlabRegionAlign = KernelAslrAlignment; const size_t slab_region_needed_size = - Common::AlignUp(code_end_phys_addr + slab_region_size, SlabRegionAlign) - - Common::AlignDown(code_end_phys_addr, SlabRegionAlign); - const VAddr slab_region_start = + Common::AlignUp(GetInteger(code_end_phys_addr) + slab_region_size, SlabRegionAlign) - + Common::AlignDown(GetInteger(code_end_phys_addr), SlabRegionAlign); + const KVirtualAddress slab_region_start = memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion( slab_region_needed_size, SlabRegionAlign, KMemoryRegionType_Kernel) + - (code_end_phys_addr % SlabRegionAlign); + (GetInteger(code_end_phys_addr) % SlabRegionAlign); ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert( - slab_region_start, slab_region_size, KMemoryRegionType_KernelSlab)); + GetInteger(slab_region_start), slab_region_size, KMemoryRegionType_KernelSlab)); // Setup the temp region. constexpr size_t TempRegionSize = 128_MiB; constexpr size_t TempRegionAlign = KernelAslrAlignment; - const VAddr temp_region_start = + const KVirtualAddress temp_region_start = memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion( TempRegionSize, TempRegionAlign, KMemoryRegionType_Kernel); - ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(temp_region_start, TempRegionSize, - KMemoryRegionType_KernelTemp)); + ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert( + GetInteger(temp_region_start), TempRegionSize, KMemoryRegionType_KernelTemp)); // Automatically map in devices that have auto-map attributes. for (auto& region : memory_layout->GetPhysicalMemoryRegionTree()) { @@ -596,35 +597,37 @@ struct KernelCore::Impl { region.SetTypeAttribute(KMemoryRegionAttr_DidKernelMap); // Create a virtual pair region and insert it into the tree. - const PAddr map_phys_addr = Common::AlignDown(region.GetAddress(), PageSize); + const KPhysicalAddress map_phys_addr = Common::AlignDown(region.GetAddress(), PageSize); const size_t map_size = - Common::AlignUp(region.GetEndAddress(), PageSize) - map_phys_addr; - const VAddr map_virt_addr = + Common::AlignUp(region.GetEndAddress(), PageSize) - GetInteger(map_phys_addr); + const KVirtualAddress map_virt_addr = memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard( map_size, PageSize, KMemoryRegionType_KernelMisc, PageSize); ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert( - map_virt_addr, map_size, KMemoryRegionType_KernelMiscMappedDevice)); - region.SetPairAddress(map_virt_addr + region.GetAddress() - map_phys_addr); + GetInteger(map_virt_addr), map_size, KMemoryRegionType_KernelMiscMappedDevice)); + region.SetPairAddress(GetInteger(map_virt_addr) + region.GetAddress() - + GetInteger(map_phys_addr)); } Init::SetupDramPhysicalMemoryRegions(*memory_layout); // Insert a physical region for the kernel code region. ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert( - code_start_phys_addr, code_region_size, KMemoryRegionType_DramKernelCode)); + GetInteger(code_start_phys_addr), code_region_size, KMemoryRegionType_DramKernelCode)); // Insert a physical region for the kernel slab region. ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert( - slab_start_phys_addr, slab_region_size, KMemoryRegionType_DramKernelSlab)); + GetInteger(slab_start_phys_addr), slab_region_size, KMemoryRegionType_DramKernelSlab)); // Determine size available for kernel page table heaps, requiring > 8 MB. - const PAddr resource_end_phys_addr = slab_start_phys_addr + resource_region_size; + const KPhysicalAddress resource_end_phys_addr = slab_start_phys_addr + resource_region_size; const size_t page_table_heap_size = resource_end_phys_addr - slab_end_phys_addr; ASSERT(page_table_heap_size / 4_MiB > 2); // Insert a physical region for the kernel page table heap region ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert( - slab_end_phys_addr, page_table_heap_size, KMemoryRegionType_DramKernelPtHeap)); + GetInteger(slab_end_phys_addr), page_table_heap_size, + KMemoryRegionType_DramKernelPtHeap)); // All DRAM regions that we haven't tagged by this point will be mapped under the linear // mapping. Tag them. @@ -646,20 +649,21 @@ struct KernelCore::Impl { // Setup the linear mapping region. constexpr size_t LinearRegionAlign = 1_GiB; - const PAddr aligned_linear_phys_start = + const KPhysicalAddress aligned_linear_phys_start = Common::AlignDown(linear_extents.GetAddress(), LinearRegionAlign); const size_t linear_region_size = Common::AlignUp(linear_extents.GetEndAddress(), LinearRegionAlign) - - aligned_linear_phys_start; - const VAddr linear_region_start = + GetInteger(aligned_linear_phys_start); + const KVirtualAddress linear_region_start = memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard( linear_region_size, LinearRegionAlign, KMemoryRegionType_None, LinearRegionAlign); - const u64 linear_region_phys_to_virt_diff = linear_region_start - aligned_linear_phys_start; + const u64 linear_region_phys_to_virt_diff = + GetInteger(linear_region_start) - GetInteger(aligned_linear_phys_start); // Map and create regions for all the linearly-mapped data. { - PAddr cur_phys_addr = 0; + KPhysicalAddress cur_phys_addr = 0; u64 cur_size = 0; for (auto& region : memory_layout->GetPhysicalMemoryRegionTree()) { if (!region.HasTypeAttribute(KMemoryRegionAttr_LinearMapped)) { @@ -678,15 +682,16 @@ struct KernelCore::Impl { cur_size = region.GetSize(); } - const VAddr region_virt_addr = + const KVirtualAddress region_virt_addr = region.GetAddress() + linear_region_phys_to_virt_diff; ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert( - region_virt_addr, region.GetSize(), + GetInteger(region_virt_addr), region.GetSize(), GetTypeForVirtualLinearMapping(region.GetType()))); - region.SetPairAddress(region_virt_addr); + region.SetPairAddress(GetInteger(region_virt_addr)); KMemoryRegion* virt_region = - memory_layout->GetVirtualMemoryRegionTree().FindModifiable(region_virt_addr); + memory_layout->GetVirtualMemoryRegionTree().FindModifiable( + GetInteger(region_virt_addr)); ASSERT(virt_region != nullptr); virt_region->SetPairAddress(region.GetAddress()); } @@ -694,10 +699,11 @@ struct KernelCore::Impl { // Insert regions for the initial page table region. ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert( - resource_end_phys_addr, KernelPageTableHeapSize, KMemoryRegionType_DramKernelInitPt)); + GetInteger(resource_end_phys_addr), KernelPageTableHeapSize, + KMemoryRegionType_DramKernelInitPt)); ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert( - resource_end_phys_addr + linear_region_phys_to_virt_diff, KernelPageTableHeapSize, - KMemoryRegionType_VirtualDramKernelInitPt)); + GetInteger(resource_end_phys_addr) + linear_region_phys_to_virt_diff, + KernelPageTableHeapSize, KMemoryRegionType_VirtualDramKernelInitPt)); // All linear-mapped DRAM regions that we haven't tagged by this point will be allocated to // some pool partition. Tag them. @@ -969,12 +975,12 @@ void KernelCore::InvalidateAllInstructionCaches() { } } -void KernelCore::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) { +void KernelCore::InvalidateCpuInstructionCacheRange(KProcessAddress addr, std::size_t size) { for (auto& physical_core : impl->cores) { if (!physical_core->IsInitialized()) { continue; } - physical_core->ArmInterface().InvalidateCacheRange(addr, size); + physical_core->ArmInterface().InvalidateCacheRange(GetInteger(addr), size); } } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 183a4d227..d5b08eeb5 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -14,6 +14,7 @@ #include "core/hardware_properties.h" #include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/k_slab_heap.h" +#include "core/hle/kernel/k_typed_address.h" #include "core/hle/kernel/svc_common.h" namespace Core { @@ -185,7 +186,7 @@ public: void InvalidateAllInstructionCaches(); - void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); + void InvalidateCpuInstructionCacheRange(KProcessAddress addr, std::size_t size); /// Registers all kernel objects with the global emulation state, this is purely for tracking /// leaks after emulation has been shutdown. diff --git a/src/core/hle/kernel/memory_types.h b/src/core/hle/kernel/memory_types.h index 92b8b37ac..18de675cc 100644 --- a/src/core/hle/kernel/memory_types.h +++ b/src/core/hle/kernel/memory_types.h @@ -6,6 +6,7 @@ #include #include "common/common_types.h" +#include "core/hle/kernel/k_typed_address.h" namespace Kernel { @@ -14,7 +15,4 @@ constexpr std::size_t PageSize{1 << PageBits}; using Page = std::array; -using KPhysicalAddress = PAddr; -using KProcessAddress = VAddr; - } // namespace Kernel diff --git a/src/core/hle/kernel/svc/svc_address_arbiter.cpp b/src/core/hle/kernel/svc/svc_address_arbiter.cpp index 22071731b..04cc5ea64 100644 --- a/src/core/hle/kernel/svc/svc_address_arbiter.cpp +++ b/src/core/hle/kernel/svc/svc_address_arbiter.cpp @@ -37,7 +37,7 @@ constexpr bool IsValidArbitrationType(Svc::ArbitrationType type) { } // namespace // Wait for an address (via Address Arbiter) -Result WaitForAddress(Core::System& system, VAddr address, ArbitrationType arb_type, s32 value, +Result WaitForAddress(Core::System& system, u64 address, ArbitrationType arb_type, s32 value, s64 timeout_ns) { LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, arb_type=0x{:X}, value=0x{:X}, timeout_ns={}", address, arb_type, value, timeout_ns); @@ -68,7 +68,7 @@ Result WaitForAddress(Core::System& system, VAddr address, ArbitrationType arb_t } // Signals to an address (via Address Arbiter) -Result SignalToAddress(Core::System& system, VAddr address, SignalType signal_type, s32 value, +Result SignalToAddress(Core::System& system, u64 address, SignalType signal_type, s32 value, s32 count) { LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, signal_type=0x{:X}, value=0x{:X}, count=0x{:X}", address, signal_type, value, count); @@ -82,12 +82,12 @@ Result SignalToAddress(Core::System& system, VAddr address, SignalType signal_ty .SignalAddressArbiter(address, signal_type, value, count)); } -Result WaitForAddress64(Core::System& system, VAddr address, ArbitrationType arb_type, s32 value, +Result WaitForAddress64(Core::System& system, u64 address, ArbitrationType arb_type, s32 value, s64 timeout_ns) { R_RETURN(WaitForAddress(system, address, arb_type, value, timeout_ns)); } -Result SignalToAddress64(Core::System& system, VAddr address, SignalType signal_type, s32 value, +Result SignalToAddress64(Core::System& system, u64 address, SignalType signal_type, s32 value, s32 count) { R_RETURN(SignalToAddress(system, address, signal_type, value, count)); } diff --git a/src/core/hle/kernel/svc/svc_code_memory.cpp b/src/core/hle/kernel/svc/svc_code_memory.cpp index 43feab986..687baff82 100644 --- a/src/core/hle/kernel/svc/svc_code_memory.cpp +++ b/src/core/hle/kernel/svc/svc_code_memory.cpp @@ -29,7 +29,7 @@ constexpr bool IsValidUnmapFromOwnerCodeMemoryPermission(MemoryPermission perm) } // namespace -Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, uint64_t size) { +Result CreateCodeMemory(Core::System& system, Handle* out, u64 address, uint64_t size) { LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, size=0x{:X}", address, size); // Get kernel instance. @@ -64,7 +64,7 @@ Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, uint64 } Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, - CodeMemoryOperation operation, VAddr address, uint64_t size, + CodeMemoryOperation operation, u64 address, uint64_t size, MemoryPermission perm) { LOG_TRACE(Kernel_SVC, diff --git a/src/core/hle/kernel/svc/svc_condition_variable.cpp b/src/core/hle/kernel/svc/svc_condition_variable.cpp index 648ed23d0..ca120d67e 100644 --- a/src/core/hle/kernel/svc/svc_condition_variable.cpp +++ b/src/core/hle/kernel/svc/svc_condition_variable.cpp @@ -11,7 +11,7 @@ namespace Kernel::Svc { /// Wait process wide key atomic -Result WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_key, u32 tag, +Result WaitProcessWideKeyAtomic(Core::System& system, u64 address, u64 cv_key, u32 tag, s64 timeout_ns) { LOG_TRACE(Kernel_SVC, "called address={:X}, cv_key={:X}, tag=0x{:08X}, timeout_ns={}", address, cv_key, tag, timeout_ns); @@ -43,7 +43,7 @@ Result WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_ke } /// Signal process wide key -void SignalProcessWideKey(Core::System& system, VAddr cv_key, s32 count) { +void SignalProcessWideKey(Core::System& system, u64 cv_key, s32 count) { LOG_TRACE(Kernel_SVC, "called, cv_key=0x{:X}, count=0x{:08X}", cv_key, count); // Signal the condition variable. diff --git a/src/core/hle/kernel/svc/svc_debug_string.cpp b/src/core/hle/kernel/svc/svc_debug_string.cpp index d4bf062d1..8771d2b01 100644 --- a/src/core/hle/kernel/svc/svc_debug_string.cpp +++ b/src/core/hle/kernel/svc/svc_debug_string.cpp @@ -8,7 +8,7 @@ namespace Kernel::Svc { /// Used to output a message on a debug hardware unit - does nothing on a retail unit -Result OutputDebugString(Core::System& system, VAddr address, u64 len) { +Result OutputDebugString(Core::System& system, u64 address, u64 len) { R_SUCCEED_IF(len == 0); std::string str(len, '\0'); diff --git a/src/core/hle/kernel/svc/svc_exception.cpp b/src/core/hle/kernel/svc/svc_exception.cpp index c2782908d..4ab5f471f 100644 --- a/src/core/hle/kernel/svc/svc_exception.cpp +++ b/src/core/hle/kernel/svc/svc_exception.cpp @@ -20,7 +20,7 @@ void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) { bool has_dumped_buffer{}; std::vector debug_buffer; - const auto handle_debug_buffer = [&](VAddr addr, u64 sz) { + const auto handle_debug_buffer = [&](u64 addr, u64 sz) { if (sz == 0 || addr == 0 || has_dumped_buffer) { return; } diff --git a/src/core/hle/kernel/svc/svc_info.cpp b/src/core/hle/kernel/svc/svc_info.cpp index 04b6d6964..2b2c878b5 100644 --- a/src/core/hle/kernel/svc/svc_info.cpp +++ b/src/core/hle/kernel/svc/svc_info.cpp @@ -54,7 +54,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle R_SUCCEED(); case InfoType::AliasRegionAddress: - *result = process->PageTable().GetAliasRegionStart(); + *result = GetInteger(process->PageTable().GetAliasRegionStart()); R_SUCCEED(); case InfoType::AliasRegionSize: @@ -62,7 +62,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle R_SUCCEED(); case InfoType::HeapRegionAddress: - *result = process->PageTable().GetHeapRegionStart(); + *result = GetInteger(process->PageTable().GetHeapRegionStart()); R_SUCCEED(); case InfoType::HeapRegionSize: @@ -70,7 +70,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle R_SUCCEED(); case InfoType::AslrRegionAddress: - *result = process->PageTable().GetAliasCodeRegionStart(); + *result = GetInteger(process->PageTable().GetAliasCodeRegionStart()); R_SUCCEED(); case InfoType::AslrRegionSize: @@ -78,7 +78,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle R_SUCCEED(); case InfoType::StackRegionAddress: - *result = process->PageTable().GetStackRegionStart(); + *result = GetInteger(process->PageTable().GetStackRegionStart()); R_SUCCEED(); case InfoType::StackRegionSize: @@ -107,7 +107,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle R_SUCCEED(); case InfoType::UserExceptionContextAddress: - *result = process->GetProcessLocalRegionAddress(); + *result = GetInteger(process->GetProcessLocalRegionAddress()); R_SUCCEED(); case InfoType::TotalNonSystemMemorySize: diff --git a/src/core/hle/kernel/svc/svc_lock.cpp b/src/core/hle/kernel/svc/svc_lock.cpp index 3681279d6..1d7bc4246 100644 --- a/src/core/hle/kernel/svc/svc_lock.cpp +++ b/src/core/hle/kernel/svc/svc_lock.cpp @@ -9,7 +9,7 @@ namespace Kernel::Svc { /// Attempts to locks a mutex -Result ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address, u32 tag) { +Result ArbitrateLock(Core::System& system, Handle thread_handle, u64 address, u32 tag) { LOG_TRACE(Kernel_SVC, "called thread_handle=0x{:08X}, address=0x{:X}, tag=0x{:08X}", thread_handle, address, tag); @@ -21,7 +21,7 @@ Result ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address, } /// Unlock a mutex -Result ArbitrateUnlock(Core::System& system, VAddr address) { +Result ArbitrateUnlock(Core::System& system, u64 address) { LOG_TRACE(Kernel_SVC, "called address=0x{:X}", address); // Validate the input address. diff --git a/src/core/hle/kernel/svc/svc_memory.cpp b/src/core/hle/kernel/svc/svc_memory.cpp index 4db25a3b7..5dcb7f045 100644 --- a/src/core/hle/kernel/svc/svc_memory.cpp +++ b/src/core/hle/kernel/svc/svc_memory.cpp @@ -22,15 +22,14 @@ constexpr bool IsValidSetMemoryPermission(MemoryPermission perm) { // Checks if address + size is greater than the given address // This can return false if the size causes an overflow of a 64-bit type // or if the given size is zero. -constexpr bool IsValidAddressRange(VAddr address, u64 size) { +constexpr bool IsValidAddressRange(u64 address, u64 size) { return address + size > address; } // Helper function that performs the common sanity checks for svcMapMemory // and svcUnmapMemory. This is doable, as both functions perform their sanitizing // in the same order. -Result MapUnmapMemorySanityChecks(const KPageTable& manager, VAddr dst_addr, VAddr src_addr, - u64 size) { +Result MapUnmapMemorySanityChecks(const KPageTable& manager, u64 dst_addr, u64 src_addr, u64 size) { if (!Common::Is4KBAligned(dst_addr)) { LOG_ERROR(Kernel_SVC, "Destination address is not aligned to 4KB, 0x{:016X}", dst_addr); R_THROW(ResultInvalidAddress); @@ -99,7 +98,7 @@ Result MapUnmapMemorySanityChecks(const KPageTable& manager, VAddr dst_addr, VAd } // namespace -Result SetMemoryPermission(Core::System& system, VAddr address, u64 size, MemoryPermission perm) { +Result SetMemoryPermission(Core::System& system, u64 address, u64 size, MemoryPermission perm) { LOG_DEBUG(Kernel_SVC, "called, address=0x{:016X}, size=0x{:X}, perm=0x{:08X", address, size, perm); @@ -120,7 +119,7 @@ Result SetMemoryPermission(Core::System& system, VAddr address, u64 size, Memory R_RETURN(page_table.SetMemoryPermission(address, size, perm)); } -Result SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, u32 attr) { +Result SetMemoryAttribute(Core::System& system, u64 address, u64 size, u32 mask, u32 attr) { LOG_DEBUG(Kernel_SVC, "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address, size, mask, attr); @@ -145,7 +144,7 @@ Result SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mas } /// Maps a memory range into a different range. -Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { +Result MapMemory(Core::System& system, u64 dst_addr, u64 src_addr, u64 size) { LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, src_addr, size); @@ -160,7 +159,7 @@ Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) } /// Unmaps a region that was previously mapped with svcMapMemory -Result UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { +Result UnmapMemory(Core::System& system, u64 dst_addr, u64 src_addr, u64 size) { LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, src_addr, size); diff --git a/src/core/hle/kernel/svc/svc_physical_memory.cpp b/src/core/hle/kernel/svc/svc_physical_memory.cpp index 63196e1ed..c2fbfb59a 100644 --- a/src/core/hle/kernel/svc/svc_physical_memory.cpp +++ b/src/core/hle/kernel/svc/svc_physical_memory.cpp @@ -8,7 +8,7 @@ namespace Kernel::Svc { /// Set the process heap to a given Size. It can both extend and shrink the heap. -Result SetHeapSize(Core::System& system, VAddr* out_address, u64 size) { +Result SetHeapSize(Core::System& system, u64* out_address, u64 size) { LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", size); // Validate size. @@ -20,7 +20,7 @@ Result SetHeapSize(Core::System& system, VAddr* out_address, u64 size) { } /// Maps memory at a desired address -Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { +Result MapPhysicalMemory(Core::System& system, u64 addr, u64 size) { LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); if (!Common::Is4KBAligned(addr)) { @@ -69,7 +69,7 @@ Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { } /// Unmaps memory previously mapped via MapPhysicalMemory -Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { +Result UnmapPhysicalMemory(Core::System& system, u64 addr, u64 size) { LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); if (!Common::Is4KBAligned(addr)) { diff --git a/src/core/hle/kernel/svc/svc_port.cpp b/src/core/hle/kernel/svc/svc_port.cpp index 0b5556bc4..c6eb70422 100644 --- a/src/core/hle/kernel/svc/svc_port.cpp +++ b/src/core/hle/kernel/svc/svc_port.cpp @@ -12,7 +12,7 @@ namespace Kernel::Svc { -Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr user_name) { +Result ConnectToNamedPort(Core::System& system, Handle* out, u64 user_name) { // Copy the provided name from user memory to kernel memory. auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax); diff --git a/src/core/hle/kernel/svc/svc_process.cpp b/src/core/hle/kernel/svc/svc_process.cpp index b538c37e7..3c3579947 100644 --- a/src/core/hle/kernel/svc/svc_process.cpp +++ b/src/core/hle/kernel/svc/svc_process.cpp @@ -50,7 +50,7 @@ Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle) { R_SUCCEED(); } -Result GetProcessList(Core::System& system, s32* out_num_processes, VAddr out_process_ids, +Result GetProcessList(Core::System& system, s32* out_num_processes, u64 out_process_ids, int32_t out_process_ids_size) { LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}", out_process_ids, out_process_ids_size); diff --git a/src/core/hle/kernel/svc/svc_process_memory.cpp b/src/core/hle/kernel/svc/svc_process_memory.cpp index f9210ca1e..aee0f2f36 100644 --- a/src/core/hle/kernel/svc/svc_process_memory.cpp +++ b/src/core/hle/kernel/svc/svc_process_memory.cpp @@ -8,7 +8,7 @@ namespace Kernel::Svc { namespace { -constexpr bool IsValidAddressRange(VAddr address, u64 size) { +constexpr bool IsValidAddressRange(u64 address, u64 size) { return address + size > address; } @@ -26,7 +26,7 @@ constexpr bool IsValidProcessMemoryPermission(Svc::MemoryPermission perm) { } // namespace -Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, VAddr address, +Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, u64 address, u64 size, Svc::MemoryPermission perm) { LOG_TRACE(Kernel_SVC, "called, process_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", @@ -56,8 +56,8 @@ Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, V R_RETURN(page_table.SetProcessMemoryPermission(address, size, perm)); } -Result MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, - VAddr src_address, u64 size) { +Result MapProcessMemory(Core::System& system, u64 dst_address, Handle process_handle, + u64 src_address, u64 size) { LOG_TRACE(Kernel_SVC, "called, dst_address=0x{:X}, process_handle=0x{:X}, src_address=0x{:X}, size=0x{:X}", dst_address, process_handle, src_address, size); @@ -97,8 +97,8 @@ Result MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_ KMemoryPermission::UserReadWrite)); } -Result UnmapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, - VAddr src_address, u64 size) { +Result UnmapProcessMemory(Core::System& system, u64 dst_address, Handle process_handle, + u64 src_address, u64 size) { LOG_TRACE(Kernel_SVC, "called, dst_address=0x{:X}, process_handle=0x{:X}, src_address=0x{:X}, size=0x{:X}", dst_address, process_handle, src_address, size); diff --git a/src/core/hle/kernel/svc/svc_query_memory.cpp b/src/core/hle/kernel/svc/svc_query_memory.cpp index 457ebf950..5db5611f0 100644 --- a/src/core/hle/kernel/svc/svc_query_memory.cpp +++ b/src/core/hle/kernel/svc/svc_query_memory.cpp @@ -8,7 +8,7 @@ namespace Kernel::Svc { Result QueryMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, - VAddr query_address) { + u64 query_address) { LOG_TRACE(Kernel_SVC, "called, out_memory_info=0x{:016X}, " "query_address=0x{:016X}", diff --git a/src/core/hle/kernel/svc/svc_shared_memory.cpp b/src/core/hle/kernel/svc/svc_shared_memory.cpp index 40d878f17..a698596aa 100644 --- a/src/core/hle/kernel/svc/svc_shared_memory.cpp +++ b/src/core/hle/kernel/svc/svc_shared_memory.cpp @@ -26,7 +26,7 @@ constexpr bool IsValidSharedMemoryPermission(MemoryPermission perm) { } // namespace -Result MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size, +Result MapSharedMemory(Core::System& system, Handle shmem_handle, u64 address, u64 size, Svc::MemoryPermission map_perm) { LOG_TRACE(Kernel_SVC, "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", @@ -64,7 +64,7 @@ Result MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, R_RETURN(shmem->Map(process, address, size, map_perm)); } -Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size) { +Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, u64 address, u64 size) { // Validate the address/size. R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp index 660b45c23..e490a13ae 100644 --- a/src/core/hle/kernel/svc/svc_synchronization.cpp +++ b/src/core/hle/kernel/svc/svc_synchronization.cpp @@ -80,7 +80,7 @@ static Result WaitSynchronization(Core::System& system, int32_t* out_index, cons } /// Wait for the given handles to synchronize, timeout after the specified nanoseconds -Result WaitSynchronization(Core::System& system, int32_t* out_index, VAddr user_handles, +Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_handles, int32_t num_handles, int64_t timeout_ns) { LOG_TRACE(Kernel_SVC, "called user_handles={:#x}, num_handles={}, timeout_ns={}", user_handles, num_handles, timeout_ns); diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp index 50991fb62..0be4858a2 100644 --- a/src/core/hle/kernel/svc/svc_thread.cpp +++ b/src/core/hle/kernel/svc/svc_thread.cpp @@ -19,8 +19,8 @@ constexpr bool IsValidVirtualCoreId(int32_t core_id) { } // Anonymous namespace /// Creates a new thread -Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, - VAddr stack_bottom, s32 priority, s32 core_id) { +Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u64 arg, + u64 stack_bottom, s32 priority, s32 core_id) { LOG_DEBUG(Kernel_SVC, "called entry_point=0x{:08X}, arg=0x{:08X}, stack_bottom=0x{:08X}, " "priority=0x{:08X}, core_id=0x{:08X}", @@ -129,7 +129,7 @@ void SleepThread(Core::System& system, s64 nanoseconds) { } /// Gets the thread context -Result GetThreadContext3(Core::System& system, VAddr out_context, Handle thread_handle) { +Result GetThreadContext3(Core::System& system, u64 out_context, Handle thread_handle) { LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle=0x{:X}", out_context, thread_handle); @@ -217,7 +217,7 @@ Result SetThreadPriority(Core::System& system, Handle thread_handle, s32 priorit R_SUCCEED(); } -Result GetThreadList(Core::System& system, s32* out_num_threads, VAddr out_thread_ids, +Result GetThreadList(Core::System& system, s32* out_num_threads, u64 out_thread_ids, s32 out_thread_ids_size, Handle debug_handle) { // TODO: Handle this case when debug events are supported. UNIMPLEMENTED_IF(debug_handle != InvalidHandle); diff --git a/src/core/hle/kernel/svc/svc_transfer_memory.cpp b/src/core/hle/kernel/svc/svc_transfer_memory.cpp index 394f06728..82d469a37 100644 --- a/src/core/hle/kernel/svc/svc_transfer_memory.cpp +++ b/src/core/hle/kernel/svc/svc_transfer_memory.cpp @@ -25,7 +25,7 @@ constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) { } // Anonymous namespace /// Creates a TransferMemory object -Result CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size, +Result CreateTransferMemory(Core::System& system, Handle* out, u64 address, u64 size, MemoryPermission map_perm) { auto& kernel = system.Kernel(); diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h index 39355d9c4..7f380ca4f 100644 --- a/src/core/hle/kernel/svc_types.h +++ b/src/core/hle/kernel/svc_types.h @@ -253,7 +253,7 @@ struct LastThreadContext { }; struct PhysicalMemoryInfo { - PAddr physical_address; + u64 physical_address; u64 virtual_address; u64 size; }; @@ -359,7 +359,7 @@ struct LastThreadContext { }; struct PhysicalMemoryInfo { - PAddr physical_address; + u64 physical_address; u32 virtual_address; u32 size; }; diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/console_sixaxis.cpp index 478d38590..37f2e4405 100644 --- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp +++ b/src/core/hle/service/hid/controllers/console_sixaxis.cpp @@ -63,7 +63,7 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti system.Memory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo)); } -void Controller_ConsoleSixAxis::SetTransferMemoryAddress(VAddr t_mem) { +void Controller_ConsoleSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) { transfer_memory = t_mem; } diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.h b/src/core/hle/service/hid/controllers/console_sixaxis.h index 8d3e4081b..7015d924c 100644 --- a/src/core/hle/service/hid/controllers/console_sixaxis.h +++ b/src/core/hle/service/hid/controllers/console_sixaxis.h @@ -5,8 +5,8 @@ #include -#include "common/common_types.h" #include "common/quaternion.h" +#include "common/typed_address.h" #include "core/hle/service/hid/controllers/controller_base.h" #include "core/hle/service/hid/ring_lifo.h" @@ -34,7 +34,7 @@ public: void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; // Called on InitializeSevenSixAxisSensor - void SetTransferMemoryAddress(VAddr t_mem); + void SetTransferMemoryAddress(Common::ProcessAddress t_mem); // Called on ResetSevenSixAxisSensorTimestamp void ResetTimestamp(); @@ -66,7 +66,7 @@ private: static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size"); SevenSixAxisState next_seven_sixaxis_state{}; - VAddr transfer_memory{}; + Common::ProcessAddress transfer_memory{}; ConsoleSharedMemory* shared_memory = nullptr; Core::HID::EmulatedConsole* console = nullptr; diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp index bce51285c..14c67e454 100644 --- a/src/core/hle/service/hid/controllers/palma.cpp +++ b/src/core/hle/service/hid/controllers/palma.cpp @@ -152,7 +152,7 @@ Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandl } Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, - VAddr t_mem, u64 size) { + Common::ProcessAddress t_mem, u64 size) { if (handle.npad_id != active_handle.npad_id) { return InvalidPalmaHandle; } diff --git a/src/core/hle/service/hid/controllers/palma.h b/src/core/hle/service/hid/controllers/palma.h index cf62f0dbc..a0491a819 100644 --- a/src/core/hle/service/hid/controllers/palma.h +++ b/src/core/hle/service/hid/controllers/palma.h @@ -5,7 +5,7 @@ #include #include "common/common_funcs.h" -#include "common/common_types.h" +#include "common/typed_address.h" #include "core/hle/service/hid/controllers/controller_base.h" #include "core/hle/service/hid/errors.h" @@ -125,8 +125,8 @@ public: Result ReadPalmaUniqueCode(const PalmaConnectionHandle& handle); Result SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle); Result WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown); - Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, VAddr t_mem, - u64 size); + Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, + Common::ProcessAddress t_mem, u64 size); Result SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle, s32 database_id_version_); Result GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle); diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.cpp b/src/core/hle/service/hid/hidbus/hidbus_base.cpp index dfd23ec04..ee522c36e 100644 --- a/src/core/hle/service/hid/hidbus/hidbus_base.cpp +++ b/src/core/hle/service/hid/hidbus/hidbus_base.cpp @@ -59,7 +59,7 @@ void HidbusBase::DisablePollingMode() { polling_mode_enabled = false; } -void HidbusBase::SetTransferMemoryAddress(VAddr t_mem) { +void HidbusBase::SetTransferMemoryAddress(Common::ProcessAddress t_mem) { transfer_memory = t_mem; } diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.h b/src/core/hle/service/hid/hidbus/hidbus_base.h index 26313264d..ec41684e1 100644 --- a/src/core/hle/service/hid/hidbus/hidbus_base.h +++ b/src/core/hle/service/hid/hidbus/hidbus_base.h @@ -5,7 +5,7 @@ #include #include -#include "common/common_types.h" +#include "common/typed_address.h" #include "core/hle/result.h" namespace Core { @@ -138,7 +138,7 @@ public: void DisablePollingMode(); // Called on EnableJoyPollingReceiveMode - void SetTransferMemoryAddress(VAddr t_mem); + void SetTransferMemoryAddress(Common::ProcessAddress t_mem); Kernel::KReadableEvent& GetSendCommandAsycEvent() const; @@ -174,7 +174,7 @@ protected: JoyEnableSixAxisDataAccessor enable_sixaxis_data{}; ButtonOnlyPollingDataAccessor button_only_data{}; - VAddr transfer_memory{}; + Common::ProcessAddress transfer_memory{}; Core::System& system; Kernel::KEvent* send_command_async_event; diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp index a268750cd..ca5d067e8 100644 --- a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp +++ b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp @@ -140,7 +140,7 @@ void ImageTransferProcessor::SetConfig( npad_device->SetCameraFormat(current_config.origin_format); } -void ImageTransferProcessor::SetTransferMemoryAddress(VAddr t_mem) { +void ImageTransferProcessor::SetTransferMemoryAddress(Common::ProcessAddress t_mem) { transfer_memory = t_mem; } diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.h b/src/core/hle/service/hid/irsensor/image_transfer_processor.h index 7cfe04c8c..7f42d8453 100644 --- a/src/core/hle/service/hid/irsensor/image_transfer_processor.h +++ b/src/core/hle/service/hid/irsensor/image_transfer_processor.h @@ -3,7 +3,7 @@ #pragma once -#include "common/common_types.h" +#include "common/typed_address.h" #include "core/hid/irs_types.h" #include "core/hle/service/hid/irsensor/processor_base.h" @@ -37,7 +37,7 @@ public: void SetConfig(Core::IrSensor::PackedImageTransferProcessorExConfig config); // Transfer memory where the image data will be stored - void SetTransferMemoryAddress(VAddr t_mem); + void SetTransferMemoryAddress(Common::ProcessAddress t_mem); Core::IrSensor::ImageTransferProcessorState GetState(std::vector& data) const; @@ -72,6 +72,6 @@ private: int callback_key{}; Core::System& system; - VAddr transfer_memory{}; + Common::ProcessAddress transfer_memory{}; }; } // namespace Service::IRS diff --git a/src/core/hle/service/jit/jit.cpp b/src/core/hle/service/jit/jit.cpp index 46bcfd695..607f27b21 100644 --- a/src/core/hle/service/jit/jit.cpp +++ b/src/core/hle/service/jit/jit.cpp @@ -195,7 +195,7 @@ public: } // Set up the configuration with the required TransferMemory address - configuration.transfer_memory.offset = tmem->GetSourceAddress(); + configuration.transfer_memory.offset = GetInteger(tmem->GetSourceAddress()); configuration.transfer_memory.size = tmem_size; // Gather up all the callbacks from the loaded plugin @@ -383,12 +383,12 @@ public: } const CodeRange user_rx{ - .offset = rx_mem->GetSourceAddress(), + .offset = GetInteger(rx_mem->GetSourceAddress()), .size = parameters.rx_size, }; const CodeRange user_ro{ - .offset = ro_mem->GetSourceAddress(), + .offset = GetInteger(ro_mem->GetSourceAddress()), .size = parameters.ro_size, }; diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 6de96ed5b..437dc2ea5 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp @@ -337,7 +337,7 @@ public: bool succeeded = false; const auto map_region_end = - page_table.GetAliasCodeRegionStart() + page_table.GetAliasCodeRegionSize(); + GetInteger(page_table.GetAliasCodeRegionStart()) + page_table.GetAliasCodeRegionSize(); while (current_map_addr < map_region_end) { if (is_region_available(current_map_addr)) { succeeded = true; @@ -642,7 +642,8 @@ public: LOG_WARNING(Service_LDR, "(STUBBED) called"); initialized = true; - current_map_addr = system.ApplicationProcess()->PageTable().GetAliasCodeRegionStart(); + current_map_addr = + GetInteger(system.ApplicationProcess()->PageTable().GetAliasCodeRegionStart()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 192571d35..3be9b71cf 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -153,7 +153,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect // Load NSO modules modules.clear(); - const VAddr base_address{process.PageTable().GetCodeRegionStart()}; + const VAddr base_address{GetInteger(process.PageTable().GetCodeRegionStart())}; VAddr next_load_addr{base_address}; const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(), system.GetContentProvider()}; diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp index d8a1bf82a..709e2564f 100644 --- a/src/core/loader/kip.cpp +++ b/src/core/loader/kip.cpp @@ -96,7 +96,7 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process, } codeset.memory = std::move(program_image); - const VAddr base_address = process.PageTable().GetCodeRegionStart(); + const VAddr base_address = GetInteger(process.PageTable().GetCodeRegionStart()); process.LoadModule(std::move(codeset), base_address); LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address); diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index a5c384fb5..79639f5e4 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -167,7 +167,7 @@ AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::S modules.clear(); // Load module - const VAddr base_address = process.PageTable().GetCodeRegionStart(); + const VAddr base_address = GetInteger(process.PageTable().GetCodeRegionStart()); if (!LoadModule(process, system, *file, base_address, true, true)) { return {ResultStatus::ErrorLoadingNSO, {}}; } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 4397fcfb1..95e070825 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -35,31 +35,35 @@ struct Memory::Impl { system.ArmInterface(core_id).PageTableChanged(*current_page_table, address_space_width); } - void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) { + void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size, + Common::PhysicalAddress target) { ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size); - ASSERT_MSG((base & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", base); - ASSERT_MSG(target >= DramMemoryMap::Base, "Out of bounds target: {:016X}", target); + ASSERT_MSG((base & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", GetInteger(base)); + ASSERT_MSG(target >= DramMemoryMap::Base, "Out of bounds target: {:016X}", + GetInteger(target)); MapPages(page_table, base / YUZU_PAGESIZE, size / YUZU_PAGESIZE, target, Common::PageType::Memory); if (Settings::IsFastmemEnabled()) { - system.DeviceMemory().buffer.Map(base, target - DramMemoryMap::Base, size); + system.DeviceMemory().buffer.Map(GetInteger(base), + GetInteger(target) - DramMemoryMap::Base, size); } } - void UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) { + void UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size) { ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size); - ASSERT_MSG((base & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", base); + ASSERT_MSG((base & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", GetInteger(base)); MapPages(page_table, base / YUZU_PAGESIZE, size / YUZU_PAGESIZE, 0, Common::PageType::Unmapped); if (Settings::IsFastmemEnabled()) { - system.DeviceMemory().buffer.Unmap(base, size); + system.DeviceMemory().buffer.Unmap(GetInteger(base), size); } } - [[nodiscard]] u8* GetPointerFromRasterizerCachedMemory(VAddr vaddr) const { - const PAddr paddr{current_page_table->backing_addr[vaddr >> YUZU_PAGEBITS]}; + [[nodiscard]] u8* GetPointerFromRasterizerCachedMemory(u64 vaddr) const { + const Common::PhysicalAddress paddr{ + current_page_table->backing_addr[vaddr >> YUZU_PAGEBITS]}; if (!paddr) { return {}; @@ -68,8 +72,9 @@ struct Memory::Impl { return system.DeviceMemory().GetPointer(paddr) + vaddr; } - [[nodiscard]] u8* GetPointerFromDebugMemory(VAddr vaddr) const { - const PAddr paddr{current_page_table->backing_addr[vaddr >> YUZU_PAGEBITS]}; + [[nodiscard]] u8* GetPointerFromDebugMemory(u64 vaddr) const { + const Common::PhysicalAddress paddr{ + current_page_table->backing_addr[vaddr >> YUZU_PAGEBITS]}; if (paddr == 0) { return {}; @@ -78,11 +83,11 @@ struct Memory::Impl { return system.DeviceMemory().GetPointer(paddr) + vaddr; } - u8 Read8(const VAddr addr) { + u8 Read8(const Common::ProcessAddress addr) { return Read(addr); } - u16 Read16(const VAddr addr) { + u16 Read16(const Common::ProcessAddress addr) { if ((addr & 1) == 0) { return Read(addr); } else { @@ -92,7 +97,7 @@ struct Memory::Impl { } } - u32 Read32(const VAddr addr) { + u32 Read32(const Common::ProcessAddress addr) { if ((addr & 3) == 0) { return Read(addr); } else { @@ -102,7 +107,7 @@ struct Memory::Impl { } } - u64 Read64(const VAddr addr) { + u64 Read64(const Common::ProcessAddress addr) { if ((addr & 7) == 0) { return Read(addr); } else { @@ -112,11 +117,11 @@ struct Memory::Impl { } } - void Write8(const VAddr addr, const u8 data) { + void Write8(const Common::ProcessAddress addr, const u8 data) { Write(addr, data); } - void Write16(const VAddr addr, const u16 data) { + void Write16(const Common::ProcessAddress addr, const u16 data) { if ((addr & 1) == 0) { Write(addr, data); } else { @@ -125,7 +130,7 @@ struct Memory::Impl { } } - void Write32(const VAddr addr, const u32 data) { + void Write32(const Common::ProcessAddress addr, const u32 data) { if ((addr & 3) == 0) { Write(addr, data); } else { @@ -134,7 +139,7 @@ struct Memory::Impl { } } - void Write64(const VAddr addr, const u64 data) { + void Write64(const Common::ProcessAddress addr, const u64 data) { if ((addr & 7) == 0) { Write(addr, data); } else { @@ -143,23 +148,23 @@ struct Memory::Impl { } } - bool WriteExclusive8(const VAddr addr, const u8 data, const u8 expected) { + bool WriteExclusive8(const Common::ProcessAddress addr, const u8 data, const u8 expected) { return WriteExclusive(addr, data, expected); } - bool WriteExclusive16(const VAddr addr, const u16 data, const u16 expected) { + bool WriteExclusive16(const Common::ProcessAddress addr, const u16 data, const u16 expected) { return WriteExclusive(addr, data, expected); } - bool WriteExclusive32(const VAddr addr, const u32 data, const u32 expected) { + bool WriteExclusive32(const Common::ProcessAddress addr, const u32 data, const u32 expected) { return WriteExclusive(addr, data, expected); } - bool WriteExclusive64(const VAddr addr, const u64 data, const u64 expected) { + bool WriteExclusive64(const Common::ProcessAddress addr, const u64 data, const u64 expected) { return WriteExclusive(addr, data, expected); } - std::string ReadCString(VAddr vaddr, std::size_t max_length) { + std::string ReadCString(Common::ProcessAddress vaddr, std::size_t max_length) { std::string string; string.reserve(max_length); for (std::size_t i = 0; i < max_length; ++i) { @@ -174,8 +179,9 @@ struct Memory::Impl { return string; } - void WalkBlock(const Kernel::KProcess& process, const VAddr addr, const std::size_t size, - auto on_unmapped, auto on_memory, auto on_rasterizer, auto increment) { + void WalkBlock(const Kernel::KProcess& process, const Common::ProcessAddress addr, + const std::size_t size, auto on_unmapped, auto on_memory, auto on_rasterizer, + auto increment) { const auto& page_table = process.PageTable().PageTableImpl(); std::size_t remaining_size = size; std::size_t page_index = addr >> YUZU_PAGEBITS; @@ -185,7 +191,7 @@ struct Memory::Impl { const std::size_t copy_amount = std::min(static_cast(YUZU_PAGESIZE) - page_offset, remaining_size); const auto current_vaddr = - static_cast((page_index << YUZU_PAGEBITS) + page_offset); + static_cast((page_index << YUZU_PAGEBITS) + page_offset); const auto [pointer, type] = page_table.pointers[page_index].PointerType(); switch (type) { @@ -220,24 +226,24 @@ struct Memory::Impl { } template - void ReadBlockImpl(const Kernel::KProcess& process, const VAddr src_addr, void* dest_buffer, - const std::size_t size) { + void ReadBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress src_addr, + void* dest_buffer, const std::size_t size) { WalkBlock( process, src_addr, size, [src_addr, size, &dest_buffer](const std::size_t copy_amount, - const VAddr current_vaddr) { + const Common::ProcessAddress current_vaddr) { LOG_ERROR(HW_Memory, "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", - current_vaddr, src_addr, size); + GetInteger(current_vaddr), GetInteger(src_addr), size); std::memset(dest_buffer, 0, copy_amount); }, [&](const std::size_t copy_amount, const u8* const src_ptr) { std::memcpy(dest_buffer, src_ptr, copy_amount); }, - [&](const VAddr current_vaddr, const std::size_t copy_amount, + [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, const u8* const host_ptr) { if constexpr (!UNSAFE) { - system.GPU().FlushRegion(current_vaddr, copy_amount); + system.GPU().FlushRegion(GetInteger(current_vaddr), copy_amount); } std::memcpy(dest_buffer, host_ptr, copy_amount); }, @@ -246,30 +252,34 @@ struct Memory::Impl { }); } - void ReadBlock(const VAddr src_addr, void* dest_buffer, const std::size_t size) { + void ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, + const std::size_t size) { ReadBlockImpl(*system.ApplicationProcess(), src_addr, dest_buffer, size); } - void ReadBlockUnsafe(const VAddr src_addr, void* dest_buffer, const std::size_t size) { + void ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer, + const std::size_t size) { ReadBlockImpl(*system.ApplicationProcess(), src_addr, dest_buffer, size); } template - void WriteBlockImpl(const Kernel::KProcess& process, const VAddr dest_addr, + void WriteBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr, const void* src_buffer, const std::size_t size) { WalkBlock( process, dest_addr, size, - [dest_addr, size](const std::size_t copy_amount, const VAddr current_vaddr) { + [dest_addr, size](const std::size_t copy_amount, + const Common::ProcessAddress current_vaddr) { LOG_ERROR(HW_Memory, "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", - current_vaddr, dest_addr, size); + GetInteger(current_vaddr), GetInteger(dest_addr), size); }, [&](const std::size_t copy_amount, u8* const dest_ptr) { std::memcpy(dest_ptr, src_buffer, copy_amount); }, - [&](const VAddr current_vaddr, const std::size_t copy_amount, u8* const host_ptr) { + [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, + u8* const host_ptr) { if constexpr (!UNSAFE) { - system.GPU().InvalidateRegion(current_vaddr, copy_amount); + system.GPU().InvalidateRegion(GetInteger(current_vaddr), copy_amount); } std::memcpy(host_ptr, src_buffer, copy_amount); }, @@ -278,71 +288,77 @@ struct Memory::Impl { }); } - void WriteBlock(const VAddr dest_addr, const void* src_buffer, const std::size_t size) { + void WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, + const std::size_t size) { WriteBlockImpl(*system.ApplicationProcess(), dest_addr, src_buffer, size); } - void WriteBlockUnsafe(const VAddr dest_addr, const void* src_buffer, const std::size_t size) { + void WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer, + const std::size_t size) { WriteBlockImpl(*system.ApplicationProcess(), dest_addr, src_buffer, size); } - void ZeroBlock(const Kernel::KProcess& process, const VAddr dest_addr, const std::size_t size) { + void ZeroBlock(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr, + const std::size_t size) { WalkBlock( process, dest_addr, size, - [dest_addr, size](const std::size_t copy_amount, const VAddr current_vaddr) { + [dest_addr, size](const std::size_t copy_amount, + const Common::ProcessAddress current_vaddr) { LOG_ERROR(HW_Memory, "Unmapped ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", - current_vaddr, dest_addr, size); + GetInteger(current_vaddr), GetInteger(dest_addr), size); }, [](const std::size_t copy_amount, u8* const dest_ptr) { std::memset(dest_ptr, 0, copy_amount); }, - [&](const VAddr current_vaddr, const std::size_t copy_amount, u8* const host_ptr) { - system.GPU().InvalidateRegion(current_vaddr, copy_amount); + [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, + u8* const host_ptr) { + system.GPU().InvalidateRegion(GetInteger(current_vaddr), copy_amount); std::memset(host_ptr, 0, copy_amount); }, [](const std::size_t copy_amount) {}); } - void CopyBlock(const Kernel::KProcess& process, VAddr dest_addr, VAddr src_addr, - const std::size_t size) { + void CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, + Common::ProcessAddress src_addr, const std::size_t size) { WalkBlock( process, dest_addr, size, - [&](const std::size_t copy_amount, const VAddr current_vaddr) { + [&](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) { LOG_ERROR(HW_Memory, "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", - current_vaddr, src_addr, size); + GetInteger(current_vaddr), GetInteger(src_addr), size); ZeroBlock(process, dest_addr, copy_amount); }, [&](const std::size_t copy_amount, const u8* const src_ptr) { WriteBlockImpl(process, dest_addr, src_ptr, copy_amount); }, - [&](const VAddr current_vaddr, const std::size_t copy_amount, u8* const host_ptr) { - system.GPU().FlushRegion(current_vaddr, copy_amount); + [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, + u8* const host_ptr) { + system.GPU().FlushRegion(GetInteger(current_vaddr), copy_amount); WriteBlockImpl(process, dest_addr, host_ptr, copy_amount); }, [&](const std::size_t copy_amount) { - dest_addr += static_cast(copy_amount); - src_addr += static_cast(copy_amount); + dest_addr += copy_amount; + src_addr += copy_amount; }); } template - Result PerformCacheOperation(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size, - Callback&& cb) { + Result PerformCacheOperation(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, + std::size_t size, Callback&& cb) { class InvalidMemoryException : public std::exception {}; try { WalkBlock( process, dest_addr, size, - [&](const std::size_t block_size, const VAddr current_vaddr) { - LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}", current_vaddr); + [&](const std::size_t block_size, const Common::ProcessAddress current_vaddr) { + LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}", + GetInteger(current_vaddr)); throw InvalidMemoryException(); }, [&](const std::size_t block_size, u8* const host_ptr) {}, - [&](const VAddr current_vaddr, const std::size_t block_size, u8* const host_ptr) { - cb(current_vaddr, block_size); - }, + [&](const Common::ProcessAddress current_vaddr, const std::size_t block_size, + u8* const host_ptr) { cb(current_vaddr, block_size); }, [](const std::size_t block_size) {}); } catch (InvalidMemoryException&) { return Kernel::ResultInvalidCurrentMemory; @@ -351,34 +367,40 @@ struct Memory::Impl { return ResultSuccess; } - Result InvalidateDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { - auto on_rasterizer = [&](const VAddr current_vaddr, const std::size_t block_size) { + Result InvalidateDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, + std::size_t size) { + auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, + const std::size_t block_size) { // dc ivac: Invalidate to point of coherency // GPU flush -> CPU invalidate - system.GPU().FlushRegion(current_vaddr, block_size); + system.GPU().FlushRegion(GetInteger(current_vaddr), block_size); }; return PerformCacheOperation(process, dest_addr, size, on_rasterizer); } - Result StoreDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { - auto on_rasterizer = [&](const VAddr current_vaddr, const std::size_t block_size) { + Result StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, + std::size_t size) { + auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, + const std::size_t block_size) { // dc cvac: Store to point of coherency // CPU flush -> GPU invalidate - system.GPU().InvalidateRegion(current_vaddr, block_size); + system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size); }; return PerformCacheOperation(process, dest_addr, size, on_rasterizer); } - Result FlushDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { - auto on_rasterizer = [&](const VAddr current_vaddr, const std::size_t block_size) { + Result FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, + std::size_t size) { + auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, + const std::size_t block_size) { // dc civac: Store to point of coherency, and invalidate from cache // CPU flush -> GPU invalidate - system.GPU().InvalidateRegion(current_vaddr, block_size); + system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size); }; return PerformCacheOperation(process, dest_addr, size, on_rasterizer); } - void MarkRegionDebug(VAddr vaddr, u64 size, bool debug) { + void MarkRegionDebug(u64 vaddr, u64 size, bool debug) { if (vaddr == 0) { return; } @@ -434,7 +456,7 @@ struct Memory::Impl { } } - void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { + void RasterizerMarkRegionCached(u64 vaddr, u64 size, bool cached) { if (vaddr == 0) { return; } @@ -514,10 +536,12 @@ struct Memory::Impl { * @param target The target address to begin mapping from. * @param type The page type to map the memory as. */ - void MapPages(Common::PageTable& page_table, VAddr base, u64 size, PAddr target, - Common::PageType type) { - LOG_DEBUG(HW_Memory, "Mapping {:016X} onto {:016X}-{:016X}", target, base * YUZU_PAGESIZE, - (base + size) * YUZU_PAGESIZE); + void MapPages(Common::PageTable& page_table, Common::ProcessAddress base_address, u64 size, + Common::PhysicalAddress target, Common::PageType type) { + auto base = GetInteger(base_address); + + LOG_DEBUG(HW_Memory, "Mapping {:016X} onto {:016X}-{:016X}", GetInteger(target), + base * YUZU_PAGESIZE, (base + size) * YUZU_PAGESIZE); // During boot, current_page_table might not be set yet, in which case we need not flush if (system.IsPoweredOn()) { @@ -530,7 +554,7 @@ struct Memory::Impl { } } - const VAddr end = base + size; + const Common::ProcessAddress end = base + size; ASSERT_MSG(end <= page_table.pointers.size(), "out of range mapping at {:016X}", base + page_table.pointers.size()); @@ -548,7 +572,7 @@ struct Memory::Impl { while (base != end) { page_table.pointers[base].Store( system.DeviceMemory().GetPointer(target) - (base << YUZU_PAGEBITS), type); - page_table.backing_addr[base] = target - (base << YUZU_PAGEBITS); + page_table.backing_addr[base] = GetInteger(target) - (base << YUZU_PAGEBITS); ASSERT_MSG(page_table.pointers[base].Pointer(), "memory mapping base yield a nullptr within the table"); @@ -559,9 +583,9 @@ struct Memory::Impl { } } - [[nodiscard]] u8* GetPointerImpl(VAddr vaddr, auto on_unmapped, auto on_rasterizer) const { + [[nodiscard]] u8* GetPointerImpl(u64 vaddr, auto on_unmapped, auto on_rasterizer) const { // AARCH64 masks the upper 16 bit of all memory accesses - vaddr &= 0xffffffffffffULL; + vaddr = vaddr & 0xffffffffffffULL; if (vaddr >= 1uLL << current_page_table->GetAddressSpaceBits()) { on_unmapped(); @@ -593,15 +617,18 @@ struct Memory::Impl { return nullptr; } - [[nodiscard]] u8* GetPointer(const VAddr vaddr) const { + [[nodiscard]] u8* GetPointer(const Common::ProcessAddress vaddr) const { return GetPointerImpl( - vaddr, [vaddr]() { LOG_ERROR(HW_Memory, "Unmapped GetPointer @ 0x{:016X}", vaddr); }, + GetInteger(vaddr), + [vaddr]() { + LOG_ERROR(HW_Memory, "Unmapped GetPointer @ 0x{:016X}", GetInteger(vaddr)); + }, []() {}); } - [[nodiscard]] u8* GetPointerSilent(const VAddr vaddr) const { + [[nodiscard]] u8* GetPointerSilent(const Common::ProcessAddress vaddr) const { return GetPointerImpl( - vaddr, []() {}, []() {}); + GetInteger(vaddr), []() {}, []() {}); } /** @@ -616,14 +643,15 @@ struct Memory::Impl { * @returns The instance of T read from the specified virtual address. */ template - T Read(VAddr vaddr) { + T Read(Common::ProcessAddress vaddr) { T result = 0; const u8* const ptr = GetPointerImpl( - vaddr, + GetInteger(vaddr), [vaddr]() { - LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:016X}", sizeof(T) * 8, vaddr); + LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:016X}", sizeof(T) * 8, + GetInteger(vaddr)); }, - [&]() { system.GPU().FlushRegion(vaddr, sizeof(T)); }); + [&]() { system.GPU().FlushRegion(GetInteger(vaddr), sizeof(T)); }); if (ptr) { std::memcpy(&result, ptr, sizeof(T)); } @@ -640,28 +668,28 @@ struct Memory::Impl { * is undefined. */ template - void Write(VAddr vaddr, const T data) { + void Write(Common::ProcessAddress vaddr, const T data) { u8* const ptr = GetPointerImpl( - vaddr, + GetInteger(vaddr), [vaddr, data]() { LOG_ERROR(HW_Memory, "Unmapped Write{} @ 0x{:016X} = 0x{:016X}", sizeof(T) * 8, - vaddr, static_cast(data)); + GetInteger(vaddr), static_cast(data)); }, - [&]() { system.GPU().InvalidateRegion(vaddr, sizeof(T)); }); + [&]() { system.GPU().InvalidateRegion(GetInteger(vaddr), sizeof(T)); }); if (ptr) { std::memcpy(ptr, &data, sizeof(T)); } } template - bool WriteExclusive(VAddr vaddr, const T data, const T expected) { + bool WriteExclusive(Common::ProcessAddress vaddr, const T data, const T expected) { u8* const ptr = GetPointerImpl( - vaddr, + GetInteger(vaddr), [vaddr, data]() { LOG_ERROR(HW_Memory, "Unmapped WriteExclusive{} @ 0x{:016X} = 0x{:016X}", - sizeof(T) * 8, vaddr, static_cast(data)); + sizeof(T) * 8, GetInteger(vaddr), static_cast(data)); }, - [&]() { system.GPU().InvalidateRegion(vaddr, sizeof(T)); }); + [&]() { system.GPU().InvalidateRegion(GetInteger(vaddr), sizeof(T)); }); if (ptr) { const auto volatile_pointer = reinterpret_cast(ptr); return Common::AtomicCompareAndSwap(volatile_pointer, data, expected); @@ -669,14 +697,14 @@ struct Memory::Impl { return true; } - bool WriteExclusive128(VAddr vaddr, const u128 data, const u128 expected) { + bool WriteExclusive128(Common::ProcessAddress vaddr, const u128 data, const u128 expected) { u8* const ptr = GetPointerImpl( - vaddr, + GetInteger(vaddr), [vaddr, data]() { LOG_ERROR(HW_Memory, "Unmapped WriteExclusive128 @ 0x{:016X} = 0x{:016X}{:016X}", - vaddr, static_cast(data[1]), static_cast(data[0])); + GetInteger(vaddr), static_cast(data[1]), static_cast(data[0])); }, - [&]() { system.GPU().InvalidateRegion(vaddr, sizeof(u128)); }); + [&]() { system.GPU().InvalidateRegion(GetInteger(vaddr), sizeof(u128)); }); if (ptr) { const auto volatile_pointer = reinterpret_cast(ptr); return Common::AtomicCompareAndSwap(volatile_pointer, data, expected); @@ -702,15 +730,16 @@ void Memory::SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) { impl->SetCurrentPageTable(process, core_id); } -void Memory::MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) { +void Memory::MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size, + Common::PhysicalAddress target) { impl->MapMemoryRegion(page_table, base, size, target); } -void Memory::UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) { +void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size) { impl->UnmapRegion(page_table, base, size); } -bool Memory::IsValidVirtualAddress(const VAddr vaddr) const { +bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const { const Kernel::KProcess& process = *system.ApplicationProcess(); const auto& page_table = process.PageTable().PageTableImpl(); const size_t page = vaddr >> YUZU_PAGEBITS; @@ -722,9 +751,9 @@ bool Memory::IsValidVirtualAddress(const VAddr vaddr) const { type == Common::PageType::DebugMemory; } -bool Memory::IsValidVirtualAddressRange(VAddr base, u64 size) const { - VAddr end = base + size; - VAddr page = Common::AlignDown(base, YUZU_PAGESIZE); +bool Memory::IsValidVirtualAddressRange(Common::ProcessAddress base, u64 size) const { + Common::ProcessAddress end = base + size; + Common::ProcessAddress page = Common::AlignDown(GetInteger(base), YUZU_PAGESIZE); for (; page < end; page += YUZU_PAGESIZE) { if (!IsValidVirtualAddress(page)) { @@ -735,131 +764,135 @@ bool Memory::IsValidVirtualAddressRange(VAddr base, u64 size) const { return true; } -u8* Memory::GetPointer(VAddr vaddr) { +u8* Memory::GetPointer(Common::ProcessAddress vaddr) { return impl->GetPointer(vaddr); } -u8* Memory::GetPointerSilent(VAddr vaddr) { +u8* Memory::GetPointerSilent(Common::ProcessAddress vaddr) { return impl->GetPointerSilent(vaddr); } -const u8* Memory::GetPointer(VAddr vaddr) const { +const u8* Memory::GetPointer(Common::ProcessAddress vaddr) const { return impl->GetPointer(vaddr); } -u8 Memory::Read8(const VAddr addr) { +u8 Memory::Read8(const Common::ProcessAddress addr) { return impl->Read8(addr); } -u16 Memory::Read16(const VAddr addr) { +u16 Memory::Read16(const Common::ProcessAddress addr) { return impl->Read16(addr); } -u32 Memory::Read32(const VAddr addr) { +u32 Memory::Read32(const Common::ProcessAddress addr) { return impl->Read32(addr); } -u64 Memory::Read64(const VAddr addr) { +u64 Memory::Read64(const Common::ProcessAddress addr) { return impl->Read64(addr); } -void Memory::Write8(VAddr addr, u8 data) { +void Memory::Write8(Common::ProcessAddress addr, u8 data) { impl->Write8(addr, data); } -void Memory::Write16(VAddr addr, u16 data) { +void Memory::Write16(Common::ProcessAddress addr, u16 data) { impl->Write16(addr, data); } -void Memory::Write32(VAddr addr, u32 data) { +void Memory::Write32(Common::ProcessAddress addr, u32 data) { impl->Write32(addr, data); } -void Memory::Write64(VAddr addr, u64 data) { +void Memory::Write64(Common::ProcessAddress addr, u64 data) { impl->Write64(addr, data); } -bool Memory::WriteExclusive8(VAddr addr, u8 data, u8 expected) { +bool Memory::WriteExclusive8(Common::ProcessAddress addr, u8 data, u8 expected) { return impl->WriteExclusive8(addr, data, expected); } -bool Memory::WriteExclusive16(VAddr addr, u16 data, u16 expected) { +bool Memory::WriteExclusive16(Common::ProcessAddress addr, u16 data, u16 expected) { return impl->WriteExclusive16(addr, data, expected); } -bool Memory::WriteExclusive32(VAddr addr, u32 data, u32 expected) { +bool Memory::WriteExclusive32(Common::ProcessAddress addr, u32 data, u32 expected) { return impl->WriteExclusive32(addr, data, expected); } -bool Memory::WriteExclusive64(VAddr addr, u64 data, u64 expected) { +bool Memory::WriteExclusive64(Common::ProcessAddress addr, u64 data, u64 expected) { return impl->WriteExclusive64(addr, data, expected); } -bool Memory::WriteExclusive128(VAddr addr, u128 data, u128 expected) { +bool Memory::WriteExclusive128(Common::ProcessAddress addr, u128 data, u128 expected) { return impl->WriteExclusive128(addr, data, expected); } -std::string Memory::ReadCString(VAddr vaddr, std::size_t max_length) { +std::string Memory::ReadCString(Common::ProcessAddress vaddr, std::size_t max_length) { return impl->ReadCString(vaddr, max_length); } -void Memory::ReadBlock(const Kernel::KProcess& process, const VAddr src_addr, void* dest_buffer, - const std::size_t size) { +void Memory::ReadBlock(const Kernel::KProcess& process, const Common::ProcessAddress src_addr, + void* dest_buffer, const std::size_t size) { impl->ReadBlockImpl(process, src_addr, dest_buffer, size); } -void Memory::ReadBlock(const VAddr src_addr, void* dest_buffer, const std::size_t size) { +void Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, + const std::size_t size) { impl->ReadBlock(src_addr, dest_buffer, size); } -void Memory::ReadBlockUnsafe(const VAddr src_addr, void* dest_buffer, const std::size_t size) { +void Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer, + const std::size_t size) { impl->ReadBlockUnsafe(src_addr, dest_buffer, size); } -void Memory::WriteBlock(const Kernel::KProcess& process, VAddr dest_addr, const void* src_buffer, - std::size_t size) { +void Memory::WriteBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, + const void* src_buffer, std::size_t size) { impl->WriteBlockImpl(process, dest_addr, src_buffer, size); } -void Memory::WriteBlock(const VAddr dest_addr, const void* src_buffer, const std::size_t size) { +void Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, + const std::size_t size) { impl->WriteBlock(dest_addr, src_buffer, size); } -void Memory::WriteBlockUnsafe(const VAddr dest_addr, const void* src_buffer, +void Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer, const std::size_t size) { impl->WriteBlockUnsafe(dest_addr, src_buffer, size); } -void Memory::CopyBlock(const Kernel::KProcess& process, VAddr dest_addr, VAddr src_addr, - const std::size_t size) { +void Memory::CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, + Common::ProcessAddress src_addr, const std::size_t size) { impl->CopyBlock(process, dest_addr, src_addr, size); } -void Memory::ZeroBlock(const Kernel::KProcess& process, VAddr dest_addr, const std::size_t size) { +void Memory::ZeroBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, + const std::size_t size) { impl->ZeroBlock(process, dest_addr, size); } -Result Memory::InvalidateDataCache(const Kernel::KProcess& process, VAddr dest_addr, - const std::size_t size) { +Result Memory::InvalidateDataCache(const Kernel::KProcess& process, + Common::ProcessAddress dest_addr, const std::size_t size) { return impl->InvalidateDataCache(process, dest_addr, size); } -Result Memory::StoreDataCache(const Kernel::KProcess& process, VAddr dest_addr, +Result Memory::StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, const std::size_t size) { return impl->StoreDataCache(process, dest_addr, size); } -Result Memory::FlushDataCache(const Kernel::KProcess& process, VAddr dest_addr, +Result Memory::FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, const std::size_t size) { return impl->FlushDataCache(process, dest_addr, size); } -void Memory::RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { - impl->RasterizerMarkRegionCached(vaddr, size, cached); +void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) { + impl->RasterizerMarkRegionCached(GetInteger(vaddr), size, cached); } -void Memory::MarkRegionDebug(VAddr vaddr, u64 size, bool debug) { - impl->MarkRegionDebug(vaddr, size, debug); +void Memory::MarkRegionDebug(Common::ProcessAddress vaddr, u64 size, bool debug) { + impl->MarkRegionDebug(GetInteger(vaddr), size, debug); } } // namespace Core::Memory diff --git a/src/core/memory.h b/src/core/memory.h index 31fe699d8..ed4e87739 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -6,7 +6,7 @@ #include #include #include -#include "common/common_types.h" +#include "common/typed_address.h" #include "core/hle/result.h" namespace Common { @@ -33,7 +33,7 @@ constexpr u64 YUZU_PAGESIZE = 1ULL << YUZU_PAGEBITS; constexpr u64 YUZU_PAGEMASK = YUZU_PAGESIZE - 1; /// Virtual user-space memory regions -enum : VAddr { +enum : u64 { /// TLS (Thread-Local Storage) related. TLS_ENTRY_SIZE = 0x200, @@ -74,7 +74,8 @@ public: * @param target Buffer with the memory backing the mapping. Must be of length at least * `size`. */ - void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target); + void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size, + Common::PhysicalAddress target); /** * Unmaps a region of the emulated process address space. @@ -83,7 +84,7 @@ public: * @param base The address to begin unmapping at. * @param size The amount of bytes to unmap. */ - void UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size); + void UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size); /** * Checks whether or not the supplied address is a valid virtual @@ -93,7 +94,7 @@ public: * * @returns True if the given virtual address is valid, false otherwise. */ - [[nodiscard]] bool IsValidVirtualAddress(VAddr vaddr) const; + [[nodiscard]] bool IsValidVirtualAddress(Common::ProcessAddress vaddr) const; /** * Checks whether or not the supplied range of addresses are all valid @@ -104,7 +105,7 @@ public: * * @returns True if all bytes in the given range are valid, false otherwise. */ - [[nodiscard]] bool IsValidVirtualAddressRange(VAddr base, u64 size) const; + [[nodiscard]] bool IsValidVirtualAddressRange(Common::ProcessAddress base, u64 size) const; /** * Gets a pointer to the given address. @@ -114,11 +115,11 @@ public: * @returns The pointer to the given address, if the address is valid. * If the address is not valid, nullptr will be returned. */ - u8* GetPointer(VAddr vaddr); - u8* GetPointerSilent(VAddr vaddr); + u8* GetPointer(Common::ProcessAddress vaddr); + u8* GetPointerSilent(Common::ProcessAddress vaddr); template - T* GetPointer(VAddr vaddr) { + T* GetPointer(Common::ProcessAddress vaddr) { return reinterpret_cast(GetPointer(vaddr)); } @@ -130,10 +131,10 @@ public: * @returns The pointer to the given address, if the address is valid. * If the address is not valid, nullptr will be returned. */ - [[nodiscard]] const u8* GetPointer(VAddr vaddr) const; + [[nodiscard]] const u8* GetPointer(Common::ProcessAddress vaddr) const; template - const T* GetPointer(VAddr vaddr) const { + const T* GetPointer(Common::ProcessAddress vaddr) const { return reinterpret_cast(GetPointer(vaddr)); } @@ -145,7 +146,7 @@ public: * * @returns the read 8-bit unsigned value. */ - u8 Read8(VAddr addr); + u8 Read8(Common::ProcessAddress addr); /** * Reads a 16-bit unsigned value from the current process' address space @@ -155,7 +156,7 @@ public: * * @returns the read 16-bit unsigned value. */ - u16 Read16(VAddr addr); + u16 Read16(Common::ProcessAddress addr); /** * Reads a 32-bit unsigned value from the current process' address space @@ -165,7 +166,7 @@ public: * * @returns the read 32-bit unsigned value. */ - u32 Read32(VAddr addr); + u32 Read32(Common::ProcessAddress addr); /** * Reads a 64-bit unsigned value from the current process' address space @@ -175,7 +176,7 @@ public: * * @returns the read 64-bit value. */ - u64 Read64(VAddr addr); + u64 Read64(Common::ProcessAddress addr); /** * Writes an 8-bit unsigned integer to the given virtual address in @@ -186,7 +187,7 @@ public: * * @post The memory at the given virtual address contains the specified data value. */ - void Write8(VAddr addr, u8 data); + void Write8(Common::ProcessAddress addr, u8 data); /** * Writes a 16-bit unsigned integer to the given virtual address in @@ -197,7 +198,7 @@ public: * * @post The memory range [addr, sizeof(data)) contains the given data value. */ - void Write16(VAddr addr, u16 data); + void Write16(Common::ProcessAddress addr, u16 data); /** * Writes a 32-bit unsigned integer to the given virtual address in @@ -208,7 +209,7 @@ public: * * @post The memory range [addr, sizeof(data)) contains the given data value. */ - void Write32(VAddr addr, u32 data); + void Write32(Common::ProcessAddress addr, u32 data); /** * Writes a 64-bit unsigned integer to the given virtual address in @@ -219,7 +220,7 @@ public: * * @post The memory range [addr, sizeof(data)) contains the given data value. */ - void Write64(VAddr addr, u64 data); + void Write64(Common::ProcessAddress addr, u64 data); /** * Writes a 8-bit unsigned integer to the given virtual address in @@ -232,7 +233,7 @@ public: * * @post The memory range [addr, sizeof(data)) contains the given data value. */ - bool WriteExclusive8(VAddr addr, u8 data, u8 expected); + bool WriteExclusive8(Common::ProcessAddress addr, u8 data, u8 expected); /** * Writes a 16-bit unsigned integer to the given virtual address in @@ -245,7 +246,7 @@ public: * * @post The memory range [addr, sizeof(data)) contains the given data value. */ - bool WriteExclusive16(VAddr addr, u16 data, u16 expected); + bool WriteExclusive16(Common::ProcessAddress addr, u16 data, u16 expected); /** * Writes a 32-bit unsigned integer to the given virtual address in @@ -258,7 +259,7 @@ public: * * @post The memory range [addr, sizeof(data)) contains the given data value. */ - bool WriteExclusive32(VAddr addr, u32 data, u32 expected); + bool WriteExclusive32(Common::ProcessAddress addr, u32 data, u32 expected); /** * Writes a 64-bit unsigned integer to the given virtual address in @@ -271,7 +272,7 @@ public: * * @post The memory range [addr, sizeof(data)) contains the given data value. */ - bool WriteExclusive64(VAddr addr, u64 data, u64 expected); + bool WriteExclusive64(Common::ProcessAddress addr, u64 data, u64 expected); /** * Writes a 128-bit unsigned integer to the given virtual address in @@ -284,7 +285,7 @@ public: * * @post The memory range [addr, sizeof(data)) contains the given data value. */ - bool WriteExclusive128(VAddr addr, u128 data, u128 expected); + bool WriteExclusive128(Common::ProcessAddress addr, u128 data, u128 expected); /** * Reads a null-terminated string from the given virtual address. @@ -301,7 +302,7 @@ public: * * @returns The read string. */ - std::string ReadCString(VAddr vaddr, std::size_t max_length); + std::string ReadCString(Common::ProcessAddress vaddr, std::size_t max_length); /** * Reads a contiguous block of bytes from a specified process' address space. @@ -320,8 +321,8 @@ public: * @post The range [dest_buffer, size) contains the read bytes from the * process' address space. */ - void ReadBlock(const Kernel::KProcess& process, VAddr src_addr, void* dest_buffer, - std::size_t size); + void ReadBlock(const Kernel::KProcess& process, Common::ProcessAddress src_addr, + void* dest_buffer, std::size_t size); /** * Reads a contiguous block of bytes from the current process' address space. @@ -339,7 +340,7 @@ public: * @post The range [dest_buffer, size) contains the read bytes from the * current process' address space. */ - void ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size); + void ReadBlock(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size); /** * Reads a contiguous block of bytes from the current process' address space. @@ -358,7 +359,7 @@ public: * @post The range [dest_buffer, size) contains the read bytes from the * current process' address space. */ - void ReadBlockUnsafe(VAddr src_addr, void* dest_buffer, std::size_t size); + void ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size); /** * Writes a range of bytes into a given process' address space at the specified @@ -380,8 +381,8 @@ public: * and will mark that region as invalidated to caches that the active * graphics backend may be maintaining over the course of execution. */ - void WriteBlock(const Kernel::KProcess& process, VAddr dest_addr, const void* src_buffer, - std::size_t size); + void WriteBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, + const void* src_buffer, std::size_t size); /** * Writes a range of bytes into the current process' address space at the specified @@ -402,7 +403,7 @@ public: * and will mark that region as invalidated to caches that the active * graphics backend may be maintaining over the course of execution. */ - void WriteBlock(VAddr dest_addr, const void* src_buffer, std::size_t size); + void WriteBlock(Common::ProcessAddress dest_addr, const void* src_buffer, std::size_t size); /** * Writes a range of bytes into the current process' address space at the specified @@ -420,7 +421,8 @@ public: * will be ignored and an error will be logged. * */ - void WriteBlockUnsafe(VAddr dest_addr, const void* src_buffer, std::size_t size); + void WriteBlockUnsafe(Common::ProcessAddress dest_addr, const void* src_buffer, + std::size_t size); /** * Copies data within a process' address space to another location within the @@ -434,8 +436,8 @@ public: * @post The range [dest_addr, size) within the process' address space contains the * same data within the range [src_addr, size). */ - void CopyBlock(const Kernel::KProcess& process, VAddr dest_addr, VAddr src_addr, - std::size_t size); + void CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, + Common::ProcessAddress src_addr, std::size_t size); /** * Zeros a range of bytes within the current process' address space at the specified @@ -448,7 +450,8 @@ public: * @post The range [dest_addr, size) within the process' address space contains the * value 0. */ - void ZeroBlock(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size); + void ZeroBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, + std::size_t size); /** * Invalidates a range of bytes within the current process' address space at the specified @@ -459,7 +462,8 @@ public: * @param size The size of the range to invalidate, in bytes. * */ - Result InvalidateDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size); + Result InvalidateDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, + std::size_t size); /** * Stores a range of bytes within the current process' address space at the specified @@ -470,7 +474,8 @@ public: * @param size The size of the range to store, in bytes. * */ - Result StoreDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size); + Result StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, + std::size_t size); /** * Flushes a range of bytes within the current process' address space at the specified @@ -481,7 +486,8 @@ public: * @param size The size of the range to flush, in bytes. * */ - Result FlushDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size); + Result FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, + std::size_t size); /** * Marks each page within the specified address range as cached or uncached. @@ -491,7 +497,7 @@ public: * @param cached Whether or not any pages within the address range should be * marked as cached or uncached. */ - void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached); + void RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached); /** * Marks each page within the specified address range as debug or non-debug. @@ -502,7 +508,7 @@ public: * @param debug Whether or not any pages within the address range should be * marked as debug or non-debug. */ - void MarkRegionDebug(VAddr vaddr, u64 size, bool debug); + void MarkRegionDebug(Common::ProcessAddress vaddr, u64 size, bool debug); private: Core::System& system; diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index de729955f..d1284a3a7 100644 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp @@ -201,17 +201,17 @@ void CheatEngine::Initialize() { const auto& page_table = system.ApplicationProcess()->PageTable(); metadata.heap_extents = { - .base = page_table.GetHeapRegionStart(), + .base = GetInteger(page_table.GetHeapRegionStart()), .size = page_table.GetHeapRegionSize(), }; metadata.address_space_extents = { - .base = page_table.GetAddressSpaceStart(), + .base = GetInteger(page_table.GetAddressSpaceStart()), .size = page_table.GetAddressSpaceSize(), }; metadata.alias_extents = { - .base = page_table.GetAliasCodeRegionStart(), + .base = GetInteger(page_table.GetAliasCodeRegionStart()), .size = page_table.GetAliasCodeRegionSize(), }; diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp index 004f2e57a..146c3f21e 100644 --- a/src/core/reporter.cpp +++ b/src/core/reporter.cpp @@ -117,8 +117,8 @@ json GetProcessorStateDataAuto(Core::System& system) { arm.SaveContext(context); return GetProcessorStateData(process->Is64BitProcess() ? "AArch64" : "AArch32", - process->PageTable().GetCodeRegionStart(), context.sp, context.pc, - context.pstate, context.cpu_registers); + GetInteger(process->PageTable().GetCodeRegionStart()), context.sp, + context.pc, context.pstate, context.cpu_registers); } json GetBacktraceData(Core::System& system) { -- cgit v1.2.3