From d1441684420dc43edea6b07225d6ac79a13d07f4 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Fri, 14 Jul 2023 22:19:59 -0400
Subject: [PATCH] memory: minimize dependency on process

---
 src/core/memory.cpp | 115 ++++++++++++++++++++++----------------------
 src/core/memory.h   |  13 +++--
 2 files changed, 63 insertions(+), 65 deletions(-)

diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index e1fbe8e00a..179685b722 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -183,13 +183,13 @@ struct Memory::Impl {
         return string;
     }
 
-    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.GetPageTable().PageTableImpl();
+    bool WalkBlock(const Common::ProcessAddress addr, const std::size_t size, auto on_unmapped,
+                   auto on_memory, auto on_rasterizer, auto increment) {
+        const auto& page_table = system.ApplicationProcess()->GetPageTable().PageTableImpl();
         std::size_t remaining_size = size;
         std::size_t page_index = addr >> YUZU_PAGEBITS;
         std::size_t page_offset = addr & YUZU_PAGEMASK;
+        bool user_accessible = true;
 
         while (remaining_size) {
             const std::size_t copy_amount =
@@ -200,6 +200,7 @@ struct Memory::Impl {
             const auto [pointer, type] = page_table.pointers[page_index].PointerType();
             switch (type) {
             case Common::PageType::Unmapped: {
+                user_accessible = false;
                 on_unmapped(copy_amount, current_vaddr);
                 break;
             }
@@ -227,13 +228,15 @@ struct Memory::Impl {
             increment(copy_amount);
             remaining_size -= copy_amount;
         }
+
+        return user_accessible;
     }
 
     template <bool UNSAFE>
-    void ReadBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress src_addr,
-                       void* dest_buffer, const std::size_t size) {
-        WalkBlock(
-            process, src_addr, size,
+    bool ReadBlockImpl(const Common::ProcessAddress src_addr, void* dest_buffer,
+                       const std::size_t size) {
+        return WalkBlock(
+            src_addr, size,
             [src_addr, size, &dest_buffer](const std::size_t copy_amount,
                                            const Common::ProcessAddress current_vaddr) {
                 LOG_ERROR(HW_Memory,
@@ -256,14 +259,14 @@ struct Memory::Impl {
             });
     }
 
-    void ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
+    bool ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
                    const std::size_t size) {
-        ReadBlockImpl<false>(*system.ApplicationProcess(), src_addr, dest_buffer, size);
+        return ReadBlockImpl<false>(src_addr, dest_buffer, size);
     }
 
-    void ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
+    bool ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
                          const std::size_t size) {
-        ReadBlockImpl<true>(*system.ApplicationProcess(), src_addr, dest_buffer, size);
+        return ReadBlockImpl<true>(src_addr, dest_buffer, size);
     }
 
     const u8* GetSpan(const VAddr src_addr, const std::size_t size) const {
@@ -283,10 +286,10 @@ struct Memory::Impl {
     }
 
     template <bool UNSAFE>
-    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,
+    bool WriteBlockImpl(const Common::ProcessAddress dest_addr, const void* src_buffer,
+                        const std::size_t size) {
+        return WalkBlock(
+            dest_addr, size,
             [dest_addr, size](const std::size_t copy_amount,
                               const Common::ProcessAddress current_vaddr) {
                 LOG_ERROR(HW_Memory,
@@ -308,20 +311,19 @@ struct Memory::Impl {
             });
     }
 
-    void WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
+    bool WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
                     const std::size_t size) {
-        WriteBlockImpl<false>(*system.ApplicationProcess(), dest_addr, src_buffer, size);
+        return WriteBlockImpl<false>(dest_addr, src_buffer, size);
     }
 
-    void WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
+    bool WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
                           const std::size_t size) {
-        WriteBlockImpl<true>(*system.ApplicationProcess(), dest_addr, src_buffer, size);
+        return WriteBlockImpl<true>(dest_addr, src_buffer, size);
     }
 
-    void ZeroBlock(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr,
-                   const std::size_t size) {
-        WalkBlock(
-            process, dest_addr, size,
+    bool ZeroBlock(const Common::ProcessAddress dest_addr, const std::size_t size) {
+        return WalkBlock(
+            dest_addr, size,
             [dest_addr, size](const std::size_t copy_amount,
                               const Common::ProcessAddress current_vaddr) {
                 LOG_ERROR(HW_Memory,
@@ -339,23 +341,23 @@ struct Memory::Impl {
             [](const std::size_t copy_amount) {});
     }
 
-    void CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
-                   Common::ProcessAddress src_addr, const std::size_t size) {
-        WalkBlock(
-            process, dest_addr, size,
+    bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
+                   const std::size_t size) {
+        return WalkBlock(
+            dest_addr, size,
             [&](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) {
                 LOG_ERROR(HW_Memory,
                           "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
                           GetInteger(current_vaddr), GetInteger(src_addr), size);
-                ZeroBlock(process, dest_addr, copy_amount);
+                ZeroBlock(dest_addr, copy_amount);
             },
             [&](const std::size_t copy_amount, const u8* const src_ptr) {
-                WriteBlockImpl<false>(process, dest_addr, src_ptr, copy_amount);
+                WriteBlockImpl<false>(dest_addr, src_ptr, copy_amount);
             },
             [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
                 u8* const host_ptr) {
                 HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount);
-                WriteBlockImpl<false>(process, dest_addr, host_ptr, copy_amount);
+                WriteBlockImpl<false>(dest_addr, host_ptr, copy_amount);
             },
             [&](const std::size_t copy_amount) {
                 dest_addr += copy_amount;
@@ -364,13 +366,13 @@ struct Memory::Impl {
     }
 
     template <typename Callback>
-    Result PerformCacheOperation(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
-                                 std::size_t size, Callback&& cb) {
+    Result PerformCacheOperation(Common::ProcessAddress dest_addr, std::size_t size,
+                                 Callback&& cb) {
         class InvalidMemoryException : public std::exception {};
 
         try {
             WalkBlock(
-                process, dest_addr, size,
+                dest_addr, size,
                 [&](const std::size_t block_size, const Common::ProcessAddress current_vaddr) {
                     LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}",
                               GetInteger(current_vaddr));
@@ -387,37 +389,34 @@ struct Memory::Impl {
         return ResultSuccess;
     }
 
-    Result InvalidateDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
-                               std::size_t size) {
+    Result InvalidateDataCache(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
             HandleRasterizerDownload(GetInteger(current_vaddr), block_size);
         };
-        return PerformCacheOperation(process, dest_addr, size, on_rasterizer);
+        return PerformCacheOperation(dest_addr, size, on_rasterizer);
     }
 
-    Result StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
-                          std::size_t size) {
+    Result StoreDataCache(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(GetInteger(current_vaddr), block_size);
         };
-        return PerformCacheOperation(process, dest_addr, size, on_rasterizer);
+        return PerformCacheOperation(dest_addr, size, on_rasterizer);
     }
 
-    Result FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr,
-                          std::size_t size) {
+    Result FlushDataCache(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(GetInteger(current_vaddr), block_size);
         };
-        return PerformCacheOperation(process, dest_addr, size, on_rasterizer);
+        return PerformCacheOperation(dest_addr, size, on_rasterizer);
     }
 
     void MarkRegionDebug(u64 vaddr, u64 size, bool debug) {
@@ -899,14 +898,14 @@ std::string Memory::ReadCString(Common::ProcessAddress vaddr, std::size_t max_le
     return impl->ReadCString(vaddr, max_length);
 }
 
-void Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
+bool Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
                        const std::size_t size) {
-    impl->ReadBlock(src_addr, dest_buffer, size);
+    return impl->ReadBlock(src_addr, dest_buffer, size);
 }
 
-void Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
+bool Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
                              const std::size_t size) {
-    impl->ReadBlockUnsafe(src_addr, dest_buffer, size);
+    return impl->ReadBlockUnsafe(src_addr, dest_buffer, size);
 }
 
 const u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) const {
@@ -917,23 +916,23 @@ 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,
+bool Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
                         const std::size_t size) {
-    impl->WriteBlock(dest_addr, src_buffer, size);
+    return impl->WriteBlock(dest_addr, src_buffer, size);
 }
 
-void Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
+bool Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
                               const std::size_t size) {
-    impl->WriteBlockUnsafe(dest_addr, src_buffer, size);
+    return impl->WriteBlockUnsafe(dest_addr, src_buffer, size);
 }
 
-void Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
+bool Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
                        const std::size_t size) {
-    impl->CopyBlock(*system.ApplicationProcess(), dest_addr, src_addr, size);
+    return impl->CopyBlock(dest_addr, src_addr, size);
 }
 
-void Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) {
-    impl->ZeroBlock(*system.ApplicationProcess(), dest_addr, size);
+bool Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) {
+    return impl->ZeroBlock(dest_addr, size);
 }
 
 void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers) {
@@ -941,15 +940,15 @@ void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers
 }
 
 Result Memory::InvalidateDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
-    return impl->InvalidateDataCache(*system.ApplicationProcess(), dest_addr, size);
+    return impl->InvalidateDataCache(dest_addr, size);
 }
 
 Result Memory::StoreDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
-    return impl->StoreDataCache(*system.ApplicationProcess(), dest_addr, size);
+    return impl->StoreDataCache(dest_addr, size);
 }
 
 Result Memory::FlushDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
-    return impl->FlushDataCache(*system.ApplicationProcess(), dest_addr, size);
+    return impl->FlushDataCache(dest_addr, size);
 }
 
 void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) {
diff --git a/src/core/memory.h b/src/core/memory.h
index ea33c769cf..2eb61ffd34 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -24,7 +24,6 @@ class GPUDirtyMemoryManager;
 } // namespace Core
 
 namespace Kernel {
-class PhysicalMemory;
 class KProcess;
 } // namespace Kernel
 
@@ -330,7 +329,7 @@ public:
      * @post The range [dest_buffer, size) contains the read bytes from the
      *       current process' address space.
      */
-    void ReadBlock(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
+    bool ReadBlock(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
 
     /**
      * Reads a contiguous block of bytes from the current process' address space.
@@ -349,7 +348,7 @@ public:
      * @post The range [dest_buffer, size) contains the read bytes from the
      *       current process' address space.
      */
-    void ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
+    bool ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
 
     const u8* GetSpan(const VAddr src_addr, const std::size_t size) const;
     u8* GetSpan(const VAddr src_addr, const std::size_t size);
@@ -373,7 +372,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(Common::ProcessAddress dest_addr, const void* src_buffer, std::size_t size);
+    bool 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
@@ -391,7 +390,7 @@ public:
      *       will be ignored and an error will be logged.
      *
      */
-    void WriteBlockUnsafe(Common::ProcessAddress dest_addr, const void* src_buffer,
+    bool WriteBlockUnsafe(Common::ProcessAddress dest_addr, const void* src_buffer,
                           std::size_t size);
 
     /**
@@ -405,7 +404,7 @@ public:
      * @post The range [dest_addr, size) within the process' address space contains the
      *       same data within the range [src_addr, size).
      */
-    void CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
+    bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
                    std::size_t size);
 
     /**
@@ -418,7 +417,7 @@ public:
      * @post The range [dest_addr, size) within the process' address space contains the
      *       value 0.
      */
-    void ZeroBlock(Common::ProcessAddress dest_addr, std::size_t size);
+    bool ZeroBlock(Common::ProcessAddress dest_addr, std::size_t size);
 
     /**
      * Invalidates a range of bytes within the current process' address space at the specified