Merge pull request #22387 from hrydgard/homebrew-slim-extra-ram

Expose extra ram to homebrew apps if Slim model is emulated
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2026-09-29 13:13:10 -06:00
commit 0c6a28fe11
6 files changed
+32 -3

No files matched your search

+3
View File
@@ -589,6 +589,9 @@ static const HLEFunction sceCtrl[] =
{0X239A6BA7, nullptr, "sceCtrlPeekBufferNegative2", '?', "" }, {0X239A6BA7, nullptr, "sceCtrlPeekBufferNegative2", '?', "" },
{0X1098030B, nullptr, "sceCtrlReadBufferPositive2", '?', "" }, {0X1098030B, nullptr, "sceCtrlReadBufferPositive2", '?', "" },
{0X7C3675AB, nullptr, "sceCtrlReadBufferNegative2", '?', "" }, {0X7C3675AB, nullptr, "sceCtrlReadBufferNegative2", '?', "" },
// sceCtrl_driver's NID for sceCtrlPeekBufferPositive in 3.71. Imported by NJEMU's SystemButtons.prx
// kernel plugin, which picks it when sceKernelDevkitVersion() is 3.71 or newer (#8925).
{0XC4AAD55F, &WrapI_UU<sceCtrlPeekBufferPositive>, "sceCtrlPeekBufferPositive", 'i', "xx"},
}; };
void Register_sceCtrl() void Register_sceCtrl()
+3 -2
View File
@@ -321,7 +321,7 @@ void __KernelMemoryInit()
{ {
MemBlockInfoInit(); MemBlockInfoInit();
kernelMemory.Init(PSP_GetKernelMemoryBase(), PSP_GetKernelMemoryEnd() - PSP_GetKernelMemoryBase(), false); kernelMemory.Init(PSP_GetKernelMemoryBase(), PSP_GetKernelMemoryEnd() - PSP_GetKernelMemoryBase(), false);
userMemory.Init(PSP_GetUserMemoryBase(), PSP_GetUserMemoryEnd() - PSP_GetUserMemoryBase(), false); userMemory.Init(PSP_GetUserMemoryBase(), PSP_GetUserPartitionEnd() - PSP_GetUserMemoryBase(), false);
volatileMemory.Init(PSP_GetVolatileMemoryStart(), PSP_GetVolatileMemoryEnd() - PSP_GetVolatileMemoryStart(), false); volatileMemory.Init(PSP_GetVolatileMemoryStart(), PSP_GetVolatileMemoryEnd() - PSP_GetVolatileMemoryStart(), false);
Memory::Memset(PSP_GetKernelMemoryBase(), 0, PSP_GetKernelMemoryEnd() - PSP_GetKernelMemoryBase()); Memory::Memset(PSP_GetKernelMemoryBase(), 0, PSP_GetKernelMemoryEnd() - PSP_GetKernelMemoryBase());
@@ -1712,7 +1712,8 @@ static u32 SysMemUserForUser_D8DE5C1E() {
// Real name per uofw's src/kd/sysmem/exports.exp: sceKernelTotalMemSize - the total size (not // Real name per uofw's src/kd/sysmem/exports.exp: sceKernelTotalMemSize - the total size (not
// free size, see sceKernelMaxFreeMemSize above) of the user memory partition. // free size, see sceKernelMaxFreeMemSize above) of the user memory partition.
static u32 sceKernelTotalMemSize() { static u32 sceKernelTotalMemSize() {
return hleLogDebug(Log::sceKernel, PSP_GetUserMemoryEnd() - PSP_GetUserMemoryBase()); // The partition's own range, which survives savestates (see PSP_GetUserPartitionEnd).
return hleLogDebug(Log::sceKernel, userMemory.GetRangeSize());
} }
static u32 SysMemUserForUser_945E45DA() { static u32 SysMemUserForUser_945E45DA() {
+1
View File
@@ -84,6 +84,7 @@ static u8 *m_pUncachedVRAM[4];
u32 g_MemorySize; u32 g_MemorySize;
// Used to store the PSP model on game startup. // Used to store the PSP model on game startup.
u32 g_PSPModel; u32 g_PSPModel;
u32 g_UserPartitionSize;
static MemMapSetupFlags g_setupFlags; static MemMapSetupFlags g_setupFlags;
+5
View File
@@ -83,6 +83,9 @@ extern u8 *base;
// This replaces RAM_NORMAL_SIZE at runtime. // This replaces RAM_NORMAL_SIZE at runtime.
extern u32 g_MemorySize; extern u32 g_MemorySize;
extern u32 g_PSPModel; extern u32 g_PSPModel;
// Size of RAM (from 0x08000000) that the user partition may extend into. 0 means all of g_MemorySize.
// Smaller only for homebrew on a PSP-2000+ that doesn't ask for the extra RAM (see CPU_Init).
extern u32 g_UserPartitionSize;
// UWP has such limited memory management that we need to mask // UWP has such limited memory management that we need to mask
// even in 64-bit mode. Also, when using the sanitizer, we need to mask as well. // even in 64-bit mode. Also, when using the sanitizer, we need to mask as well.
@@ -673,6 +676,8 @@ constexpr u32 PSP_GetScratchpadMemoryEnd() { return 0x00014000;}
constexpr u32 PSP_GetKernelMemoryBase() { return 0x08000000;} constexpr u32 PSP_GetKernelMemoryBase() { return 0x08000000;}
inline u32 PSP_GetUserMemoryEnd() { return PSP_GetKernelMemoryBase() + Memory::g_MemorySize;} inline u32 PSP_GetUserMemoryEnd() { return PSP_GetKernelMemoryBase() + Memory::g_MemorySize;}
// Where the user memory partition ends. Usually PSP_GetUserMemoryEnd(), which is the end of mapped RAM.
inline u32 PSP_GetUserPartitionEnd() { return PSP_GetKernelMemoryBase() + (Memory::g_UserPartitionSize ? Memory::g_UserPartitionSize : Memory::g_MemorySize); }
constexpr u32 PSP_GetKernelMemoryEnd() { return 0x08400000;} constexpr u32 PSP_GetKernelMemoryEnd() { return 0x08400000;}
// "Volatile" RAM is between 0x08400000 and 0x08800000, can be requested by the // "Volatile" RAM is between 0x08400000 and 0x08800000, can be requested by the
+19 -1
View File
@@ -345,6 +345,7 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin
// Default memory settings // Default memory settings
// Seems to be the safest place currently.. // Seems to be the safest place currently..
Memory::g_MemorySize = Memory::RAM_NORMAL_SIZE; // 32 MB of ram by default Memory::g_MemorySize = Memory::RAM_NORMAL_SIZE; // 32 MB of ram by default
Memory::g_UserPartitionSize = 0;
g_RemasterMode = false; g_RemasterMode = false;
g_DoubleTextureCoordinates = false; g_DoubleTextureCoordinates = false;
@@ -396,10 +397,27 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin
case IdentifiedFileType::PSP_PBP_DIRECTORY: case IdentifiedFileType::PSP_PBP_DIRECTORY:
// This is normal for homebrew. // This is normal for homebrew.
// ERROR_LOG(Log::Loader, "PBP directory resolution failed."); // ERROR_LOG(Log::Loader, "PBP directory resolution failed.");
if (LoadParamSFOFromPBP(fileLoader)) { {
const bool hasSFO = LoadParamSFOFromPBP(fileLoader);
if (hasSFO) {
InitMemorySizeForGame(); InitMemorySizeForGame();
} }
// Homebrew written for a PSP-2000+ under custom firmware (e.g. 3.71 M33) can use the top
// 32MB of RAM (0x0A000000-0x0C000000) directly, without MEMSIZE=1 in its PARAM.SFO. There
// the user partition stays at its normal size, so the heap and thread stacks stay below
// 0x0A000000 and the top of RAM is left to the program. NJEMU's slim builds (MVSPSP, CPS2PSP)
// work this way (#8925). Map the memory, but don't grow the partition into it: MEMSIZE=1
// would, and the program would then overwrite its own heap and stacks.
// Homebrew is identified by the MG ("memory stick game") category, or no PARAM.SFO at all.
// (g_paramSFO only gets a few keys copied over for a PBP, so the category is in the raw copy.)
const bool homebrew = !hasSFO || g_paramSFORaw.GetValueString("CATEGORY") == "MG";
if (homebrew && Memory::g_PSPModel != PSP_MODEL_FAT && Memory::g_MemorySize == Memory::RAM_NORMAL_SIZE) {
INFO_LOG(Log::Loader, "Homebrew PBP: mapping the PSP-2000 extra RAM, outside the user partition");
Memory::g_MemorySize = Memory::RAM_DOUBLE_SIZE;
Memory::g_UserPartitionSize = Memory::RAM_NORMAL_SIZE;
}
break; break;
}
case IdentifiedFileType::PSP_ELF: case IdentifiedFileType::PSP_ELF:
if (Memory::g_PSPModel != PSP_MODEL_FAT) { if (Memory::g_PSPModel != PSP_MODEL_FAT) {
INFO_LOG(Log::Loader, "ELF, using full PSP-2000 memory access"); INFO_LOG(Log::Loader, "ELF, using full PSP-2000 memory access");
+1
View File
@@ -53,6 +53,7 @@ public:
u32 GetBlockSizeFromAddress(u32 addr) const; u32 GetBlockSizeFromAddress(u32 addr) const;
u32 GetLargestFreeBlockSize() const; u32 GetLargestFreeBlockSize() const;
u32 GetTotalFreeBytes() const; u32 GetTotalFreeBytes() const;
u32 GetRangeSize() const { return rangeSize_; }
const char *GetBlockTag(u32 addr) const; const char *GetBlockTag(u32 addr) const;