mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-27 04:25:12 +00:00
Fix sceKernelReserveVirtualRange
.
This commit is contained in:
parent
ff4584c14d
commit
7a83b74d3e
@ -107,9 +107,9 @@ s32 PS4_SYSV_ABI sceKernelReserveVirtualRange(void** addr, u64 len, int flags, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto* memory = Core::Memory::Instance();
|
auto* memory = Core::Memory::Instance();
|
||||||
|
const VAddr in_addr = reinterpret_cast<VAddr>(*addr);
|
||||||
const auto map_flags = static_cast<Core::MemoryMapFlags>(flags);
|
const auto map_flags = static_cast<Core::MemoryMapFlags>(flags);
|
||||||
memory->MapMemory(addr, 0, len, Core::MemoryProt::NoAccess, map_flags, Core::VMAType::Direct,
|
memory->Reserve(addr, in_addr, len, map_flags, alignment);
|
||||||
"", false, -1, alignment);
|
|
||||||
|
|
||||||
return SCE_OK;
|
return SCE_OK;
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,25 @@ void MemoryManager::Free(PAddr phys_addr, size_t size) {
|
|||||||
MergeAdjacent(dmem_map, dmem_area);
|
MergeAdjacent(dmem_map, dmem_area);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MemoryManager::Reserve(void** out_addr, VAddr virtual_addr, size_t size, MemoryMapFlags flags,
|
||||||
|
u64 alignment) {
|
||||||
|
std::scoped_lock lk{mutex};
|
||||||
|
|
||||||
|
virtual_addr = (virtual_addr == 0) ? impl.VirtualBase() : virtual_addr;
|
||||||
|
|
||||||
|
VAddr mapped_addr = alignment > 0 ? Common::AlignUp(virtual_addr, alignment) : virtual_addr;
|
||||||
|
|
||||||
|
// Add virtual memory area
|
||||||
|
auto& new_vma = AddMapping(mapped_addr, size);
|
||||||
|
new_vma.disallow_merge = True(flags & MemoryMapFlags::NoCoalesce);
|
||||||
|
new_vma.prot = MemoryProt::NoAccess;
|
||||||
|
new_vma.name = "";
|
||||||
|
new_vma.type = VMAType::Reserved;
|
||||||
|
|
||||||
|
*out_addr = std::bit_cast<void*>(mapped_addr);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot,
|
int MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot,
|
||||||
MemoryMapFlags flags, VMAType type, std::string_view name,
|
MemoryMapFlags flags, VMAType type, std::string_view name,
|
||||||
bool is_exec, PAddr phys_addr, u64 alignment) {
|
bool is_exec, PAddr phys_addr, u64 alignment) {
|
||||||
@ -146,18 +165,35 @@ int MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, size_t size, M
|
|||||||
|
|
||||||
int MemoryManager::MapFile(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot,
|
int MemoryManager::MapFile(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot,
|
||||||
MemoryMapFlags flags, uintptr_t fd, size_t offset) {
|
MemoryMapFlags flags, uintptr_t fd, size_t offset) {
|
||||||
virtual_addr = impl.VirtualBase();
|
if (virtual_addr == 0) {
|
||||||
|
virtual_addr = impl.VirtualBase();
|
||||||
|
} else {
|
||||||
|
LOG_INFO(Kernel_Vmm, "Virtual addr {:#x} with size {:#x}", virtual_addr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
VAddr mapped_addr = 0;
|
||||||
const size_t size_aligned = Common::AlignUp(size, 16_KB);
|
const size_t size_aligned = Common::AlignUp(size, 16_KB);
|
||||||
|
|
||||||
// Find first free area to map the file.
|
// Find first free area to map the file.
|
||||||
auto it = FindVMA(virtual_addr);
|
if (False(flags & MemoryMapFlags::Fixed)) {
|
||||||
while (it->second.type != VMAType::Free || it->second.size < size_aligned) {
|
auto it = FindVMA(virtual_addr);
|
||||||
it++;
|
while (it->second.type != VMAType::Free || it->second.size < size_aligned) {
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
ASSERT(it != vma_map.end());
|
||||||
|
|
||||||
|
mapped_addr = it->second.base;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (True(flags & MemoryMapFlags::Fixed)) {
|
||||||
|
const auto& vma = FindVMA(virtual_addr)->second;
|
||||||
|
const size_t remaining_size = vma.base + vma.size - virtual_addr;
|
||||||
|
ASSERT_MSG((vma.type == VMAType::Free || vma.type == VMAType::Reserved) && remaining_size >= size);
|
||||||
|
|
||||||
|
mapped_addr = virtual_addr;
|
||||||
}
|
}
|
||||||
ASSERT(it != vma_map.end());
|
|
||||||
|
|
||||||
// Map the file.
|
// Map the file.
|
||||||
const VAddr mapped_addr = it->second.base;
|
|
||||||
impl.MapFile(mapped_addr, size, offset, fd);
|
impl.MapFile(mapped_addr, size, offset, fd);
|
||||||
|
|
||||||
// Add virtual memory area
|
// Add virtual memory area
|
||||||
@ -302,7 +338,7 @@ VirtualMemoryArea& MemoryManager::AddMapping(VAddr virtual_addr, size_t size) {
|
|||||||
ASSERT_MSG(vma_handle != vma_map.end(), "Virtual address not in vm_map");
|
ASSERT_MSG(vma_handle != vma_map.end(), "Virtual address not in vm_map");
|
||||||
|
|
||||||
const VirtualMemoryArea& vma = vma_handle->second;
|
const VirtualMemoryArea& vma = vma_handle->second;
|
||||||
ASSERT_MSG(vma.type == VMAType::Free && vma.base <= virtual_addr,
|
ASSERT_MSG((vma.type == VMAType::Free || vma.type == VMAType::Reserved) && vma.base <= virtual_addr,
|
||||||
"Adding a mapping to already mapped region");
|
"Adding a mapping to already mapped region");
|
||||||
|
|
||||||
const VAddr start_in_vma = virtual_addr - vma.base;
|
const VAddr start_in_vma = virtual_addr - vma.base;
|
||||||
|
@ -137,6 +137,9 @@ public:
|
|||||||
|
|
||||||
void Free(PAddr phys_addr, size_t size);
|
void Free(PAddr phys_addr, size_t size);
|
||||||
|
|
||||||
|
int Reserve(void** out_addr, VAddr virtual_addr, size_t size, MemoryMapFlags flags,
|
||||||
|
u64 alignment = 0);
|
||||||
|
|
||||||
int MapMemory(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot,
|
int MapMemory(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot,
|
||||||
MemoryMapFlags flags, VMAType type, std::string_view name = "",
|
MemoryMapFlags flags, VMAType type, std::string_view name = "",
|
||||||
bool is_exec = false, PAddr phys_addr = -1, u64 alignment = 0);
|
bool is_exec = false, PAddr phys_addr = -1, u64 alignment = 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user