summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp6
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp12
-rw-r--r--src/core/device_memory.cpp2
-rw-r--r--src/core/device_memory.h17
-rw-r--r--src/core/memory.cpp18
5 files changed, 45 insertions, 10 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index cea7f0fb1..c8f6dc765 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -128,6 +128,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
128 if (page_table) { 128 if (page_table) {
129 config.page_table = reinterpret_cast<std::array<std::uint8_t*, NUM_PAGE_TABLE_ENTRIES>*>( 129 config.page_table = reinterpret_cast<std::array<std::uint8_t*, NUM_PAGE_TABLE_ENTRIES>*>(
130 page_table->pointers.data()); 130 page_table->pointers.data());
131 config.fastmem_pointer = page_table->fastmem_arena;
131 } 132 }
132 config.absolute_offset_page_table = true; 133 config.absolute_offset_page_table = true;
133 config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS; 134 config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS;
@@ -143,7 +144,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
143 144
144 // Code cache size 145 // Code cache size
145 config.code_cache_size = 512 * 1024 * 1024; 146 config.code_cache_size = 512 * 1024 * 1024;
146 config.far_code_offset = 256 * 1024 * 1024; 147 config.far_code_offset = 400 * 1024 * 1024;
147 148
148 // Safe optimizations 149 // Safe optimizations
149 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) { 150 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) {
@@ -171,6 +172,9 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
171 if (!Settings::values.cpuopt_reduce_misalign_checks) { 172 if (!Settings::values.cpuopt_reduce_misalign_checks) {
172 config.only_detect_misalignment_via_page_table_on_page_boundary = false; 173 config.only_detect_misalignment_via_page_table_on_page_boundary = false;
173 } 174 }
175 if (!Settings::values.cpuopt_fastmem) {
176 config.fastmem_pointer = nullptr;
177 }
174 } 178 }
175 179
176 // Unsafe optimizations 180 // Unsafe optimizations
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index 63193dcb1..ba524cd05 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -160,6 +160,10 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
160 config.absolute_offset_page_table = true; 160 config.absolute_offset_page_table = true;
161 config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128; 161 config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128;
162 config.only_detect_misalignment_via_page_table_on_page_boundary = true; 162 config.only_detect_misalignment_via_page_table_on_page_boundary = true;
163
164 config.fastmem_pointer = page_table->fastmem_arena;
165 config.fastmem_address_space_bits = address_space_bits;
166 config.silently_mirror_fastmem = false;
163 } 167 }
164 168
165 // Multi-process state 169 // Multi-process state
@@ -181,7 +185,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
181 185
182 // Code cache size 186 // Code cache size
183 config.code_cache_size = 512 * 1024 * 1024; 187 config.code_cache_size = 512 * 1024 * 1024;
184 config.far_code_offset = 256 * 1024 * 1024; 188 config.far_code_offset = 400 * 1024 * 1024;
185 189
186 // Safe optimizations 190 // Safe optimizations
187 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) { 191 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) {
@@ -209,6 +213,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
209 if (!Settings::values.cpuopt_reduce_misalign_checks) { 213 if (!Settings::values.cpuopt_reduce_misalign_checks) {
210 config.only_detect_misalignment_via_page_table_on_page_boundary = false; 214 config.only_detect_misalignment_via_page_table_on_page_boundary = false;
211 } 215 }
216 if (!Settings::values.cpuopt_fastmem) {
217 config.fastmem_pointer = nullptr;
218 }
212 } 219 }
213 220
214 // Unsafe optimizations 221 // Unsafe optimizations
@@ -223,6 +230,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
223 if (Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue()) { 230 if (Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue()) {
224 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; 231 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
225 } 232 }
233 if (Settings::values.cpuopt_unsafe_fastmem_check.GetValue()) {
234 config.fastmem_address_space_bits = 64;
235 }
226 } 236 }
227 237
228 return std::make_shared<Dynarmic::A64::Jit>(config); 238 return std::make_shared<Dynarmic::A64::Jit>(config);
diff --git a/src/core/device_memory.cpp b/src/core/device_memory.cpp
index 0c4b440ed..f19c0515f 100644
--- a/src/core/device_memory.cpp
+++ b/src/core/device_memory.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Core { 7namespace Core {
8 8
9DeviceMemory::DeviceMemory() : buffer{DramMemoryMap::Size} {} 9DeviceMemory::DeviceMemory() : buffer{DramMemoryMap::Size, 1ULL << 39} {}
10DeviceMemory::~DeviceMemory() = default; 10DeviceMemory::~DeviceMemory() = default;
11 11
12} // namespace Core 12} // namespace Core
diff --git a/src/core/device_memory.h b/src/core/device_memory.h
index 5b1ae28f3..c4d17705f 100644
--- a/src/core/device_memory.h
+++ b/src/core/device_memory.h
@@ -5,7 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "common/virtual_buffer.h" 8#include "common/host_memory.h"
9 9
10namespace Core { 10namespace Core {
11 11
@@ -21,27 +21,30 @@ enum : u64 {
21}; 21};
22}; // namespace DramMemoryMap 22}; // namespace DramMemoryMap
23 23
24class DeviceMemory : NonCopyable { 24class DeviceMemory {
25public: 25public:
26 explicit DeviceMemory(); 26 explicit DeviceMemory();
27 ~DeviceMemory(); 27 ~DeviceMemory();
28 28
29 DeviceMemory& operator=(const DeviceMemory&) = delete;
30 DeviceMemory(const DeviceMemory&) = delete;
31
29 template <typename T> 32 template <typename T>
30 PAddr GetPhysicalAddr(const T* ptr) const { 33 PAddr GetPhysicalAddr(const T* ptr) const {
31 return (reinterpret_cast<uintptr_t>(ptr) - reinterpret_cast<uintptr_t>(buffer.data())) + 34 return (reinterpret_cast<uintptr_t>(ptr) -
35 reinterpret_cast<uintptr_t>(buffer.BackingBasePointer())) +
32 DramMemoryMap::Base; 36 DramMemoryMap::Base;
33 } 37 }
34 38
35 u8* GetPointer(PAddr addr) { 39 u8* GetPointer(PAddr addr) {
36 return buffer.data() + (addr - DramMemoryMap::Base); 40 return buffer.BackingBasePointer() + (addr - DramMemoryMap::Base);
37 } 41 }
38 42
39 const u8* GetPointer(PAddr addr) const { 43 const u8* GetPointer(PAddr addr) const {
40 return buffer.data() + (addr - DramMemoryMap::Base); 44 return buffer.BackingBasePointer() + (addr - DramMemoryMap::Base);
41 } 45 }
42 46
43private: 47 Common::HostMemory buffer;
44 Common::VirtualBuffer<u8> buffer;
45}; 48};
46 49
47} // namespace Core 50} // namespace Core
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 9857278f6..f285c6f63 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -12,6 +12,7 @@
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "common/logging/log.h" 13#include "common/logging/log.h"
14#include "common/page_table.h" 14#include "common/page_table.h"
15#include "common/settings.h"
15#include "common/swap.h" 16#include "common/swap.h"
16#include "core/arm/arm_interface.h" 17#include "core/arm/arm_interface.h"
17#include "core/core.h" 18#include "core/core.h"
@@ -32,6 +33,7 @@ struct Memory::Impl {
32 33
33 void SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) { 34 void SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) {
34 current_page_table = &process.PageTable().PageTableImpl(); 35 current_page_table = &process.PageTable().PageTableImpl();
36 current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer();
35 37
36 const std::size_t address_space_width = process.PageTable().GetAddressSpaceWidth(); 38 const std::size_t address_space_width = process.PageTable().GetAddressSpaceWidth();
37 39
@@ -41,13 +43,23 @@ struct Memory::Impl {
41 void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) { 43 void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) {
42 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size); 44 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size);
43 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base); 45 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base);
46 ASSERT_MSG(target >= DramMemoryMap::Base && target < DramMemoryMap::End,
47 "Out of bounds target: {:016X}", target);
44 MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, Common::PageType::Memory); 48 MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, Common::PageType::Memory);
49
50 if (Settings::IsFastmemEnabled()) {
51 system.DeviceMemory().buffer.Map(base, target - DramMemoryMap::Base, size);
52 }
45 } 53 }
46 54
47 void UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) { 55 void UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) {
48 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size); 56 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size);
49 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base); 57 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base);
50 MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, 0, Common::PageType::Unmapped); 58 MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, 0, Common::PageType::Unmapped);
59
60 if (Settings::IsFastmemEnabled()) {
61 system.DeviceMemory().buffer.Unmap(base, size);
62 }
51 } 63 }
52 64
53 bool IsValidVirtualAddress(const Kernel::KProcess& process, const VAddr vaddr) const { 65 bool IsValidVirtualAddress(const Kernel::KProcess& process, const VAddr vaddr) const {
@@ -466,6 +478,12 @@ struct Memory::Impl {
466 if (vaddr == 0) { 478 if (vaddr == 0) {
467 return; 479 return;
468 } 480 }
481
482 if (Settings::IsFastmemEnabled()) {
483 const bool is_read_enable = Settings::IsGPULevelHigh() || !cached;
484 system.DeviceMemory().buffer.Protect(vaddr, size, is_read_enable, !cached);
485 }
486
469 // Iterate over a contiguous CPU address space, which corresponds to the specified GPU 487 // Iterate over a contiguous CPU address space, which corresponds to the specified GPU
470 // address space, marking the region as un/cached. The region is marked un/cached at a 488 // address space, marking the region as un/cached. The region is marked un/cached at a
471 // granularity of CPU pages, hence why we iterate on a CPU page basis (note: GPU page size 489 // granularity of CPU pages, hence why we iterate on a CPU page basis (note: GPU page size