diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index ba4a063d55..64e197e3e3 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -1860,15 +1860,30 @@ bool ppu_load_exec(const ppu_exec_object& elf, bool virtual_load, const std::str else if (already_loaded) { } - else if (!vm::falloc(addr, size, vm::main)) + else if (![&]() -> bool { - ppu_loader.error("vm::falloc(vm::main) failed (addr=0x%x, memsz=0x%x)", addr, size); // TODO + // 1M pages if it is RSX shared + const u32 area_flags = (_seg.flags >> 28) ? vm::page_size_1m : vm::page_size_64k; + const u32 alloc_at = std::max(addr & -0x10000000, 0x10000); - if (!vm::falloc(addr, size)) + const auto area = vm::reserve_map(vm::any, std::max(addr & -0x10000000, 0x10000), 0x10000000, area_flags); + + if (!area) { - ppu_loader.error("ppu_load_exec(): vm::falloc() failed (addr=0x%x, memsz=0x%x)", addr, size); return false; } + + if (area->addr != alloc_at || (area->flags & 0xf00) != area_flags) + { + ppu_loader.error("Failed to allocate memory at 0x%x - conflicting memory area exists: area->addr=0x%x, area->flags=0x%x", addr, area->addr, area->flags); + return false; + } + + return area->falloc(addr, size); + }()) + { + ppu_loader.error("ppu_load_exec(): vm::falloc() failed (addr=0x%x, memsz=0x%x)", addr, size); + return false; } // Store only LOAD segments (TODO) diff --git a/rpcs3/Emu/Cell/lv2/sys_memory.cpp b/rpcs3/Emu/Cell/lv2/sys_memory.cpp index 067902d60c..d8b9ff6823 100644 --- a/rpcs3/Emu/Cell/lv2/sys_memory.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_memory.cpp @@ -85,6 +85,12 @@ struct sys_memory_address_table } }; +std::shared_ptr reserve_map(u32 alloc_size, u32 align) +{ + return vm::reserve_map(align == 0x10000 ? vm::user64k : vm::user1m, 0, align == 0x10000 ? 0x20000000 : utils::align(alloc_size, 0x10000000) + , align == 0x10000 ? (vm::page_size_64k | vm::bf0_0x1) : (vm::page_size_1m | vm::bf0_0x1)); +} + // Todo: fix order of error checks error_code sys_memory_allocate(cpu_thread& cpu, u32 size, u64 flags, vm::ptr alloc_addr) @@ -123,7 +129,7 @@ error_code sys_memory_allocate(cpu_thread& cpu, u32 size, u64 flags, vm::ptralloc(size, nullptr, align)) { @@ -197,7 +203,7 @@ error_code sys_memory_allocate_from_container(cpu_thread& cpu, u32 size, u32 cid return ct.ret; } - if (const auto area = vm::reserve_map(align == 0x10000 ? vm::user64k : vm::user1m, 0, utils::align(size, 0x10000000), 0x401)) + if (const auto area = reserve_map(size, align)) { if (const u32 addr = area->alloc(size)) { diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 28305052a1..79680c5c41 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -1803,12 +1803,12 @@ namespace vm { const u32 max = (0xC0000000 - size) & (0 - align); - if (size > 0xC0000000 - 0x20000000 || max < 0x20000000) + if (size > 0xC0000000 - 0x10000000 || max < 0x10000000) { return nullptr; } - for (u32 addr = utils::align(0x20000000, align);; addr += align) + for (u32 addr = utils::align(0x10000000, align);; addr += align) { if (_test_map(addr, size)) { @@ -2131,8 +2131,8 @@ namespace vm g_locations = { - std::make_shared(0x00010000, 0x1FFF0000, page_size_64k | preallocated), // main - std::make_shared(0x20000000, 0x10000000, page_size_64k | bf0_0x1), // user 64k pages + std::make_shared(0x00010000, 0x0FFF0000, page_size_64k | preallocated), // main + nullptr, // user 64k pages nullptr, // user 1m pages nullptr, // rsx context std::make_shared(0xC0000000, 0x10000000, page_size_64k | preallocated), // video