Implement sceKernelMapDirectMemory2

Behaves similarly to sceKernelMapDirectMemory, but has a type parameter.
This commit is contained in:
Stephen Miller 2025-05-15 23:44:56 -05:00
parent 26c965cf4a
commit 0a3ca050e4
3 changed files with 56 additions and 0 deletions

View File

@ -209,6 +209,46 @@ int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int fl
"anon"); "anon");
} }
s32 PS4_SYSV_ABI sceKernelMapDirectMemory2(void** addr, u64 len, s32 type, s32 prot, s32 flags,
s64 phys_addr, u64 alignment) {
LOG_INFO(Kernel_Vmm,
"in_addr = {}, len = {:#x}, type = {:#x}, prot = {:#x}, flags = {:#x}, "
"phys_addr = {:#x}, alignment = {:#x}",
fmt::ptr(*addr), len, type, prot, flags, phys_addr, alignment);
if (len == 0 || !Common::Is16KBAligned(len)) {
LOG_ERROR(Kernel_Vmm, "Map size is either zero or not 16KB aligned!");
return ORBIS_KERNEL_ERROR_EINVAL;
}
if (!Common::Is16KBAligned(phys_addr)) {
LOG_ERROR(Kernel_Vmm, "Start address is not 16KB aligned!");
return ORBIS_KERNEL_ERROR_EINVAL;
}
if (alignment != 0) {
if ((!std::has_single_bit(alignment) && !Common::Is16KBAligned(alignment))) {
LOG_ERROR(Kernel_Vmm, "Alignment value is invalid!");
return ORBIS_KERNEL_ERROR_EINVAL;
}
}
const VAddr in_addr = reinterpret_cast<VAddr>(*addr);
const auto mem_prot = static_cast<Core::MemoryProt>(prot);
const auto map_flags = static_cast<Core::MemoryMapFlags>(flags);
auto* memory = Core::Memory::Instance();
const auto ret = memory->MapMemory(addr, in_addr, len, mem_prot, map_flags,
Core::VMAType::Direct, "anon", false, phys_addr, alignment);
if (ret == 0) {
memory->SetDirectMemoryType(phys_addr, type);
}
LOG_INFO(Kernel_Vmm, "out_addr = {}", fmt::ptr(*addr));
return ret;
}
s32 PS4_SYSV_ABI sceKernelMapNamedFlexibleMemory(void** addr_in_out, std::size_t len, int prot, s32 PS4_SYSV_ABI sceKernelMapNamedFlexibleMemory(void** addr_in_out, std::size_t len, int prot,
int flags, const char* name) { int flags, const char* name) {
@ -646,6 +686,7 @@ void RegisterMemory(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("yDBwVAolDgg", "libkernel", 1, "libkernel", 1, 1, sceKernelIsStack); LIB_FUNCTION("yDBwVAolDgg", "libkernel", 1, "libkernel", 1, 1, sceKernelIsStack);
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);
LIB_FUNCTION("BQQniolj9tQ", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory2);
LIB_FUNCTION("WFcfL2lzido", "libkernel", 1, "libkernel", 1, 1, sceKernelQueryMemoryProtection); LIB_FUNCTION("WFcfL2lzido", "libkernel", 1, "libkernel", 1, 1, sceKernelQueryMemoryProtection);
LIB_FUNCTION("BHouLQzh0X0", "libkernel", 1, "libkernel", 1, 1, sceKernelDirectMemoryQuery); LIB_FUNCTION("BHouLQzh0X0", "libkernel", 1, "libkernel", 1, 1, sceKernelDirectMemoryQuery);
LIB_FUNCTION("MBuItvba6z8", "libkernel", 1, "libkernel", 1, 1, sceKernelReleaseDirectMemory); LIB_FUNCTION("MBuItvba6z8", "libkernel", 1, "libkernel", 1, 1, sceKernelReleaseDirectMemory);

View File

@ -783,6 +783,19 @@ int MemoryManager::DirectQueryAvailable(PAddr search_start, PAddr search_end, si
return ORBIS_OK; return ORBIS_OK;
} }
s32 MemoryManager::SetDirectMemoryType(s64 phys_addr, s32 memory_type) {
std::scoped_lock lk{mutex};
auto& dmem_area = FindDmemArea(phys_addr)->second;
ASSERT_MSG(phys_addr <= dmem_area.GetEnd() && !dmem_area.is_free,
"Direct memory area is not mapped");
dmem_area.memory_type = memory_type;
return ORBIS_OK;
}
void MemoryManager::NameVirtualRange(VAddr virtual_addr, size_t size, std::string_view name) { void MemoryManager::NameVirtualRange(VAddr virtual_addr, size_t size, std::string_view name) {
auto it = FindVMA(virtual_addr); auto it = FindVMA(virtual_addr);

View File

@ -219,6 +219,8 @@ public:
int GetDirectMemoryType(PAddr addr, int* directMemoryTypeOut, void** directMemoryStartOut, int GetDirectMemoryType(PAddr addr, int* directMemoryTypeOut, void** directMemoryStartOut,
void** directMemoryEndOut); void** directMemoryEndOut);
s32 SetDirectMemoryType(s64 phys_addr, s32 memory_type);
void NameVirtualRange(VAddr virtual_addr, size_t size, std::string_view name); void NameVirtualRange(VAddr virtual_addr, size_t size, std::string_view name);
void InvalidateMemory(VAddr addr, u64 size) const; void InvalidateMemory(VAddr addr, u64 size) const;