diff --git a/app/src/main/cpp/skyline/common/address_space.h b/app/src/main/cpp/skyline/common/address_space.h index 5d00787a..e3f1965c 100644 --- a/app/src/main/cpp/skyline/common/address_space.h +++ b/app/src/main/cpp/skyline/common/address_space.h @@ -116,19 +116,19 @@ namespace skyline { /** * @return A vector of all physical ranges inside of the given virtual range */ - std::vector> TranslateRange(VaType virt, VaType size); + std::vector> TranslateRange(VaType virt, VaType size, std::function)> cpuAccessCallback = {}); - void Read(u8 *destination, VaType virt, VaType size); + void Read(u8 *destination, VaType virt, VaType size, std::function)> cpuAccessCallback = {}); template - void Read(span destination, VaType virt) { - Read(reinterpret_cast(destination.data()), virt, destination.size_bytes()); + void Read(span destination, VaType virt, std::function)> cpuAccessCallback = {}) { + Read(reinterpret_cast(destination.data()), virt, destination.size_bytes(), cpuAccessCallback); } template - T Read(VaType virt) { + T Read(VaType virt, std::function)> cpuAccessCallback = {}) { T obj; - Read(reinterpret_cast(&obj), virt, sizeof(T)); + Read(reinterpret_cast(&obj), virt, sizeof(T), cpuAccessCallback); return obj; } @@ -140,7 +140,7 @@ namespace skyline { * @note The function will provide no feedback on if the end has been reached or if there was an early exit */ template - span ReadTill(Container& destination, VaType virt, Function function) { + span ReadTill(Container& destination, VaType virt, Function function, std::function)> cpuAccessCallback = {}) { //TRACE_EVENT("containers", "FlatMemoryManager::ReadTill"); std::scoped_lock lock(this->blockMutex); @@ -164,7 +164,11 @@ namespace skyline { if (predecessor->extraInfo.sparseMapped) { std::memset(pointer, 0, blockReadSize); } else { - auto end{function(span(blockPhys, blockReadSize))}; + span cpuBlock{blockPhys, blockReadSize}; + if (cpuAccessCallback) + cpuAccessCallback(cpuBlock); + + auto end{function(cpuBlock)}; std::memcpy(pointer, blockPhys, end ? *end : blockReadSize); if (end) return {destination.data(), (destination.size() - remainingSize) + *end}; @@ -184,18 +188,18 @@ namespace skyline { return {destination.data(), destination.size()}; } - void Write(VaType virt, u8 *source, VaType size); + void Write(VaType virt, u8 *source, VaType size, std::function)> cpuAccessCallback = {}); template - void Write(VaType virt, span source) { + void Write(VaType virt, span source, std::function)> cpuAccessCallback = {}) { Write(virt, reinterpret_cast(source.data()), source.size_bytes()); } - void Write(VaType virt, util::TrivialObject auto source) { - Write(virt, reinterpret_cast(&source), sizeof(source)); + void Write(VaType virt, util::TrivialObject auto source, std::function)> cpuAccessCallback = {}) { + Write(virt, reinterpret_cast(&source), sizeof(source), cpuAccessCallback); } - void Copy(VaType dst, VaType src, VaType size); + void Copy(VaType dst, VaType src, VaType size, std::function)> cpuAccessCallback = {}); }; /** diff --git a/app/src/main/cpp/skyline/common/address_space.inc b/app/src/main/cpp/skyline/common/address_space.inc index 5a3fe598..bec53a73 100644 --- a/app/src/main/cpp/skyline/common/address_space.inc +++ b/app/src/main/cpp/skyline/common/address_space.inc @@ -233,7 +233,7 @@ namespace skyline { munmap(sparseMap, SparseMapSize); } - MM_MEMBER(std::vector>)::TranslateRange(VaType virt, VaType size) { + MM_MEMBER(std::vector>)::TranslateRange(VaType virt, VaType size, std::function)> cpuAccessCallback) { TRACE_EVENT("containers", "FlatMemoryManager::TranslateRange"); std::scoped_lock lock(this->blockMutex); @@ -258,7 +258,11 @@ namespace skyline { blockPhys = sparseMap; } - ranges.push_back(span(blockPhys, blockSize)); + span cpuBlock{blockPhys, blockSize}; + if (cpuAccessCallback) + cpuAccessCallback(cpuBlock); + + ranges.push_back(cpuBlock); size -= blockSize; @@ -272,7 +276,7 @@ namespace skyline { return ranges; } - MM_MEMBER(void)::Read(u8 *destination, VaType virt, VaType size) { + MM_MEMBER(void)::Read(u8 *destination, VaType virt, VaType size, std::function)> cpuAccessCallback) { TRACE_EVENT("containers", "FlatMemoryManager::Read"); std::scoped_lock lock(this->blockMutex); @@ -291,10 +295,14 @@ namespace skyline { if (predecessor->phys == nullptr) { throw exception("Page fault at 0x{:X}", predecessor->virt); } else { - if (predecessor->extraInfo.sparseMapped) // Sparse mappings read all zeroes + if (predecessor->extraInfo.sparseMapped) { // Sparse mappings read all zeroes std::memset(destination, 0, blockReadSize); - else + } else { + if (cpuAccessCallback) + cpuAccessCallback(span{blockPhys, blockReadSize}); + std::memcpy(destination, blockPhys, blockReadSize); + } } destination += blockReadSize; @@ -308,7 +316,7 @@ namespace skyline { } } - MM_MEMBER(void)::Write(VaType virt, u8 *source, VaType size) { + MM_MEMBER(void)::Write(VaType virt, u8 *source, VaType size, std::function)> cpuAccessCallback) { TRACE_EVENT("containers", "FlatMemoryManager::Write"); std::scoped_lock lock(this->blockMutex); @@ -329,8 +337,12 @@ namespace skyline { if (predecessor->phys == nullptr) { throw exception("Page fault at 0x{:X}", predecessor->virt); } else { - if (!predecessor->extraInfo.sparseMapped) // Sparse mappings ignore writes + if (!predecessor->extraInfo.sparseMapped) { // Sparse mappings ignore writes + if (cpuAccessCallback) + cpuAccessCallback(span{blockPhys, blockWriteSize}); + std::memcpy(blockPhys, source, blockWriteSize); + } } source += blockWriteSize; @@ -344,7 +356,7 @@ namespace skyline { } } - MM_MEMBER(void)::Copy(VaType dst, VaType src, VaType size) { + MM_MEMBER(void)::Copy(VaType dst, VaType src, VaType size, std::function)> cpuAccessCallback) { TRACE_EVENT("containers", "FlatMemoryManager::Copy"); std::scoped_lock lock(this->blockMutex); @@ -378,10 +390,16 @@ namespace skyline { } else if (dstPredecessor->phys == nullptr) { throw exception("Page fault at 0x{:X}", dstPredecessor->virt); } else { [[likely]] - if (srcPredecessor->extraInfo.sparseMapped) + if (srcPredecessor->extraInfo.sparseMapped) { std::memset(dstBlockPhys, 0, blockCopySize); - else [[likely]] + } else [[likely]] { + if (cpuAccessCallback) { + cpuAccessCallback(span{dstBlockPhys, blockCopySize}); + cpuAccessCallback(span{srcBlockPhys, blockCopySize}); + } + std::memcpy(dstBlockPhys, srcBlockPhys, blockCopySize); + } } dstBlockPhys += blockCopySize;