Add sceKernelGetDirectMemoryType and update sceKernelReserveVirtualRange to search for free region when virtual_addr==0
This commit is contained in:
parent
36d528743a
commit
f556f85279
|
@ -375,6 +375,7 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
|
||||||
sceKernelCheckedReleaseDirectMemory);
|
sceKernelCheckedReleaseDirectMemory);
|
||||||
LIB_FUNCTION("rVjRvHJ0X6c", "libkernel", 1, "libkernel", 1, 1, sceKernelVirtualQuery);
|
LIB_FUNCTION("rVjRvHJ0X6c", "libkernel", 1, "libkernel", 1, 1, sceKernelVirtualQuery);
|
||||||
LIB_FUNCTION("7oxv3PPCumo", "libkernel", 1, "libkernel", 1, 1, sceKernelReserveVirtualRange);
|
LIB_FUNCTION("7oxv3PPCumo", "libkernel", 1, "libkernel", 1, 1, sceKernelReserveVirtualRange);
|
||||||
|
LIB_FUNCTION("BC+OG5m9+bw", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemoryType);
|
||||||
LIB_FUNCTION("pO96TwzOm5E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemorySize);
|
LIB_FUNCTION("pO96TwzOm5E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemorySize);
|
||||||
LIB_FUNCTION("NcaWUxfMNIQ", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedDirectMemory);
|
LIB_FUNCTION("NcaWUxfMNIQ", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedDirectMemory);
|
||||||
LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory);
|
LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory);
|
||||||
|
|
|
@ -211,4 +211,12 @@ void PS4_SYSV_ABI _sceKernelRtldSetApplicationHeapAPI(void* func) {
|
||||||
linker->SetHeapApiFunc(func);
|
linker->SetHeapApiFunc(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceKernelGetDirectMemoryType(u64 addr, int* directMemoryTypeOut,
|
||||||
|
void** directMemoryStartOut,
|
||||||
|
void** directMemoryEndOut) {
|
||||||
|
LOG_WARNING(Kernel_Vmm, "called, direct memory addr = {:#x}", addr);
|
||||||
|
auto* memory = Core::Memory::Instance();
|
||||||
|
return memory->GetDirectMemoryType(addr, directMemoryTypeOut, directMemoryStartOut, directMemoryEndOut);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
} // namespace Libraries::Kernel
|
||||||
|
|
|
@ -81,5 +81,8 @@ int PS4_SYSV_ABI sceKernelDirectMemoryQuery(u64 offset, int flags, OrbisQueryInf
|
||||||
size_t infoSize);
|
size_t infoSize);
|
||||||
s32 PS4_SYSV_ABI sceKernelAvailableFlexibleMemorySize(size_t* sizeOut);
|
s32 PS4_SYSV_ABI sceKernelAvailableFlexibleMemorySize(size_t* sizeOut);
|
||||||
void PS4_SYSV_ABI _sceKernelRtldSetApplicationHeapAPI(void* func);
|
void PS4_SYSV_ABI _sceKernelRtldSetApplicationHeapAPI(void* func);
|
||||||
|
int PS4_SYSV_ABI sceKernelGetDirectMemoryType(u64 addr, int* directMemoryTypeOut,
|
||||||
|
void** directMemoryStartOut,
|
||||||
|
void** directMemoryEndOut);
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
} // namespace Libraries::Kernel
|
||||||
|
|
|
@ -87,10 +87,27 @@ int MemoryManager::Reserve(void** out_addr, VAddr virtual_addr, size_t size, Mem
|
||||||
u64 alignment) {
|
u64 alignment) {
|
||||||
std::scoped_lock lk{mutex};
|
std::scoped_lock lk{mutex};
|
||||||
|
|
||||||
ASSERT_MSG(virtual_addr != 0, "TODO: Reserve address is zero - search for free space");
|
virtual_addr = (virtual_addr == 0) ? impl.VirtualBase() : virtual_addr;
|
||||||
|
alignment = alignment > 0 ? alignment : 16_KB;
|
||||||
VAddr mapped_addr = alignment > 0 ? Common::AlignUp(virtual_addr, alignment) : virtual_addr;
|
VAddr mapped_addr = alignment > 0 ? Common::AlignUp(virtual_addr, alignment) : virtual_addr;
|
||||||
|
|
||||||
|
// Find the first free area starting with provided virtual address.
|
||||||
|
if (False(flags & MemoryMapFlags::Fixed)) {
|
||||||
|
auto it = FindVMA(mapped_addr);
|
||||||
|
// If the VMA is free and contains the requested mapping we are done.
|
||||||
|
if (it->second.type == VMAType::Free && it->second.Contains(virtual_addr, size)) {
|
||||||
|
mapped_addr = virtual_addr;
|
||||||
|
} else {
|
||||||
|
// Search for the first free VMA that fits our mapping.
|
||||||
|
while (it->second.type != VMAType::Free || it->second.size < size) {
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
ASSERT(it != vma_map.end());
|
||||||
|
const auto& vma = it->second;
|
||||||
|
mapped_addr = alignment > 0 ? Common::AlignUp(vma.base, alignment) : vma.base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add virtual memory area
|
// Add virtual memory area
|
||||||
auto& new_vma = AddMapping(mapped_addr, size);
|
auto& new_vma = AddMapping(mapped_addr, size);
|
||||||
new_vma.disallow_merge = True(flags & MemoryMapFlags::NoCoalesce);
|
new_vma.disallow_merge = True(flags & MemoryMapFlags::NoCoalesce);
|
||||||
|
@ -489,4 +506,22 @@ void MemoryManager::UnmapVulkanMemory(VAddr addr, size_t size) {
|
||||||
mapped_memories.erase(it);
|
mapped_memories.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MemoryManager::GetDirectMemoryType(PAddr addr, int* directMemoryTypeOut, void** directMemoryStartOut,
|
||||||
|
void** directMemoryEndOut) {
|
||||||
|
std::scoped_lock lk{mutex};
|
||||||
|
|
||||||
|
auto dmem_area = FindDmemArea(addr);
|
||||||
|
|
||||||
|
if (dmem_area == dmem_map.end() || dmem_area->second.is_free) {
|
||||||
|
LOG_ERROR(Core, "Unable to find allocated direct memory region to check type!");
|
||||||
|
return ORBIS_KERNEL_ERROR_ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& area = dmem_area->second;
|
||||||
|
*directMemoryStartOut = reinterpret_cast<void*>(area.base);
|
||||||
|
*directMemoryEndOut = reinterpret_cast<void*>(area.GetEnd());
|
||||||
|
*directMemoryTypeOut = area.memory_type;
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
|
@ -160,6 +160,9 @@ public:
|
||||||
|
|
||||||
std::pair<vk::Buffer, size_t> GetVulkanBuffer(VAddr addr);
|
std::pair<vk::Buffer, size_t> GetVulkanBuffer(VAddr addr);
|
||||||
|
|
||||||
|
int GetDirectMemoryType(PAddr addr, int* directMemoryTypeOut, void** directMemoryStartOut,
|
||||||
|
void** directMemoryEndOut);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VMAHandle FindVMA(VAddr target) {
|
VMAHandle FindVMA(VAddr target) {
|
||||||
return std::prev(vma_map.upper_bound(target));
|
return std::prev(vma_map.upper_bound(target));
|
||||||
|
|
Loading…
Reference in New Issue