From a43e7c172c724378187c9b78a3fb94f3bda5c4a3 Mon Sep 17 00:00:00 2001 From: eladash Date: Fri, 8 Mar 2019 11:21:02 +0200 Subject: [PATCH] Fix shared memory page flags TODO: From hw testing, it seems like sys_memory_get_page_attribute and sys_rsx_context_iomap check page size a little differently get_page_attribute() always go by area flags, sys_rsx_context_iomap checks page by the page granularity This means that if the area page size 64k, but shared memory is mapped with SYS_MEMORY_GRANULARITY_1M It can be mapped for rsxio, but the page attribute will indicate 64k page size :thonk: rsxio memory is verified to need 1m pages. --- rpcs3/Emu/Cell/lv2/sys_mmapper.cpp | 4 ++-- rpcs3/Emu/Memory/vm.cpp | 16 ++++++++++++++-- rpcs3/Emu/Memory/vm.h | 4 ++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp b/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp index bcd65c8cd2..5c91fbe4a4 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp @@ -309,7 +309,7 @@ error_code sys_mmapper_map_shared_memory(u32 addr, u32 mem_id, u64 flags) return mem.ret; } - if (!area->falloc(addr, mem->size, &mem->shm)) + if (!area->falloc(addr, mem->size, &mem->shm, mem->align == 0x10000 ? SYS_MEMORY_PAGE_SIZE_64K : SYS_MEMORY_PAGE_SIZE_1M)) { mem->counter--; return CELL_EBUSY; @@ -339,7 +339,7 @@ error_code sys_mmapper_search_and_map(u32 start_addr, u32 mem_id, u64 flags, vm: return CELL_ESRCH; } - const u32 addr = area->alloc(mem->size, mem->align, &mem->shm); + const u32 addr = area->alloc(mem->size, mem->align, &mem->shm, mem->align == 0x10000 ? SYS_MEMORY_PAGE_SIZE_64K : SYS_MEMORY_PAGE_SIZE_1M); if (!addr) { diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index f5835b81c0..8c6ac50612 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -665,8 +665,14 @@ namespace vm } } - u32 block_t::alloc(const u32 orig_size, u32 align, const std::shared_ptr* src) + u32 block_t::alloc(const u32 orig_size, u32 align, const std::shared_ptr* src, u64 flags) { + if (!src) + { + // Use the block's flags + flags = this->flags; + } + vm::writer_lock lock(0); // Determine minimal alignment @@ -720,8 +726,14 @@ namespace vm return 0; } - u32 block_t::falloc(u32 addr, const u32 orig_size, const std::shared_ptr* src) + u32 block_t::falloc(u32 addr, const u32 orig_size, const std::shared_ptr* src, u64 flags) { + if (!src) + { + // Use the block's flags + flags = this->flags; + } + vm::writer_lock lock(0); // Determine minimal alignment diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index 453a2e5d08..013512b476 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -161,10 +161,10 @@ namespace vm const u64 flags; // Currently unused // Search and map memory (min alignment is 0x10000) - u32 alloc(u32 size, u32 align = 0x10000, const std::shared_ptr* = nullptr); + u32 alloc(u32 size, u32 align = 0x10000, const std::shared_ptr* = nullptr, u64 flags = 0); // Try to map memory at fixed location - u32 falloc(u32 addr, u32 size, const std::shared_ptr* = nullptr); + u32 falloc(u32 addr, u32 size, const std::shared_ptr* = nullptr, u64 flags = 0); // Unmap memory at specified location previously returned by alloc(), return size u32 dealloc(u32 addr, const std::shared_ptr* = nullptr);