mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-08 20:58:41 +00:00
Memory: Implement sceKernelMemoryPoolGetBlockStats (#3646)
* Implement sceKernelMemoryPoolGetBlockStats Not entirely sure on the logic behind the cached blocks work, but flushed blocks seems to just be based on committed direct memory. * Fix comment
This commit is contained in:
@@ -555,6 +555,23 @@ s32 PS4_SYSV_ABI sceKernelMemoryPoolBatch(const OrbisKernelMemoryPoolBatchEntry*
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceKernelMemoryPoolGetBlockStats(OrbisKernelMemoryPoolBlockStats* stats,
|
||||
u64 size) {
|
||||
LOG_WARNING(Kernel_Vmm, "called");
|
||||
auto* memory = Core::Memory::Instance();
|
||||
OrbisKernelMemoryPoolBlockStats local_stats;
|
||||
memory->GetMemoryPoolStats(&local_stats);
|
||||
|
||||
u64 size_to_copy = size < sizeof(OrbisKernelMemoryPoolBlockStats)
|
||||
? size
|
||||
: sizeof(OrbisKernelMemoryPoolBlockStats);
|
||||
// As of firmware 12.02, the kernel does not check if stats is null,
|
||||
// this can cause crashes on real hardware, so have an assert for this case.
|
||||
ASSERT_MSG(stats != nullptr || size == 0, "Block stats cannot be null");
|
||||
std::memcpy(stats, &local_stats, size_to_copy);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
void* PS4_SYSV_ABI posix_mmap(void* addr, u64 len, s32 prot, s32 flags, s32 fd, s64 phys_addr) {
|
||||
LOG_INFO(
|
||||
Kernel_Vmm,
|
||||
@@ -715,6 +732,7 @@ void RegisterMemory(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("Vzl66WmfLvk", "libkernel", 1, "libkernel", sceKernelMemoryPoolCommit);
|
||||
LIB_FUNCTION("LXo1tpFqJGs", "libkernel", 1, "libkernel", sceKernelMemoryPoolDecommit);
|
||||
LIB_FUNCTION("YN878uKRBbE", "libkernel", 1, "libkernel", sceKernelMemoryPoolBatch);
|
||||
LIB_FUNCTION("bvD+95Q6asU", "libkernel", 1, "libkernel", sceKernelMemoryPoolGetBlockStats);
|
||||
|
||||
LIB_FUNCTION("BPE9s9vQQXo", "libkernel", 1, "libkernel", posix_mmap);
|
||||
LIB_FUNCTION("BPE9s9vQQXo", "libScePosix", 1, "libkernel", posix_mmap);
|
||||
|
||||
@@ -126,6 +126,13 @@ struct OrbisKernelMemoryPoolBatchEntry {
|
||||
};
|
||||
};
|
||||
|
||||
struct OrbisKernelMemoryPoolBlockStats {
|
||||
s32 available_flushed_blocks;
|
||||
s32 available_cached_blocks;
|
||||
s32 allocated_flushed_blocks;
|
||||
s32 allocated_cached_blocks;
|
||||
};
|
||||
|
||||
u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize();
|
||||
s32 PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u64 len,
|
||||
u64 alignment, s32 memoryType, s64* physAddrOut);
|
||||
@@ -176,6 +183,7 @@ s32 PS4_SYSV_ABI sceKernelMemoryPoolCommit(void* addr, u64 len, s32 type, s32 pr
|
||||
s32 PS4_SYSV_ABI sceKernelMemoryPoolDecommit(void* addr, u64 len, s32 flags);
|
||||
s32 PS4_SYSV_ABI sceKernelMemoryPoolBatch(const OrbisKernelMemoryPoolBatchEntry* entries, s32 count,
|
||||
s32* num_processed, s32 flags);
|
||||
s32 PS4_SYSV_ABI sceKernelMemoryPoolGetBlockStats(OrbisKernelMemoryPoolBlockStats* stats, u64 size);
|
||||
|
||||
s32 PS4_SYSV_ABI sceKernelMunmap(void* addr, u64 len);
|
||||
|
||||
|
||||
@@ -979,6 +979,27 @@ s32 MemoryManager::IsStack(VAddr addr, void** start, void** end) {
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 MemoryManager::GetMemoryPoolStats(::Libraries::Kernel::OrbisKernelMemoryPoolBlockStats* stats) {
|
||||
// Run through dmem_map, determine how much physical memory is currently committed
|
||||
constexpr u64 block_size = 64_KB;
|
||||
u64 committed_size = 0;
|
||||
|
||||
auto dma_handle = dmem_map.begin();
|
||||
while (dma_handle != dmem_map.end()) {
|
||||
if (dma_handle->second.dma_type == DMAType::Committed) {
|
||||
committed_size += dma_handle->second.size;
|
||||
}
|
||||
dma_handle++;
|
||||
}
|
||||
|
||||
stats->allocated_flushed_blocks = committed_size / block_size;
|
||||
stats->available_flushed_blocks = committed_size / block_size;
|
||||
// TODO: Determine how "cached blocks" work
|
||||
stats->allocated_cached_blocks = 0;
|
||||
stats->available_cached_blocks = 0;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
void MemoryManager::InvalidateMemory(const VAddr addr, const u64 size) const {
|
||||
if (rasterizer) {
|
||||
rasterizer->InvalidateMemory(addr, size);
|
||||
|
||||
@@ -258,6 +258,8 @@ public:
|
||||
|
||||
void NameVirtualRange(VAddr virtual_addr, u64 size, std::string_view name);
|
||||
|
||||
s32 GetMemoryPoolStats(::Libraries::Kernel::OrbisKernelMemoryPoolBlockStats* stats);
|
||||
|
||||
void InvalidateMemory(VAddr addr, u64 size) const;
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user