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);
|
||||
LIB_FUNCTION("rVjRvHJ0X6c", "libkernel", 1, "libkernel", 1, 1, sceKernelVirtualQuery);
|
||||
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("NcaWUxfMNIQ", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedDirectMemory);
|
||||
LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory);
|
||||
|
|
|
@ -211,4 +211,12 @@ void PS4_SYSV_ABI _sceKernelRtldSetApplicationHeapAPI(void* 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
|
||||
|
|
|
@ -81,5 +81,8 @@ int PS4_SYSV_ABI sceKernelDirectMemoryQuery(u64 offset, int flags, OrbisQueryInf
|
|||
size_t infoSize);
|
||||
s32 PS4_SYSV_ABI sceKernelAvailableFlexibleMemorySize(size_t* sizeOut);
|
||||
void PS4_SYSV_ABI _sceKernelRtldSetApplicationHeapAPI(void* func);
|
||||
int PS4_SYSV_ABI sceKernelGetDirectMemoryType(u64 addr, int* directMemoryTypeOut,
|
||||
void** directMemoryStartOut,
|
||||
void** directMemoryEndOut);
|
||||
|
||||
} // namespace Libraries::Kernel
|
||||
|
|
|
@ -87,10 +87,27 @@ int MemoryManager::Reserve(void** out_addr, VAddr virtual_addr, size_t size, Mem
|
|||
u64 alignment) {
|
||||
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;
|
||||
|
||||
// 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
|
||||
auto& new_vma = AddMapping(mapped_addr, size);
|
||||
new_vma.disallow_merge = True(flags & MemoryMapFlags::NoCoalesce);
|
||||
|
@ -489,4 +506,22 @@ void MemoryManager::UnmapVulkanMemory(VAddr addr, size_t size) {
|
|||
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
|
||||
|
|
|
@ -160,6 +160,9 @@ public:
|
|||
|
||||
std::pair<vk::Buffer, size_t> GetVulkanBuffer(VAddr addr);
|
||||
|
||||
int GetDirectMemoryType(PAddr addr, int* directMemoryTypeOut, void** directMemoryStartOut,
|
||||
void** directMemoryEndOut);
|
||||
|
||||
private:
|
||||
VMAHandle FindVMA(VAddr target) {
|
||||
return std::prev(vma_map.upper_bound(target));
|
||||
|
|
Loading…
Reference in New Issue