mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-14 15:00:30 +02:00
sceKernelLoadModule: Charge for reading the file and loading it
On hardware a load costs an open and a read of the file, plus about 1ms and 30us per KB of loader work (pspautotests threads/scheduling/callcosts), with the caller waiting throughout. It now charges sceIoOpen's and sceIoRead's estimates for the file plus that, instead of a flat 500us. Also notes why sceKernelLoadModuleByID fails from a game's own fd on ms0: or host0: on hardware, which we don't emulate. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
4ba981b5b3
commit
f2eba8f711
3 files changed
+31
-17
No files matched your search
@@ -2453,6 +2453,7 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) {
|
||||
const u32 error = hleLogError(Log::Loader, SCE_KERNEL_ERROR_FILEERR, "module file size is 0");
|
||||
return hleDelayResult(error, "module loaded", 500);
|
||||
}
|
||||
const int fileSize = (int)fileData.size();
|
||||
|
||||
// A .sprx installed by a PKG game update comes wrapped in an NPDRM "\0PSPEDAT" container: a
|
||||
// 0x90-byte header naming the content ID, then the payload at the offset in its u16 at 0x0C.
|
||||
@@ -2544,8 +2545,11 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) {
|
||||
INFO_LOG(Log::sceModule,"%i=sceKernelLoadModule(name=%s,flag=%08x,(...))", module->GetUID(), name, flags);
|
||||
}
|
||||
|
||||
// TODO: This is not the right timing and probably not the right wait type, just an approximation.
|
||||
return hleDelayResult(hleNoLog(module->GetUID()), "module loaded", 500);
|
||||
// Opening and reading the file, then about 1ms plus 30us per KB of loader work, the caller waiting
|
||||
// throughout. The loader part is what a load took on hardware beyond an open and a read of the
|
||||
// same file (pspautotests threads/scheduling/callcosts, from an SD card in a memory stick adapter).
|
||||
const int loadUs = __IoOpenDelayUs(name) + __IoReadDelayUs(fileSize) + 1000 + fileSize / 34;
|
||||
return hleDelayResult(hleNoLog(module->GetUID()), "module loaded", loadUs);
|
||||
}
|
||||
|
||||
static u32 sceKernelLoadModuleNpDrm(const char *name, u32 flags, u32 optionAddr) {
|
||||
@@ -2984,6 +2988,10 @@ u32 sceKernelFindModuleByName(const char *name)
|
||||
}
|
||||
|
||||
// The id in question here is a file handle.
|
||||
// On hardware, from a game's own fd on ms0: or host0: this fails with
|
||||
// SCE_KERNEL_ERROR_PROHIBIT_LOADMODULE_DEVICE: the file has to pass a kernel-only ioctl (0x00208001),
|
||||
// which a user fd doesn't (it returns ILLEGAL_PERM). sceKernelLoadModule opens the file itself, so it
|
||||
// passes. Whether a disc0:/umd0: fd passes is untested, so we let every device through.
|
||||
static u32 sceKernelLoadModuleByID(u32 id, u32 flags, u32 lmoptionPtr) {
|
||||
u32 error;
|
||||
u32 handle = __IoGetFileHandleFromId(id, error);
|
||||
|
||||
Reference in new issue
Block a user