diff --git a/rpcs3/Emu/Cell/lv2/sys_vm.cpp b/rpcs3/Emu/Cell/lv2/sys_vm.cpp index 8c5ec0613c..61a10ad935 100644 --- a/rpcs3/Emu/Cell/lv2/sys_vm.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_vm.cpp @@ -1,43 +1,46 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/System.h" -#include "Emu/IdManager.h" - -#include "Emu/Cell/ErrorCodes.h" -#include "sys_memory.h" #include "sys_vm.h" +#include "sys_memory.h" + +namespace vm { using namespace ps3; } logs::channel sys_vm("sys_vm", logs::level::notice); -s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, vm::ptr addr) +ppu_error_code sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, vm::ptr addr) { sys_vm.error("sys_vm_memory_map(vsize=0x%x, psize=0x%x, cid=0x%x, flags=0x%llx, policy=0x%llx, addr=*0x%x)", vsize, psize, cid, flag, policy, addr); - LV2_LOCK; - - // Use fixed address (TODO: search and use some free address instead) - const u32 new_addr = vm::check_addr(0x60000000) ? 0x70000000 : 0x60000000; - - // Map memory - const auto area = vm::map(new_addr, vsize, flag); - - // Alloc memory - if (!area || !area->alloc(vsize)) + if (!vsize || !psize || vsize & 0x2000000 || vsize > 0x10000000 || psize > 0x10000000 || policy != SYS_VM_POLICY_AUTO_RECOMMENDED) { - return CELL_ENOMEM; + return CELL_EINVAL; } - // Write a pointer for the allocated memory. - *addr = new_addr; + if (cid != SYS_MEMORY_CONTAINER_ID_INVALID && !idm::check(cid)) + { + return CELL_ESRCH; + } - return CELL_OK; + // Look for unmapped space (roughly) + for (u32 found = 0x60000000; found <= 0xC0000000 - vsize; found += 0x2000000) + { + // Try to map + if (const auto area = vm::map(found, vsize, flag)) + { + // Alloc all memory (shall not fail) + VERIFY(area->alloc(vsize)); + + // Write a pointer for the allocated memory + *addr = found; + return CELL_OK; + } + } + + return CELL_ENOMEM; } -s32 sys_vm_unmap(u32 addr) +ppu_error_code sys_vm_unmap(u32 addr) { - sys_vm.error("sys_vm_unmap(addr=0x%x)", addr); - - LV2_LOCK; + sys_vm.warning("sys_vm_unmap(addr=0x%x)", addr); if (!vm::unmap(addr)) { @@ -47,81 +50,81 @@ s32 sys_vm_unmap(u32 addr) return CELL_OK; } -s32 sys_vm_append_memory(u32 addr, u32 size) +ppu_error_code sys_vm_append_memory(u32 addr, u32 size) { - sys_vm.todo("sys_vm_append_memory(addr=0x%x, size=0x%x)", addr, size); + sys_vm.warning("sys_vm_append_memory(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } -s32 sys_vm_return_memory(u32 addr, u32 size) +ppu_error_code sys_vm_return_memory(u32 addr, u32 size) { - sys_vm.todo("sys_vm_return_memory(addr=0x%x, size=0x%x)", addr, size); + sys_vm.warning("sys_vm_return_memory(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } -s32 sys_vm_lock(u32 addr, u32 size) +ppu_error_code sys_vm_lock(u32 addr, u32 size) { - sys_vm.todo("sys_vm_lock(addr=0x%x, size=0x%x)", addr, size); + sys_vm.warning("sys_vm_lock(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } -s32 sys_vm_unlock(u32 addr, u32 size) +ppu_error_code sys_vm_unlock(u32 addr, u32 size) { - sys_vm.todo("sys_vm_unlock(addr=0x%x, size=0x%x)", addr, size); + sys_vm.warning("sys_vm_unlock(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } -s32 sys_vm_touch(u32 addr, u32 size) +ppu_error_code sys_vm_touch(u32 addr, u32 size) { - sys_vm.todo("sys_vm_touch(addr=0x%x, size=0x%x)", addr, size); + sys_vm.warning("sys_vm_touch(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } -s32 sys_vm_flush(u32 addr, u32 size) +ppu_error_code sys_vm_flush(u32 addr, u32 size) { - sys_vm.todo("sys_vm_flush(addr=0x%x, size=0x%x)", addr, size); + sys_vm.warning("sys_vm_flush(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } -s32 sys_vm_invalidate(u32 addr, u32 size) +ppu_error_code sys_vm_invalidate(u32 addr, u32 size) { sys_vm.todo("sys_vm_invalidate(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } -s32 sys_vm_store(u32 addr, u32 size) +ppu_error_code sys_vm_store(u32 addr, u32 size) { - sys_vm.todo("sys_vm_store(addr=0x%x, size=0x%x)", addr, size); + sys_vm.warning("sys_vm_store(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } -s32 sys_vm_sync(u32 addr, u32 size) +ppu_error_code sys_vm_sync(u32 addr, u32 size) { - sys_vm.todo("sys_vm_sync(addr=0x%x, size=0x%x)", addr, size); + sys_vm.warning("sys_vm_sync(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } -s32 sys_vm_test(u32 addr, u32 size, vm::ptr result) +ppu_error_code sys_vm_test(u32 addr, u32 size, vm::ptr result) { - sys_vm.todo("sys_vm_test(addr=0x%x, size=0x%x, result=*0x%x)", addr, size, result); + sys_vm.warning("sys_vm_test(addr=0x%x, size=0x%x, result=*0x%x)", addr, size, result); *result = SYS_VM_STATE_ON_MEMORY; return CELL_OK; } -s32 sys_vm_get_statistics(u32 addr, vm::ptr stat) +ppu_error_code sys_vm_get_statistics(u32 addr, vm::ptr stat) { - sys_vm.todo("sys_vm_get_statistics(addr=0x%x, stat=*0x%x)", addr, stat); + sys_vm.warning("sys_vm_get_statistics(addr=0x%x, stat=*0x%x)", addr, stat); stat->page_fault_ppu = 0; stat->page_fault_spu = 0; diff --git a/rpcs3/Emu/Cell/lv2/sys_vm.h b/rpcs3/Emu/Cell/lv2/sys_vm.h index 5c03b588d1..84b2542b3c 100644 --- a/rpcs3/Emu/Cell/lv2/sys_vm.h +++ b/rpcs3/Emu/Cell/lv2/sys_vm.h @@ -1,6 +1,8 @@ #pragma once -#include "sys_sync.h" +#include "Emu/Memory/Memory.h" +#include "Emu/Cell/ErrorCodes.h" +#include "Emu/IdManager.h" enum : u64 { @@ -8,6 +10,8 @@ enum : u64 SYS_VM_STATE_UNUSED = 1ull, SYS_VM_STATE_ON_MEMORY = 2ull, SYS_VM_STATE_STORED = 4ull, + + SYS_VM_POLICY_AUTO_RECOMMENDED = 1ull, }; struct sys_vm_statistics_t @@ -22,16 +26,16 @@ struct sys_vm_statistics_t }; // SysCalls -s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, vm::ptr addr); -s32 sys_vm_unmap(u32 addr); -s32 sys_vm_append_memory(u32 addr, u32 size); -s32 sys_vm_return_memory(u32 addr, u32 size); -s32 sys_vm_lock(u32 addr, u32 size); -s32 sys_vm_unlock(u32 addr, u32 size); -s32 sys_vm_touch(u32 addr, u32 size); -s32 sys_vm_flush(u32 addr, u32 size); -s32 sys_vm_invalidate(u32 addr, u32 size); -s32 sys_vm_store(u32 addr, u32 size); -s32 sys_vm_sync(u32 addr, u32 size); -s32 sys_vm_test(u32 addr, u32 size, vm::ptr result); -s32 sys_vm_get_statistics(u32 addr, vm::ptr stat); +ppu_error_code sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, vm::ps3::ptr addr); +ppu_error_code sys_vm_unmap(u32 addr); +ppu_error_code sys_vm_append_memory(u32 addr, u32 size); +ppu_error_code sys_vm_return_memory(u32 addr, u32 size); +ppu_error_code sys_vm_lock(u32 addr, u32 size); +ppu_error_code sys_vm_unlock(u32 addr, u32 size); +ppu_error_code sys_vm_touch(u32 addr, u32 size); +ppu_error_code sys_vm_flush(u32 addr, u32 size); +ppu_error_code sys_vm_invalidate(u32 addr, u32 size); +ppu_error_code sys_vm_store(u32 addr, u32 size); +ppu_error_code sys_vm_sync(u32 addr, u32 size); +ppu_error_code sys_vm_test(u32 addr, u32 size, vm::ps3::ptr result); +ppu_error_code sys_vm_get_statistics(u32 addr, vm::ps3::ptr stat);