diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 1ea243283..26e1636ee 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -35,6 +35,8 @@ add_library(core STATIC crypto/ctr_encryption_layer.h crypto/xts_encryption_layer.cpp crypto/xts_encryption_layer.h + device_memory.cpp + device_memory.h file_sys/bis_factory.cpp file_sys/bis_factory.h file_sys/card_image.cpp diff --git a/src/core/core.cpp b/src/core/core.cpp index 87b147f63..4bc71c7a7 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -14,6 +14,7 @@ #include "core/core_manager.h" #include "core/core_timing.h" #include "core/cpu_manager.h" +#include "core/device_memory.h" #include "core/file_sys/bis_factory.h" #include "core/file_sys/card_image.h" #include "core/file_sys/mode.h" @@ -113,7 +114,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, } struct System::Impl { explicit Impl(System& system) - : kernel{system}, fs_controller{system}, memory{system}, + : kernel{system}, device_memory{system}, fs_controller{system}, memory{system}, cpu_manager{system}, reporter{system}, applet_manager{system} {} CoreManager& CurrentCoreManager() { @@ -337,6 +338,7 @@ struct System::Impl { Timing::CoreTiming core_timing; Kernel::KernelCore kernel; + DeviceMemory device_memory; /// RealVfsFilesystem instance FileSys::VirtualFilesystem virtual_filesystem; /// ContentProviderUnion instance @@ -472,6 +474,14 @@ Kernel::Process* System::CurrentProcess() { return impl->kernel.CurrentProcess(); } +DeviceMemory& System::GetDeviceMemory() { + return impl->device_memory; +} + +const DeviceMemory& System::GetDeviceMemory() const { + return impl->device_memory; +} + const Kernel::Process* System::CurrentProcess() const { return impl->kernel.CurrentProcess(); } diff --git a/src/core/core.h b/src/core/core.h index c2bdef07e..6cd93000a 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -91,6 +91,7 @@ namespace Core { class ARM_Interface; class CoreManager; +class DeviceMemory; class ExclusiveMonitor; class FrameLimiter; class PerfStats; @@ -256,6 +257,12 @@ public: /// Gets the global scheduler const Kernel::GlobalScheduler& GlobalScheduler() const; + /// Gets the manager for the guest device memory + DeviceMemory& GetDeviceMemory(); + + /// Gets the manager for the guest device memory + const DeviceMemory& GetDeviceMemory() const; + /// Provides a pointer to the current process Kernel::Process* CurrentProcess(); diff --git a/src/core/device_memory.cpp b/src/core/device_memory.cpp new file mode 100644 index 000000000..1e4187546 --- /dev/null +++ b/src/core/device_memory.cpp @@ -0,0 +1,50 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#ifdef _WIN32 +#include +#endif + +#include "common/assert.h" +#include "core/core.h" +#include "core/device_memory.h" +#include "core/memory.h" + +namespace Core { + +constexpr u64 DramSize{4ULL * 1024 * 1024 * 1024}; + +DeviceMemory::DeviceMemory(System& system) : system{system} { +#ifdef _WIN32 + base = static_cast( + VirtualAlloc(nullptr, // System selects address + DramSize, // Size of allocation + MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, // Allocate reserved pages + PAGE_READWRITE)); // Protection = no access +#else + physical_memory.resize(DramSize); + base = physical_memory.data(); +#endif +} + +DeviceMemory::~DeviceMemory() { +#ifdef _WIN32 + ASSERT(VirtualFree(base, DramSize, MEM_RELEASE)); +#endif +} + +PAddr DeviceMemory::GetPhysicalAddr(VAddr addr) { + u8* pointer{system.Memory().GetPointer(addr)}; + ASSERT(pointer); + const uintptr_t offset{static_cast(pointer - GetPointer(DramMemoryMap::Base))}; + return DramMemoryMap::Base + offset; +} + +u8* DeviceMemory::GetPointer(PAddr addr) { + ASSERT(addr >= DramMemoryMap::Base); + ASSERT(addr < DramMemoryMap::Base + DramSize); + return base + (addr - DramMemoryMap::Base); +} + +} // namespace Core diff --git a/src/core/device_memory.h b/src/core/device_memory.h new file mode 100644 index 000000000..a60a7238a --- /dev/null +++ b/src/core/device_memory.h @@ -0,0 +1,48 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "common/assert.h" +#include "common/common_funcs.h" +#include "core/hle/kernel/physical_memory.h" + +namespace Core { + +class System; + +namespace DramMemoryMap { +constexpr u64 Base = 0x80000000ULL; +constexpr u64 Size = 0x100000000ULL; +constexpr u64 End = Base + Size; +constexpr u64 KernelReserveBase = Base + 0x60000; +constexpr u64 SlabHeapBase = KernelReserveBase + 0x85000; +constexpr u64 SlapHeapSize = 0xa21000; +constexpr u64 SlabHeapEnd = SlabHeapBase + SlapHeapSize; +}; // namespace DramMemoryMap + +class DeviceMemory : NonCopyable { +public: + DeviceMemory(Core::System& system); + ~DeviceMemory(); + + template + PAddr GetPhysicalAddr(T* ptr) { + const auto ptr_addr{reinterpret_cast(ptr)}; + const auto base_addr{reinterpret_cast(base)}; + ASSERT(ptr_addr >= base_addr); + return ptr_addr - base_addr + DramMemoryMap::Base; + } + + PAddr GetPhysicalAddr(VAddr addr); + + u8* GetPointer(PAddr addr); + +private: + u8* base{}; + Kernel::PhysicalMemory physical_memory; + Core::System& system; +}; + +} // namespace Core