Implement sceKernelMapNamedSystemFlexibleMemory

Needed for libSceGnmDriver init
This commit is contained in:
Stephen Miller 2025-04-21 15:30:25 -05:00
parent f3a3df90e2
commit 27b7c1dc14
3 changed files with 46 additions and 0 deletions

View file

@ -234,6 +234,37 @@ s32 PS4_SYSV_ABI sceKernelMapNamedFlexibleMemory(void** addr_in_out, std::size_t
Core::VMAType::Flexible, name);
}
s32 PS4_SYSV_ABI sceKernelMapNamedSystemFlexibleMemory(void** addr_in_out, std::size_t len, int prot,
int flags, const char* name) {
if (len == 0 || !Common::Is16KBAligned(len)) {
LOG_ERROR(Kernel_Vmm, "len is 0 or not 16kb multiple");
return ORBIS_KERNEL_ERROR_EINVAL;
}
static constexpr size_t MaxNameSize = 32;
if (std::strlen(name) > MaxNameSize) {
LOG_ERROR(Kernel_Vmm, "name exceeds 32 bytes!");
return ORBIS_KERNEL_ERROR_ENAMETOOLONG;
}
if (name == nullptr) {
LOG_ERROR(Kernel_Vmm, "name is invalid!");
return ORBIS_KERNEL_ERROR_EFAULT;
}
const VAddr in_addr = reinterpret_cast<VAddr>(*addr_in_out);
const auto mem_prot = static_cast<Core::MemoryProt>(prot);
const auto map_flags = static_cast<Core::MemoryMapFlags>(flags);
SCOPE_EXIT {
LOG_INFO(Kernel_Vmm,
"in_addr = {:#x}, out_addr = {}, len = {:#x}, prot = {:#x}, flags = {:#x}",
in_addr, fmt::ptr(*addr_in_out), len, prot, flags);
};
auto* memory = Core::Memory::Instance();
return memory->MapSystemMemory(addr_in_out, in_addr, len, mem_prot, map_flags,
Core::VMAType::Flexible, name);
}
s32 PS4_SYSV_ABI sceKernelMapFlexibleMemory(void** addr_in_out, std::size_t len, int prot,
int flags) {
return sceKernelMapNamedFlexibleMemory(addr_in_out, len, prot, flags, "");
@ -578,6 +609,7 @@ void RegisterMemory(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("PGhQHd-dzv8", "libkernel", 1, "libkernel", 1, 1, sceKernelMmap);
LIB_FUNCTION("cQke9UuBQOk", "libkernel", 1, "libkernel", 1, 1, sceKernelMunmap);
LIB_FUNCTION("mL8NDH86iQI", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedFlexibleMemory);
LIB_FUNCTION("kc+LEEIYakc", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedSystemFlexibleMemory);
LIB_FUNCTION("aNz11fnnzi4", "libkernel", 1, "libkernel", 1, 1,
sceKernelAvailableFlexibleMemorySize);
LIB_FUNCTION("aNz11fnnzi4", "libkernel_avlfmem", 1, "libkernel", 1, 1,

View file

@ -360,6 +360,17 @@ int MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, size_t size, M
return ORBIS_OK;
}
int MemoryManager::MapSystemMemory(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot,
MemoryMapFlags flags, VMAType type, std::string_view name) {
// If address is 0, this maps to System Reserved memory instead, which starts at address 0x880000000
VAddr in_addr = virtual_addr;
if (in_addr == 0) {
static constexpr VAddr KernelAllocBase = 0x880000000ULL;
in_addr = SearchFree(KernelAllocBase, size, 1);
}
return MapMemory(out_addr, in_addr, size, prot, flags, type, name);
}
int MemoryManager::MapFile(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot,
MemoryMapFlags flags, uintptr_t fd, size_t offset) {
VAddr mapped_addr = (virtual_addr == 0) ? impl.SystemManagedVirtualBase() : virtual_addr;

View file

@ -189,6 +189,9 @@ public:
MemoryMapFlags flags, VMAType type, std::string_view name = "",
bool is_exec = false, PAddr phys_addr = -1, u64 alignment = 0);
int MapSystemMemory(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot,
MemoryMapFlags flags, VMAType type, std::string_view name = "");
int MapFile(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot,
MemoryMapFlags flags, uintptr_t fd, size_t offset);