Merge pull request #312 from Borchev/main

Add sceKernelGetDirectMemoryType, update sceKernelReserveVirtualRange
This commit is contained in:
georgemoralis 2024-07-21 22:52:50 +03:00 committed by GitHub
commit 36ec7a1a43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 53 additions and 2 deletions

View File

@ -384,6 +384,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);

View File

@ -216,4 +216,13 @@ 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

View File

@ -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

View File

@ -96,10 +96,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);
@ -498,4 +515,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

View File

@ -166,6 +166,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));