summaryrefslogtreecommitdiffstats
path: root/src/core/memory.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/memory.cpp62
1 files changed, 53 insertions, 9 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 257406f09..e1fbe8e00 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -31,10 +31,10 @@ struct Memory::Impl {
explicit Impl(Core::System& system_) : system{system_} {}
void SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) {
- current_page_table = &process.PageTable().PageTableImpl();
+ current_page_table = &process.GetPageTable().PageTableImpl();
current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer();
- const std::size_t address_space_width = process.PageTable().GetAddressSpaceWidth();
+ const std::size_t address_space_width = process.GetPageTable().GetAddressSpaceWidth();
system.ArmInterface(core_id).PageTableChanged(*current_page_table, address_space_width);
}
@@ -186,7 +186,7 @@ struct Memory::Impl {
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();
+ const auto& page_table = process.GetPageTable().PageTableImpl();
std::size_t remaining_size = size;
std::size_t page_index = addr >> YUZU_PAGEBITS;
std::size_t page_offset = addr & YUZU_PAGEMASK;
@@ -266,6 +266,22 @@ struct Memory::Impl {
ReadBlockImpl<true>(*system.ApplicationProcess(), src_addr, dest_buffer, size);
}
+ const u8* GetSpan(const VAddr src_addr, const std::size_t size) const {
+ if (current_page_table->blocks[src_addr >> YUZU_PAGEBITS] ==
+ current_page_table->blocks[(src_addr + size) >> YUZU_PAGEBITS]) {
+ return GetPointerSilent(src_addr);
+ }
+ return nullptr;
+ }
+
+ u8* GetSpan(const VAddr src_addr, const std::size_t size) {
+ if (current_page_table->blocks[src_addr >> YUZU_PAGEBITS] ==
+ current_page_table->blocks[(src_addr + size) >> YUZU_PAGEBITS]) {
+ return GetPointerSilent(src_addr);
+ }
+ return nullptr;
+ }
+
template <bool UNSAFE>
void WriteBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr,
const void* src_buffer, const std::size_t size) {
@@ -559,7 +575,7 @@ struct Memory::Impl {
}
}
- const Common::ProcessAddress end = base + size;
+ const auto end = base + size;
ASSERT_MSG(end <= page_table.pointers.size(), "out of range mapping at {:016X}",
base + page_table.pointers.size());
@@ -570,14 +586,18 @@ struct Memory::Impl {
while (base != end) {
page_table.pointers[base].Store(nullptr, type);
page_table.backing_addr[base] = 0;
-
+ page_table.blocks[base] = 0;
base += 1;
}
} else {
+ auto orig_base = base;
while (base != end) {
- page_table.pointers[base].Store(
- system.DeviceMemory().GetPointer<u8>(target) - (base << YUZU_PAGEBITS), type);
- page_table.backing_addr[base] = GetInteger(target) - (base << YUZU_PAGEBITS);
+ auto host_ptr =
+ system.DeviceMemory().GetPointer<u8>(target) - (base << YUZU_PAGEBITS);
+ auto backing = GetInteger(target) - (base << YUZU_PAGEBITS);
+ page_table.pointers[base].Store(host_ptr, type);
+ page_table.backing_addr[base] = backing;
+ page_table.blocks[base] = orig_base << YUZU_PAGEBITS;
ASSERT_MSG(page_table.pointers[base].Pointer(),
"memory mapping base yield a nullptr within the table");
@@ -747,6 +767,14 @@ struct Memory::Impl {
VAddr last_address;
};
+ void InvalidateRegion(Common::ProcessAddress dest_addr, size_t size) {
+ system.GPU().InvalidateRegion(GetInteger(dest_addr), size);
+ }
+
+ void FlushRegion(Common::ProcessAddress dest_addr, size_t size) {
+ system.GPU().FlushRegion(GetInteger(dest_addr), size);
+ }
+
Core::System& system;
Common::PageTable* current_page_table = nullptr;
std::array<VideoCore::RasterizerDownloadArea, Core::Hardware::NUM_CPU_CORES>
@@ -780,7 +808,7 @@ void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress b
bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const {
const Kernel::KProcess& process = *system.ApplicationProcess();
- const auto& page_table = process.PageTable().PageTableImpl();
+ const auto& page_table = process.GetPageTable().PageTableImpl();
const size_t page = vaddr >> YUZU_PAGEBITS;
if (page >= page_table.pointers.size()) {
return false;
@@ -881,6 +909,14 @@ void Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_b
impl->ReadBlockUnsafe(src_addr, dest_buffer, size);
}
+const u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) const {
+ return impl->GetSpan(src_addr, size);
+}
+
+u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) {
+ return impl->GetSpan(src_addr, 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);
@@ -924,4 +960,12 @@ void Memory::MarkRegionDebug(Common::ProcessAddress vaddr, u64 size, bool debug)
impl->MarkRegionDebug(GetInteger(vaddr), size, debug);
}
+void Memory::InvalidateRegion(Common::ProcessAddress dest_addr, size_t size) {
+ impl->InvalidateRegion(dest_addr, size);
+}
+
+void Memory::FlushRegion(Common::ProcessAddress dest_addr, size_t size) {
+ impl->FlushRegion(dest_addr, size);
+}
+
} // namespace Core::Memory