From 749541f65326916cfda313243d46c8e8b3f4d764 Mon Sep 17 00:00:00 2001 From: winstrex <79346005+winstrex@users.noreply.github.com> Date: Mon, 12 Oct 2026 02:39:44 -0300 Subject: [PATCH] feat(libkernel): implement sceKernelEnableDmemAliasing Direct memory can already be mapped more than once, so there is no aliasing to enable and the call returns 0. ProsperoEden (PPSA99008) imports it and calls it before mapping the same direct memory again. Co-Authored-By: Claude Opus 5.5 --- core/libs/prx/libkernel/DirectMemory/Export.cpp | 4 ++++ core/libs/tests/GuestMemory.cpp | 2 ++ docs/dev/TechnicalDebt.md | 1 + 3 files changed, 7 insertions(+) diff --git a/core/libs/prx/libkernel/DirectMemory/Export.cpp b/core/libs/prx/libkernel/DirectMemory/Export.cpp index 7deed55ab..cf0fe1203 100644 --- a/core/libs/prx/libkernel/DirectMemory/Export.cpp +++ b/core/libs/prx/libkernel/DirectMemory/Export.cpp @@ -171,6 +171,10 @@ size_t APS5_VABI sceKernelGetDirectMemorySize(void) { return DIRECT_MEMORY_SIZE; } +int APS5_VABI sceKernelEnableDmemAliasing(void) { + return 0; +} + int APS5_VABI sceKernelMapDirectMemory(void** addr, size_t len, int prot, int flags, int64_t direct_memory_start, size_t alignment) { (void)alignment; return DoMapDirect(addr, len, prot, flags, direct_memory_start, alignment); diff --git a/core/libs/tests/GuestMemory.cpp b/core/libs/tests/GuestMemory.cpp index d1fafa044..52b3867e1 100644 --- a/core/libs/tests/GuestMemory.cpp +++ b/core/libs/tests/GuestMemory.cpp @@ -59,6 +59,7 @@ int APS5_VABI sceKernelSetVirtualRangeName(const void*, std::uint64_t, const cha int APS5_VABI sceKernelClearVirtualRangeName(const void*, std::uint64_t); int APS5_VABI sceKernelAllocateDirectMemory(std::int64_t, std::int64_t, std::size_t, std::size_t, int, std::int64_t*); int APS5_VABI sceKernelMapDirectMemory(void**, std::size_t, int, int, std::int64_t, std::size_t); +int APS5_VABI sceKernelEnableDmemAliasing(); int APS5_VABI sceKernelReleaseDirectMemory(std::int64_t, std::size_t); int APS5_VABI sceKernelAvailableDirectMemorySize(std::int64_t, std::int64_t, std::size_t, std::int64_t*, std::size_t*); int APS5_VABI sceKernelCheckedReleaseDirectMemory(std::int64_t, std::size_t); @@ -251,6 +252,7 @@ static void CheckDirectMemoryFollowsPhysicalPages() { Require(sceKernelMapDirectMemory(&first, page * 2, 3, 0, phys, 0) == 0); static_cast(first)[0] = 11; static_cast(first)[page + 5] = 22; + Require(sceKernelEnableDmemAliasing() == 0); void* alias = nullptr; Require(sceKernelMapDirectMemory(&alias, page, 3, 0, phys + page, 0) == 0); Require(alias != first && static_cast(alias)[5] == 22); diff --git a/docs/dev/TechnicalDebt.md b/docs/dev/TechnicalDebt.md index f5709b025..9ce251a0c 100644 --- a/docs/dev/TechnicalDebt.md +++ b/docs/dev/TechnicalDebt.md @@ -47,6 +47,7 @@ Throughout the project, every function at every stage either **does exactly what - [sceFontGlyphDefineAttribute](../../core/libs/prx/libSceFont/src/Render.cpp) (libSceFont) checks the glyph and ignores the attribute and its value, whose meaning is unknown. PPSA01325 sets attribute 0x11 to 0 on a glyph from `sceFontGenerateCharGlyph` that it deletes unused, and draws the character with `sceFontRenderCharGlyphImageHorizontal` - [sceAudioInInit](../../core/libs/prx/libSceAudioIn/Export.cpp) (libSceAudioIn) - returns 0 without library-wide setup, as `sceAudioOutInit` does; each `sceAudioInOpen` opens its own SDL capture device - [sceRazorCpuPushMarker](../../core/libs/prx/libSceRazorCpu/Export.cpp) (libSceRazorCpu) - signature (label, color, flags) from [SharpProspero](https://github.com/SvenGDK/SharpProspero), the same as sceRazorCpuPushMarkerStatic's except that the label is copied; it does nothing without a capture and returns 0 +- [sceKernelEnableDmemAliasing](../../core/libs/prx/libkernel/DirectMemory/Export.cpp) (libkernel) returns 0 and changes nothing: direct memory can always be mapped more than once here, as `DoMapDirect` in [DirectMemory.cpp](../../core/libs/prx/libkernel/DirectMemory/DirectMemory.cpp) only checks that the physical pages are allocated, so there is no aliasing to turn on. [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/e0a466753a1aacbc8db8253be685bf7ab4d9daae/src/core/libraries/kernel/memory.cpp#L39-L43) (PS4) sets a flag there that lifts the `EBUSY` its [`sceKernelMapDirectMemory2`](https://github.com/shadps4-emu/shadPS4/blob/e0a466753a1aacbc8db8253be685bf7ab4d9daae/src/core/libraries/kernel/memory.cpp#L299-L301), and [`sceKernelMapDirectMemory` for SDK 2.50 and later](https://github.com/shadps4-emu/shadPS4/blob/e0a466753a1aacbc8db8253be685bf7ab4d9daae/src/core/libraries/kernel/memory.cpp#L237-L242), return for direct memory that is [already mapped](https://github.com/shadps4-emu/shadPS4/blob/e0a466753a1aacbc8db8253be685bf7ab4d9daae/src/core/memory.cpp#L548-L553); that check is not applied here. The no-argument `int` signature follows shadPS4 and ProsperoEden (PPSA99008), which calls it before mapping the same direct memory again. Whether the PS5 refuses such a mapping without the call is unverified ### Unknown function info