diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index d898e29deb..78fc5032df 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -429,36 +429,41 @@ u32 GetSyscallOp(std::string_view moduleName, u32 nib) { } } -void WriteFuncStub(u32 stubAddr, u32 symAddr) -{ +// It's assumed that stubAddr and symAddr are valid. +void WriteFuncStub(u32 stubAddr, u32 symAddr) { + _dbg_assert_(Memory::IsValid4AlignedAddress(stubAddr)); + _dbg_assert_(Memory::IsValid4AlignedAddress(symAddr)); + // Note that this should be J not JAL, as otherwise control will return to the stub.. - Memory::Write_U32(MIPS_MAKE_J(symAddr), stubAddr); + Memory::WriteUnchecked_U32(MIPS_MAKE_J(symAddr), stubAddr); // Note: doing that, we can't trace external module calls, so maybe something else should be done to debug more efficiently // Perhaps a syscall here (and verify support in jit), marking the module by uid (debugIdentifier)? - Memory::Write_U32(MIPS_MAKE_NOP(), stubAddr + 4); + Memory::WriteUnchecked_U32(MIPS_MAKE_NOP(), stubAddr + 4); } -void WriteFuncMissingStub(u32 stubAddr, u32 nid) -{ +// It's assumed that stubAddr is valid. +void WriteFuncMissingStub(u32 stubAddr, u32 nid) { + _dbg_assert_(Memory::IsValid4AlignedAddress(stubAddr)); // Write a trap so we notice this func if it's called before resolving. - Memory::Write_U32(MIPS_MAKE_JR_RA(), stubAddr); // jr ra - Memory::Write_U32(GetSyscallOp("", nid), stubAddr + 4); + Memory::WriteUnchecked_U32(MIPS_MAKE_JR_RA(), stubAddr); // jr ra + Memory::WriteUnchecked_U32(GetSyscallOp("", nid), stubAddr + 4); } -bool WriteHLESyscall(std::string_view moduleName, u32 nib, u32 address) -{ +// It's assumed that address is valid. +bool WriteHLESyscall(std::string_view moduleName, u32 nib, u32 address) { + _dbg_assert_(Memory::IsValid4AlignedAddress(address)); if (nib == 0) { WARN_LOG_REPORT(Log::HLE, "Wrote patched out nid=0 syscall (%.*s)", (int)moduleName.size(), moduleName.data()); - Memory::Write_U32(MIPS_MAKE_JR_RA(), address); //patched out? - Memory::Write_U32(MIPS_MAKE_NOP(), address+4); //patched out? + Memory::WriteUnchecked_U32(MIPS_MAKE_JR_RA(), address); //patched out? + Memory::WriteUnchecked_U32(MIPS_MAKE_NOP(), address+4); //patched out? return true; } int modindex = GetHLEModuleIndex(moduleName); if (modindex != -1) { - Memory::Write_U32(MIPS_MAKE_JR_RA(), address); // jr ra - Memory::Write_U32(GetSyscallOp(moduleName, nib), address + 4); + Memory::WriteUnchecked_U32(MIPS_MAKE_JR_RA(), address); // jr ra + Memory::WriteUnchecked_U32(GetSyscallOp(moduleName, nib), address + 4); return true; } else @@ -640,7 +645,7 @@ void hleFlushCalls() { } stackData->argc = (int)info.args.size(); for (int j = 0; j < (int)info.args.size(); ++j) { - Memory::Write_U32(info.args[j], sp + sizeof(HLEMipsCallStack) + j * sizeof(u32)); + Memory::WriteUnchecked_U32(info.args[j], sp + sizeof(HLEMipsCallStack) + j * sizeof(u32)); } } enqueuedMipsCalls.clear(); diff --git a/Core/HLE/HLEHelperThread.cpp b/Core/HLE/HLEHelperThread.cpp index d90208d75a..7b78215a8c 100644 --- a/Core/HLE/HLEHelperThread.cpp +++ b/Core/HLE/HLEHelperThread.cpp @@ -26,18 +26,18 @@ #include "Core/HLE/sceKernelMemory.h" #include "Core/MIPS/MIPSCodeUtils.h" -HLEHelperThread::HLEHelperThread() : id_(0), entry_(0) { -} +HLEHelperThread::HLEHelperThread() : id_(0), entry_(0) {} HLEHelperThread::HLEHelperThread(const char *threadName, const u32 instructions[], u32 instrCount, u32 prio, int stacksize) { u32 instrBytes = instrCount * sizeof(u32); u32 totalBytes = instrBytes + sizeof(u32) * 2; AllocEntry(totalBytes); + _dbg_assert_(Memory::IsValid4AlignedAddress(entry_)); // after AllocEntry. Memory::Memcpy(entry_, instructions, instrBytes, "HelperMIPS"); // Just to simplify things, we add the return here. - Memory::Write_U32(MIPS_MAKE_JR_RA(), entry_ + instrBytes + 0); - Memory::Write_U32(MIPS_MAKE_NOP(), entry_ + instrBytes + 4); + Memory::WriteUnchecked_U32(MIPS_MAKE_JR_RA(), entry_ + instrBytes + 0); + Memory::WriteUnchecked_U32(MIPS_MAKE_NOP(), entry_ + instrBytes + 4); Create(threadName, prio, stacksize); } @@ -45,8 +45,9 @@ HLEHelperThread::HLEHelperThread(const char *threadName, const u32 instructions[ HLEHelperThread::HLEHelperThread(const char *threadName, const char *module, const char *func, u32 prio, int stacksize) { const u32 bytes = sizeof(u32) * 2; AllocEntry(bytes); - Memory::Write_U32(MIPS_MAKE_JR_RA(), entry_ + 0); - Memory::Write_U32(MIPS_MAKE_SYSCALL(module, func), entry_ + 4); + _dbg_assert_(Memory::IsValid4AlignedAddress(entry_)); // after AllocEntry. + Memory::WriteUnchecked_U32(MIPS_MAKE_JR_RA(), entry_ + 0); + Memory::WriteUnchecked_U32(MIPS_MAKE_SYSCALL(module, func), entry_ + 4); Create(threadName, prio, stacksize); } @@ -60,6 +61,7 @@ HLEHelperThread::~HLEHelperThread() { void HLEHelperThread::AllocEntry(u32 size) { entry_ = kernelMemory.Alloc(size, false, "HLEHelper"); + _dbg_assert_(Memory::IsValid4AlignedAddress(entry_)); // after AllocEntry. Memory::Memset(entry_, 0, size, "HLEHelperClear"); currentMIPS->InvalidateICache(entry_, size); } diff --git a/Core/HLE/KernelWaitHelpers.h b/Core/HLE/KernelWaitHelpers.h index 735b7875d9..027ede75b8 100644 --- a/Core/HLE/KernelWaitHelpers.h +++ b/Core/HLE/KernelWaitHelpers.h @@ -39,7 +39,7 @@ inline void WaitExecTimeout(SceUID threadID) { if (ko) { if (timeoutPtr != 0) - Memory::Write_U32(0, timeoutPtr); + Memory::WriteOrException_U32(0, timeoutPtr); // This thread isn't waiting anymore, but we'll remove it from waitingThreads later. // The reason is, if it times out, but what it was waiting on is DELETED prior to it @@ -196,7 +196,7 @@ WaitBeginEndCallbackResult WaitEndCallback(SceUID threadID, SceUID prevCallbackI // TODO: Since it was deleted, we don't know how long was actually left. // For now, we just say the full time was taken. if (timeoutPtr != 0 && waitTimer != -1) { - Memory::Write_U32(0, timeoutPtr); + Memory::WriteOrException_U32(0, timeoutPtr); } __KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_DELETE); @@ -217,7 +217,7 @@ WaitBeginEndCallbackResult WaitEndCallback(SceUID threadID, SceUID prevCallbackI s64 cyclesLeft = waitDeadline - CoreTiming::GetTicks(); if (cyclesLeft < 0 && waitDeadline != 0) { if (timeoutPtr != 0 && waitTimer != -1) { - Memory::Write_U32(0, timeoutPtr); + Memory::WriteOrException_U32(0, timeoutPtr); } __KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_TIMEOUT); @@ -247,7 +247,7 @@ WaitBeginEndCallbackResult WaitEndCallback(SceUID threadID, SceUID prevCallbackI // TODO: Since it was deleted, we don't know how long was actually left. // For now, we just say the full time was taken. if (timeoutPtr != 0 && waitTimer != -1) { - Memory::Write_U32(0, timeoutPtr); + Memory::WriteOrException_U32(0, timeoutPtr); } __KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_DELETE); diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index b609955fb4..c98d878190 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -1501,12 +1501,13 @@ static int Hook_starocean_clear_framebuf_after() { u32 y_address, h_address; if (GetMIPSGPAddress(y_address, -204) && GetMIPSGPAddress(h_address, -200)) { - int y = (s16)Memory::Read_U16(y_address); - int h = (s16)Memory::Read_U16(h_address); - - DEBUG_LOG(Log::HLE, "starocean_clear_framebuf() - %08x y=%d-%d", framebuf, y, h); - // TODO: This is always clearing to 0, actually, which could be faster than an upload. - gpu->PerformWriteColorFromMemory(framebuf + 512 * y * 4, 512 * h * 4); + if (Memory::IsValid2AlignedAddress(y_address) && Memory::IsValid2AlignedAddress(h_address)) { + int y = (s16)Memory::ReadUnchecked_U16(y_address); + int h = (s16)Memory::ReadUnchecked_U16(h_address); + DEBUG_LOG(Log::HLE, "starocean_clear_framebuf() - %08x y=%d-%d", framebuf, y, h); + // TODO: This is always clearing to 0, actually, which could be faster than an upload. + gpu->PerformWriteColorFromMemory(framebuf + 512 * y * 4, 512 * h * 4); + } } return 0; } @@ -1515,9 +1516,9 @@ static int Hook_motorstorm_pixel_read() { if (!Memory::IsValidRange(currentMIPS->r[MIPS_REG_A0] + 0x18, 0x20)) { return 0; } - u32 fb_address = Memory::ReadUnchecked_U32(currentMIPS->r[MIPS_REG_A0] + 0x18); - u32 fb_height = Memory::ReadUnchecked_U16(currentMIPS->r[MIPS_REG_A0] + 0x26); - u32 fb_stride = Memory::ReadUnchecked_U16(currentMIPS->r[MIPS_REG_A0] + 0x28); + const u32 fb_address = Memory::ReadUnchecked_U32(currentMIPS->r[MIPS_REG_A0] + 0x18); + const u32 fb_height = Memory::ReadUnchecked_U16(currentMIPS->r[MIPS_REG_A0] + 0x26); + const u32 fb_stride = Memory::ReadUnchecked_U16(currentMIPS->r[MIPS_REG_A0] + 0x28); gpu->PerformReadbackToMemory(fb_address, fb_height * fb_stride); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, fb_height * fb_stride, "motorstorm_pixel_read"); return 0; @@ -1525,8 +1526,8 @@ static int Hook_motorstorm_pixel_read() { static int Hook_worms_copy_normalize_alpha() { // At this point in the function (0x0CC), s1 is the framebuf and a2 is the size. - u32 fb_address = currentMIPS->r[MIPS_REG_S1]; - u32 fb_size = currentMIPS->r[MIPS_REG_A2]; + const u32 fb_address = currentMIPS->r[MIPS_REG_S1]; + const u32 fb_size = currentMIPS->r[MIPS_REG_A2]; if (Memory::IsVRAMAddress(fb_address) && Memory::IsValidRange(fb_address, fb_size)) { gpu->PerformReadbackToMemory(fb_address, fb_size); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, fb_size, "worms_copy_normalize_alpha"); @@ -1881,7 +1882,7 @@ std::map SaveAndClearReplacements() { const u32 curInstr = Memory::Read_Opcode_JIT(addr).encoding; if (MIPS_IS_REPLACEMENT(curInstr)) { saved[addr] = curInstr; - Memory::Write_U32(instr, addr); + Memory::WriteUnchecked_U32(instr, addr); } } @@ -1892,7 +1893,11 @@ std::map SaveAndClearReplacements() { void RestoreSavedReplacements(const std::map &saved) { for (const auto &[addr, instr] : saved) { // Just put the replacements back. - Memory::Write_U32(instr, addr); + if (Memory::IsValid4AlignedAddress(addr)) { + Memory::WriteUnchecked_U32(instr, addr); + } else { + ERROR_LOG(Log::HLE, "RestoreSavedReplacements: Invalid address %08x", addr); + } } } diff --git a/Core/HLE/sceCtrl.cpp b/Core/HLE/sceCtrl.cpp index e6657bb670..d9b53ebaff 100644 --- a/Core/HLE/sceCtrl.cpp +++ b/Core/HLE/sceCtrl.cpp @@ -482,15 +482,15 @@ static int sceCtrlSetIdleCancelThreshold(int idleReset, int idleBack) static int sceCtrlGetIdleCancelThreshold(u32 idleResetPtr, u32 idleBackPtr) { - if (idleResetPtr && !Memory::IsValidAddress(idleResetPtr)) + if (idleResetPtr && !Memory::IsValid4AlignedAddress(idleResetPtr)) return hleLogError(Log::sceCtrl, SCE_KERNEL_ERROR_PRIV_REQUIRED); - if (idleBackPtr && !Memory::IsValidAddress(idleBackPtr)) + if (idleBackPtr && !Memory::IsValid4AlignedAddress(idleBackPtr)) return hleLogError(Log::sceCtrl, SCE_KERNEL_ERROR_PRIV_REQUIRED); if (idleResetPtr) - Memory::Write_U32(ctrlIdleReset, idleResetPtr); + Memory::WriteUnchecked_U32(ctrlIdleReset, idleResetPtr); if (idleBackPtr) - Memory::Write_U32(ctrlIdleBack, idleBackPtr); + Memory::WriteUnchecked_U32(ctrlIdleBack, idleBackPtr); return hleLogDebug(Log::sceCtrl, 0); } diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index c9c75946f7..96bf288c27 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -955,12 +955,12 @@ bool __DisplayGetFramebuf(PSPPointer *topaddr, u32 *linesize, u32 *pixelForm static u32 sceDisplayGetFramebuf(u32 topaddrPtr, u32 linesizePtr, u32 pixelFormatPtr, int latchedMode) { const FrameBufferState &fbState = latchedMode == PSP_DISPLAY_SETBUF_NEXTFRAME ? latchedFramebuf : framebuf; - if (Memory::IsValidAddress(topaddrPtr)) - Memory::Write_U32(fbState.topaddr, topaddrPtr); - if (Memory::IsValidAddress(linesizePtr)) - Memory::Write_U32(fbState.stride, linesizePtr); - if (Memory::IsValidAddress(pixelFormatPtr)) - Memory::Write_U32(fbState.fmt, pixelFormatPtr); + if (Memory::IsValid4AlignedAddress(topaddrPtr)) + Memory::WriteUnchecked_U32(fbState.topaddr, topaddrPtr); + if (Memory::IsValid4AlignedAddress(linesizePtr)) + Memory::WriteUnchecked_U32(fbState.stride, linesizePtr); + if (Memory::IsValid4AlignedAddress(pixelFormatPtr)) + Memory::WriteUnchecked_U32(fbState.fmt, pixelFormatPtr); return hleLogDebug(Log::sceDisplay, 0); } @@ -1068,12 +1068,12 @@ static u32 sceDisplayIsForeground() { } static u32 sceDisplayGetMode(u32 modeAddr, u32 widthAddr, u32 heightAddr) { - if (Memory::IsValidAddress(modeAddr)) - Memory::Write_U32(mode, modeAddr); - if (Memory::IsValidAddress(widthAddr)) - Memory::Write_U32(width, widthAddr); - if (Memory::IsValidAddress(heightAddr)) - Memory::Write_U32(height, heightAddr); + if (Memory::IsValid4AlignedAddress(modeAddr)) + Memory::WriteUnchecked_U32(mode, modeAddr); + if (Memory::IsValid4AlignedAddress(widthAddr)) + Memory::WriteUnchecked_U32(width, widthAddr); + if (Memory::IsValid4AlignedAddress(heightAddr)) + Memory::WriteUnchecked_U32(height, heightAddr); return hleLogDebug(Log::sceDisplay, 0); } @@ -1086,8 +1086,8 @@ static u32 sceDisplayIsVsync() { } static u32 sceDisplayGetResumeMode(u32 resumeModeAddr) { - if (Memory::IsValidAddress(resumeModeAddr)) - Memory::Write_U32(resumeMode, resumeModeAddr); + if (Memory::IsValid4AlignedAddress(resumeModeAddr)) + Memory::WriteUnchecked_U32(resumeMode, resumeModeAddr); return hleLogDebug(Log::sceDisplay, 0); } @@ -1100,12 +1100,12 @@ static u32 sceDisplaySetResumeMode(u32 rMode) { static u32 sceDisplayGetBrightness(u32 levelAddr, u32 otherAddr) { // Standard levels on a PSP: 44, 60, 72, 84 (AC only) - if (Memory::IsValidAddress(levelAddr)) { - Memory::Write_U32(brightnessLevel, levelAddr); + if (Memory::IsValid4AlignedAddress(levelAddr)) { + Memory::WriteUnchecked_U32(brightnessLevel, levelAddr); } // Always seems to write zero? - if (Memory::IsValidAddress(otherAddr)) { - Memory::Write_U32(0, otherAddr); + if (Memory::IsValid4AlignedAddress(otherAddr)) { + Memory::WriteUnchecked_U32(0, otherAddr); } return hleLogWarning(Log::sceDisplay, 0); } diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 2856a5232a..51c023423a 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -785,7 +785,7 @@ void PostAllocCallback::run(MipsCall &call) { if (v0 == 0) { // TODO: Who deletes fontLib? if (errorCodePtr_) - Memory::Write_U32(SCE_FONT_ERROR_OUT_OF_MEMORY, errorCodePtr_); + Memory::WriteOrException_U32(SCE_FONT_ERROR_OUT_OF_MEMORY, errorCodePtr_); call.setReturnValue(0); } else { _dbg_assert_(fontLibID_ >= 0); diff --git a/Core/HLE/sceHprm.cpp b/Core/HLE/sceHprm.cpp index 688ccf3087..3581fc5646 100644 --- a/Core/HLE/sceHprm.cpp +++ b/Core/HLE/sceHprm.cpp @@ -22,7 +22,7 @@ #include "Core/MIPS/MIPS.h" static u32 sceHprmPeekCurrentKey(u32 keyAddress) { - Memory::Write_U32(0, keyAddress); + Memory::WriteOrException_U32(0, keyAddress); return hleLogDebug(Log::HLE, 0); } diff --git a/Core/HLE/sceJpeg.cpp b/Core/HLE/sceJpeg.cpp index 366499d3ba..3ea7f3b89b 100644 --- a/Core/HLE/sceJpeg.cpp +++ b/Core/HLE/sceJpeg.cpp @@ -389,9 +389,9 @@ static int JpegGetOutputInfo(u32 jpegAddr, int jpegSize, u32 colourInfoAddr) { // - Bits 16 to 24 (Color mode): 0x00 (Unknown), 0x01 (Greyscale) or 0x02 (YCbCr) // - Bits 8 to 16 (Vertical chroma subsampling value): 0x00, 0x01 or 0x02 // - Bits 0 to 8 (Horizontal chroma subsampling value): 0x00, 0x01 or 0x02 - if (Memory::IsValidAddress(colourInfoAddr)) { + if (Memory::IsValid4AlignedAddress(colourInfoAddr)) { // Note: can't actually seem to get any other subsampling values or color modes to work on a PSP. - Memory::Write_U32(0x00020202, colourInfoAddr); + Memory::WriteUnchecked_U32(0x00020202, colourInfoAddr); NotifyMemInfo(MemBlockFlags::WRITE, colourInfoAddr, 4, "JpegGetOutputInfo"); } diff --git a/Core/HLE/sceKernelEventFlag.cpp b/Core/HLE/sceKernelEventFlag.cpp index 1129d228ed..a3a6dee106 100644 --- a/Core/HLE/sceKernelEventFlag.cpp +++ b/Core/HLE/sceKernelEventFlag.cpp @@ -144,8 +144,8 @@ static bool __KernelCheckEventFlagMatches(u32 pattern, u32 bits, u8 wait) { static bool __KernelApplyEventFlagMatch(u32_le *pattern, u32 bits, u8 wait, u32 outAddr) { if (__KernelCheckEventFlagMatches(*pattern, bits, wait)) { - if (Memory::IsValidAddress(outAddr)) - Memory::Write_U32(*pattern, outAddr); + if (Memory::IsValid4AlignedAddress(outAddr)) + Memory::WriteUnchecked_U32(*pattern, outAddr); if (wait & PSP_EVENT_WAITCLEAR) *pattern &= ~bits; @@ -167,14 +167,14 @@ static bool __KernelUnlockEventFlagForThread(EventFlag *e, EventFlagTh &th, u32 } else { // Otherwise, we set the current result since we're bailing. if (Memory::IsValidAddress(th.outAddr)) - Memory::Write_U32(e->nef.currentPattern, th.outAddr); + Memory::WriteOrException_U32(e->nef.currentPattern, th.outAddr); } u32 timeoutPtr = __KernelGetWaitTimeoutPtr(th.threadID, error); if (timeoutPtr != 0 && eventFlagWaitTimer != -1) { // Remove any event for this thread. s64 cyclesLeft = CoreTiming::UnscheduleEvent(eventFlagWaitTimer, th.threadID); - Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); + Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); } __KernelResumeThreadFromWait(th.threadID, result); @@ -327,7 +327,7 @@ void __KernelEventFlagTimeout(u64 userdata, int cycleslate) { EventFlag *e = kernelObjects.Get(flagID, error); if (e) { if (timeoutPtr != 0) - Memory::Write_U32(0, timeoutPtr); + Memory::WriteOrException_U32(0, timeoutPtr); for (size_t i = 0; i < e->waitingThreads.size(); i++) { EventFlagTh *t = &e->waitingThreads[i]; @@ -349,7 +349,7 @@ static void __KernelSetEventFlagTimeout(EventFlag *e, u32 timeoutPtr) { if (timeoutPtr == 0 || eventFlagWaitTimer == -1) return; - int micro = (int) Memory::Read_U32(timeoutPtr); + int micro = (int) Memory::ReadOrException_U32(timeoutPtr); // This seems like the actual timing of timeouts on hardware. if (micro <= 1) @@ -385,7 +385,7 @@ int sceKernelWaitEventFlag(SceUID id, u32 bits, u32 wait, u32 outBitsPtr, u32 ti u32 timeout = 0xFFFFFFFF; if (Memory::IsValidAddress(timeoutPtr)) - timeout = Memory::Read_U32(timeoutPtr); + timeout = Memory::ReadOrException_U32(timeoutPtr); // Do we allow more than one thread to wait? if (e->waitingThreads.size() > 0 && (e->nef.attr & PSP_EVENT_WAITMULTIPLE) == 0) { @@ -448,7 +448,7 @@ int sceKernelWaitEventFlagCB(SceUID id, u32 bits, u32 wait, u32 outBitsPtr, u32 u32 timeout = 0xFFFFFFFF; if (Memory::IsValidAddress(timeoutPtr)) - timeout = Memory::Read_U32(timeoutPtr); + timeout = Memory::ReadOrException_U32(timeoutPtr); // Do we allow more than one thread to wait? if (e->waitingThreads.size() > 0 && (e->nef.attr & PSP_EVENT_WAITMULTIPLE) == 0) { @@ -502,8 +502,9 @@ int sceKernelPollEventFlag(SceUID id, u32 bits, u32 wait, u32 outBitsPtr) { EventFlag *e = kernelObjects.Get(id, error); if (e) { if (!__KernelApplyEventFlagMatch(&e->nef.currentPattern, bits, wait, outBitsPtr)) { - if (Memory::IsValidAddress(outBitsPtr)) - Memory::Write_U32(e->nef.currentPattern, outBitsPtr); + if (Memory::IsValid4AlignedAddress(outBitsPtr)) { + Memory::WriteUnchecked_U32(e->nef.currentPattern, outBitsPtr); + } if (e->waitingThreads.size() > 0 && (e->nef.attr & PSP_EVENT_WAITMULTIPLE) == 0) { return hleLogDebug(Log::sceKernel, SCE_KERNEL_ERROR_EVF_MULTI); diff --git a/Core/HLE/sceKernelMbx.cpp b/Core/HLE/sceKernelMbx.cpp index d9670519fb..22e29873b9 100644 --- a/Core/HLE/sceKernelMbx.cpp +++ b/Core/HLE/sceKernelMbx.cpp @@ -207,7 +207,7 @@ static bool __KernelUnlockMbxForThread(Mbx *m, MbxWaitingThread &th, u32 &error, { // Remove any event for this thread. s64 cyclesLeft = CoreTiming::UnscheduleEvent(mbxWaitTimer, th.threadID); - Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); + Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); } __KernelResumeThreadFromWait(th.threadID, result); @@ -254,7 +254,7 @@ static void __KernelWaitMbx(Mbx *m, u32 timeoutPtr) if (timeoutPtr == 0 || mbxWaitTimer == -1) return; - int micro = (int) Memory::Read_U32(timeoutPtr); + int micro = (int) Memory::ReadOrException_U32(timeoutPtr); // This seems to match the actual timing. if (micro <= 2) @@ -379,7 +379,7 @@ int sceKernelSendMbx(SceUID id, u32 packetAddr) m->waitingThreads.erase(iter); if (wokeThreads) { - Memory::Write_U32(packetAddr, t.packetAddr); + Memory::WriteOrException_U32(packetAddr, t.packetAddr); hleReSchedule("mbx sent"); // We don't need to do anything else, finish here. @@ -521,7 +521,7 @@ int sceKernelCancelReceiveMbx(SceUID id, u32 numWaitingThreadsAddr) { hleReSchedule("mbx canceled"); if (numWaitingThreadsAddr) - Memory::Write_U32(count, numWaitingThreadsAddr); + Memory::WriteOrException_U32(count, numWaitingThreadsAddr); return 0; } diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index aff2d78aa9..a89bce775b 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -457,7 +457,7 @@ static bool __KernelUnlockFplForThread(FPL *fpl, FplWaitingThread &threadInfo, u int blockNum = fpl->AllocateBlock(); if (blockNum >= 0) { u32 blockPtr = fpl->address + fpl->alignedSize * blockNum; - Memory::Write_U32(blockPtr, threadInfo.addrPtr); + Memory::WriteOrException_U32(blockPtr, threadInfo.addrPtr); NotifyMemInfo(MemBlockFlags::SUB_ALLOC, blockPtr, fpl->alignedSize, "FplAllocate"); } else { return false; @@ -468,7 +468,7 @@ static bool __KernelUnlockFplForThread(FPL *fpl, FplWaitingThread &threadInfo, u if (timeoutPtr != 0 && fplWaitTimer != -1) { // Remove any event for this thread. s64 cyclesLeft = CoreTiming::UnscheduleEvent(fplWaitTimer, threadID); - Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); + Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); } __KernelResumeThreadFromWait(threadID, result); @@ -543,10 +543,10 @@ int sceKernelCreateFpl(const char *name, u32 mpid, u32 attr, u32 blockSize, u32 return hleReportWarning(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE, "invalid blockSize/count"); int alignment = 4; - if (Memory::IsValidRange(optPtr, 4)) { + if (Memory::IsValidRange(optPtr, 8)) { u32 size = Memory::ReadUnchecked_U32(optPtr); if (size >= 4) - alignment = Memory::Read_U32(optPtr + 4); + alignment = Memory::ReadUnchecked_U32(optPtr + 4); // Must be a power of 2 to be valid. if ((alignment & (alignment - 1)) != 0) return hleLogWarning(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT, "invalid alignment %d", alignment); @@ -614,7 +614,7 @@ static void __KernelSetFplTimeout(u32 timeoutPtr) if (timeoutPtr == 0 || fplWaitTimer == -1) return; - int micro = (int) Memory::Read_U32(timeoutPtr); + int micro = (int) Memory::ReadOrException_U32(timeoutPtr); // TODO: test for fpls. // This happens to be how the hardware seems to time things. @@ -697,7 +697,7 @@ int sceKernelTryAllocateFpl(SceUID uid, u32 blockPtrAddr) { int blockNum = fpl->AllocateBlock(); if (blockNum >= 0) { u32 blockPtr = fpl->address + fpl->alignedSize * blockNum; - Memory::Write_U32(blockPtr, blockPtrAddr); + Memory::WriteOrException_U32(blockPtr, blockPtrAddr); NotifyMemInfo(MemBlockFlags::SUB_ALLOC, blockPtr, fpl->alignedSize, "FplAllocate"); return hleLogDebug(Log::sceKernel, 0); } else { @@ -757,8 +757,9 @@ int sceKernelCancelFpl(SceUID uid, u32 numWaitThreadsPtr) { } fpl->nf.numWaitThreads = (int) fpl->waitingThreads.size(); - if (Memory::IsValidAddress(numWaitThreadsPtr)) - Memory::Write_U32(fpl->nf.numWaitThreads, numWaitThreadsPtr); + if (Memory::IsValid4AlignedAddress(numWaitThreadsPtr)) { + Memory::WriteUnchecked_U32(fpl->nf.numWaitThreads, numWaitThreadsPtr); + } bool wokeThreads = __KernelClearFplThreads(fpl, SCE_KERNEL_ERROR_WAIT_CANCEL); if (wokeThreads) hleReSchedule("fpl canceled"); @@ -1247,7 +1248,7 @@ static bool __KernelUnlockVplForThread(VPL *vpl, VplWaitingThread &threadInfo, u addr = vpl->alloc.Alloc(allocSize, true); } if (addr != (u32) -1) { - Memory::Write_U32(addr, threadInfo.addrPtr); + Memory::WriteOrException_U32(addr, threadInfo.addrPtr); } else { return false; } @@ -1257,7 +1258,7 @@ static bool __KernelUnlockVplForThread(VPL *vpl, VplWaitingThread &threadInfo, u if (timeoutPtr != 0 && vplWaitTimer != -1) { // Remove any event for this thread. s64 cyclesLeft = CoreTiming::UnscheduleEvent(vplWaitTimer, threadID); - Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); + Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); } __KernelResumeThreadFromWait(threadID, result); @@ -1428,7 +1429,7 @@ static bool __KernelAllocateVpl(SceUID uid, u32 size, u32 addrPtr, u32 &error, b addr = vpl->alloc.Alloc(allocSize, true, "VplAllocate"); } if (addr != (u32) -1) { - Memory::Write_U32(addr, addrPtr); + Memory::WriteOrException_U32(addr, addrPtr); error = 0; } else { error = SCE_KERNEL_ERROR_NO_MEMORY; @@ -1465,7 +1466,7 @@ static void __KernelSetVplTimeout(u32 timeoutPtr) if (timeoutPtr == 0 || vplWaitTimer == -1) return; - int micro = (int) Memory::Read_U32(timeoutPtr); + int micro = (int) Memory::ReadOrException_U32(timeoutPtr); // This happens to be how the hardware seems to time things. if (micro <= 5) @@ -1487,7 +1488,7 @@ int sceKernelAllocateVpl(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr) VPL *vpl = kernelObjects.Get(uid, ignore); if (error == SCE_KERNEL_ERROR_NO_MEMORY) { - if (timeoutPtr != 0 && Memory::Read_U32(timeoutPtr) == 0) + if (timeoutPtr != 0 && Memory::ReadOrException_U32(timeoutPtr) == 0) return hleLogError(Log::sceKernel, SCE_KERNEL_ERROR_WAIT_TIMEOUT); if (vpl) { @@ -1517,7 +1518,7 @@ int sceKernelAllocateVplCB(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr) VPL *vpl = kernelObjects.Get(uid, ignore); if (error == SCE_KERNEL_ERROR_NO_MEMORY) { - if (timeoutPtr != 0 && Memory::Read_U32(timeoutPtr) == 0) + if (timeoutPtr != 0 && Memory::ReadOrException_U32(timeoutPtr) == 0) return hleLogError(Log::sceKernel, SCE_KERNEL_ERROR_WAIT_TIMEOUT); if (vpl) @@ -1669,7 +1670,7 @@ static u32 sceKernelGetMemoryBlockAddr(u32 uid, u32 addr) { u32 error; PartitionMemoryBlock *block = kernelObjects.Get(uid, error); if (block) { - Memory::Write_U32(block->address, addr); + Memory::WriteOrException_U32(block->address, addr); return hleLogInfo(Log::sceKernel, 0, "block address: %08x", block->address); } else { return hleLogError(Log::sceKernel, 0, "failed"); diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index af9ca91efe..e349f9012b 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -395,7 +395,7 @@ public: }; void AfterModuleEntryCall::run(MipsCall &call) { - Memory::Write_U32(retValAddr, currentMIPS->r[MIPS_REG_V0]); + Memory::WriteOrException_U32(retValAddr, currentMIPS->r[MIPS_REG_V0]); } ////////////////////////////////////////////////////////////////////////// @@ -571,7 +571,7 @@ static void WriteVarSymbol(WriteVarSymbolState &state, u32 exportAddress, u32 re // The low instruction will be a signed add, which means (full & 0x8000) will subtract. // We add 1 in that case so that it ends up the right value. u16 high = (full >> 16) + ((full & 0x8000) ? 1 : 0); - Memory::Write_U32((reloc.data & ~0xFFFF) | high, reloc.addr); + Memory::WriteUnchecked_U32((reloc.data & ~0xFFFF) | high, reloc.addr); currentMIPS->InvalidateICache(reloc.addr, 4); } state.lastHI16Processed = true; @@ -586,7 +586,7 @@ static void WriteVarSymbol(WriteVarSymbolState &state, u32 exportAddress, u32 re WARN_LOG_REPORT(Log::Loader, "Unsupported var relocation type %d - %08x => %08x", type, exportAddress, relocAddress); } - Memory::Write_U32(relocData, relocAddress); + Memory::WriteUnchecked_U32(relocData, relocAddress); currentMIPS->InvalidateICache(relocAddress, 4); } @@ -2138,7 +2138,7 @@ u32 sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 returnValue return hleLogWarning(Log::sceModule, error, "error %08x", error); } else if (module->isFake) { if (returnValueAddr) - Memory::Write_U32(0, returnValueAddr); + Memory::WriteOrException_U32(0, returnValueAddr); return hleLogInfo(Log::sceModule, moduleId, "Faked module"); } else if (module->nm.status == MODULE_STATUS_STARTED) { // TODO: Maybe should be SCE_KERNEL_ERROR_ALREADY_STARTED, but I get SCE_KERNEL_ERROR_ERROR. @@ -2176,7 +2176,7 @@ static u32 sceKernelStopModule(u32 moduleId, u32 argSize, u32 argAddr, u32 retur if (module->isFake) { if (returnValueAddr) - Memory::Write_U32(0, returnValueAddr); + Memory::WriteOrException_U32(0, returnValueAddr); return hleLogInfo(Log::sceModule, 0, "faking"); } if (module->nm.status != MODULE_STATUS_STARTED) { @@ -2192,8 +2192,7 @@ static u32 sceKernelStopModule(u32 moduleId, u32 argSize, u32 argAddr, u32 retur attr = module->nm.module_stop_thread_attr; // TODO: Need to test how this really works. Let's assume it's an override. - if (Memory::IsValidAddress(optionAddr)) - { + if (Memory::IsValidRange(optionAddr, sizeof(SceKernelSMOption))) { auto options = PSPPointer::Create(optionAddr); // TODO: Check how size handling actually works. if (options->size != 0 && options->priority != 0) @@ -2207,8 +2206,7 @@ static u32 sceKernelStopModule(u32 moduleId, u32 argSize, u32 argAddr, u32 retur WARN_LOG_REPORT(Log::sceModule, "Stopping module with attr=%x, but options specify 0", attr); } - if (Memory::IsValidAddress(stopFunc)) - { + if (Memory::IsValid4AlignedAddress(stopFunc)) { SceUID threadID = __KernelCreateThread(module->nm.name, moduleId, stopFunc, priority, stacksize, attr, 0, (module->nm.attribute & 0x1000) != 0); _dbg_assert_(threadID > 0); // TOOD: Check the return value and bail? @@ -2219,14 +2217,10 @@ static u32 sceKernelStopModule(u32 moduleId, u32 argSize, u32 argAddr, u32 retur const ModuleWaitingThread mwt = {__KernelGetCurThread(), returnValueAddr}; module->nm.status = MODULE_STATUS_STOPPING; module->waitingThreads.push_back(mwt); - } - else if (stopFunc == 0) - { + } else if (stopFunc == 0) { module->nm.status = MODULE_STATUS_STOPPED; return hleLogInfo(Log::sceModule, 0, "no stop func, skipping"); - } - else - { + } else { module->nm.status = MODULE_STATUS_STOPPED; return hleLogError(Log::sceModule, 0, "sceKernelStopModule(%08x, %08x, %08x, %08x, %08x): bad stop func address", moduleId, argSize, argAddr, returnValueAddr, optionAddr); } @@ -2378,7 +2372,7 @@ void __KernelReturnFromModuleFunc() { hleCall(ThreadManForKernel, int, sceKernelTerminateDeleteThread, it->threadID); } else { if (it->statusPtr != 0) - Memory::Write_U32(exitStatus, it->statusPtr); + Memory::WriteOrException_U32(exitStatus, it->statusPtr); __KernelResumeThreadFromWait(it->threadID, module->nm.status == MODULE_STATUS_STARTED ? leftModuleID : 0); } } @@ -2644,14 +2638,14 @@ static u32 sceKernelGetModuleIdList(u32 resultBuffer, u32 resultBufferSize, u32 PSPModule *module = kernelObjects.Get(moduleId, error); if (!module->isFake || liedAboutThisModule(module)) { if (resultBufferOffset < resultBufferSize) { - Memory::Write_U32(module->GetUID(), resultBuffer + resultBufferOffset); + Memory::WriteOrException_U32(module->GetUID(), resultBuffer + resultBufferOffset); resultBufferOffset += 4; } idCount++; } // Actually, should we return fake modules too? They wouldn't be fake on the real hardware. Not like any games use this function though. } - Memory::Write_U32(idCount, idCountAddr); + Memory::WriteOrException_U32(idCount, idCountAddr); return hleNoLog(0); } diff --git a/Core/HLE/sceKernelMsgPipe.cpp b/Core/HLE/sceKernelMsgPipe.cpp index 0f4967af97..44572dcf64 100644 --- a/Core/HLE/sceKernelMsgPipe.cpp +++ b/Core/HLE/sceKernelMsgPipe.cpp @@ -85,7 +85,7 @@ struct MsgPipeWaitingThread { // Remove any event for this thread. s64 cyclesLeft = CoreTiming::UnscheduleEvent(waitTimer, threadID); - Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); + Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); } } } @@ -369,8 +369,8 @@ static int __KernelSendMsgPipe(MsgPipe *m, u32 sendBufAddr, u32 sendSize, int wa if (poll) { // Generally, result is not updated in this case. But for a 0 size buffer in ASAP mode, it is. - if (Memory::IsValidAddress(resultAddr) && waitMode == SCE_KERNEL_MPW_ASAP) - Memory::Write_U32(curSendAddr - sendBufAddr, resultAddr); + if (Memory::IsValid4AlignedAddress(resultAddr) && waitMode == SCE_KERNEL_MPW_ASAP) + Memory::WriteUnchecked_U32(curSendAddr - sendBufAddr, resultAddr); return SCE_KERNEL_ERROR_MPP_FULL; } else @@ -424,8 +424,8 @@ static int __KernelSendMsgPipe(MsgPipe *m, u32 sendBufAddr, u32 sendSize, int wa } // We didn't wait, so update the number of bytes transferred now. - if (Memory::IsValidAddress(resultAddr)) - Memory::Write_U32(curSendAddr - sendBufAddr, resultAddr); + if (Memory::IsValid4AlignedAddress(resultAddr)) + Memory::WriteUnchecked_U32(curSendAddr - sendBufAddr, resultAddr); return 0; } @@ -469,8 +469,8 @@ static int __KernelReceiveMsgPipe(MsgPipe *m, u32 receiveBufAddr, u32 receiveSiz if (poll) { // Generally, result is not updated in this case. But for a 0 size buffer in ASAP mode, it is. - if (Memory::IsValidAddress(resultAddr) && waitMode == SCE_KERNEL_MPW_ASAP) - Memory::Write_U32(curReceiveAddr - receiveBufAddr, resultAddr); + if (Memory::IsValid4AlignedAddress(resultAddr) && waitMode == SCE_KERNEL_MPW_ASAP) + Memory::WriteUnchecked_U32(curReceiveAddr - receiveBufAddr, resultAddr); return SCE_KERNEL_ERROR_MPP_EMPTY; } else @@ -520,8 +520,8 @@ static int __KernelReceiveMsgPipe(MsgPipe *m, u32 receiveBufAddr, u32 receiveSiz } } - if (Memory::IsValidAddress(resultAddr)) - Memory::Write_U32(curReceiveAddr - receiveBufAddr, resultAddr); + if (Memory::IsValid4AlignedAddress(resultAddr)) + Memory::WriteUnchecked_U32(curReceiveAddr - receiveBufAddr, resultAddr); return 0; } diff --git a/Core/HLE/sceKernelMutex.cpp b/Core/HLE/sceKernelMutex.cpp index 92b986d545..a2e3883fbe 100644 --- a/Core/HLE/sceKernelMutex.cpp +++ b/Core/HLE/sceKernelMutex.cpp @@ -263,7 +263,7 @@ static bool __KernelUnlockMutexForThread(PSPMutex *mutex, SceUID threadID, u32 & { // Remove any event for this thread. s64 cyclesLeft = CoreTiming::UnscheduleEvent(mutexWaitTimer, threadID); - Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); + Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); } __KernelResumeThreadFromWait(threadID, result); @@ -498,8 +498,8 @@ int sceKernelCancelMutex(SceUID uid, int count, u32 numWaitThreadsPtr) { // Remove threads no longer waiting on this first (so the numWaitThreads value is correct.) HLEKernel::CleanupWaitingThreads(WAITTYPE_MUTEX, uid, mutex->waitingThreads); - if (Memory::IsValidAddress(numWaitThreadsPtr)) - Memory::Write_U32((u32)mutex->waitingThreads.size(), numWaitThreadsPtr); + if (Memory::IsValid4AlignedAddress(numWaitThreadsPtr)) + Memory::WriteUnchecked_U32((u32)mutex->waitingThreads.size(), numWaitThreadsPtr); bool wokeThreads = false; for (auto iter = mutex->waitingThreads.begin(), end = mutex->waitingThreads.end(); iter != end; ++iter) @@ -730,8 +730,7 @@ bool __KernelUnlockLwMutexForThread(LwMutex *mutex, T workarea, SceUID threadID, return false; // If result is an error code, we're just letting it go. - if (result == 0) - { + if (result == 0) { workarea->lockLevel = (int) __KernelGetWaitValue(threadID, error); workarea->lockThread = threadID; } @@ -740,7 +739,7 @@ bool __KernelUnlockLwMutexForThread(LwMutex *mutex, T workarea, SceUID threadID, if (timeoutPtr != 0 && lwMutexWaitTimer != -1) { // Remove any event for this thread. s64 cyclesLeft = CoreTiming::UnscheduleEvent(lwMutexWaitTimer, threadID); - Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); + Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); } __KernelResumeThreadFromWait(threadID, result); diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index 47fc250360..4c4aa30401 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -132,7 +132,7 @@ static bool __KernelUnlockSemaForThread(PSPSemaphore *s, SceUID threadID, u32 &e s64 cyclesLeft = CoreTiming::UnscheduleEvent(semaWaitTimer, threadID); if (cyclesLeft < 0) cyclesLeft = 0; - Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); + Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); } __KernelResumeThreadFromWait(threadID, result); @@ -184,7 +184,7 @@ int sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr) s->ns.numWaitThreads = (int) s->waitingThreads.size(); if (Memory::IsValidAddress(numWaitThreadsPtr)) - Memory::Write_U32(s->ns.numWaitThreads, numWaitThreadsPtr); + Memory::WriteOrException_U32(s->ns.numWaitThreads, numWaitThreadsPtr); if (newCount < 0) s->ns.currentCount = s->ns.initCount; diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 165e1b96bc..eb02c25878 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -382,13 +382,13 @@ bool PSPThread::FillStack() { context.r[MIPS_REG_K0] = context.r[MIPS_REG_SP]; u32 k0 = context.r[MIPS_REG_K0]; Memory::Memset(k0, 0, 0x100, "ThreadK0"); - Memory::Write_U32(GetUID(), k0 + 0xc0); - Memory::Write_U32(nt.initialStack, k0 + 0xc8); - Memory::Write_U32(0xffffffff, k0 + 0xf8); - Memory::Write_U32(0xffffffff, k0 + 0xfc); + Memory::WriteOrException_U32(GetUID(), k0 + 0xc0); + Memory::WriteOrException_U32(nt.initialStack, k0 + 0xc8); + Memory::WriteOrException_U32(0xffffffff, k0 + 0xf8); + Memory::WriteOrException_U32(0xffffffff, k0 + 0xfc); // After k0 comes the arguments, which is done by sceKernelStartThread(). - Memory::Write_U32(GetUID(), nt.initialStack); + Memory::WriteOrException_U32(GetUID(), nt.initialStack); return true; } @@ -418,7 +418,7 @@ bool PSPThread::PushExtendedStack(u32 size) { // We still drop the threadID at the bottom and fill it, but there's no k0. Memory::Memset(currentStack.start, 0xFF, nt.stackSize, "ThreadExtendStack"); - Memory::Write_U32(GetUID(), nt.initialStack); + Memory::WriteOrException_U32(GetUID(), nt.initialStack); return true; } @@ -715,7 +715,7 @@ static bool __KernelCheckResumeThreadEnd(PSPThread *t, SceUID waitingThreadID, u u32 timeoutPtr = __KernelGetWaitTimeoutPtr(waitingThreadID, error); s64 cyclesLeft = CoreTiming::UnscheduleEvent(eventThreadEndTimeout, waitingThreadID); if (timeoutPtr != 0) - Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); + Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); s32 exitStatus = t->nt.exitStatus; __KernelResumeThreadFromWait(waitingThreadID, exitStatus); return true; @@ -1327,7 +1327,7 @@ u32 sceKernelGetThreadmanIdList(u32 type, u32 readBufPtr, u32 readBufSize, u32 i } if (Memory::IsValidAddress(idCountPtr)) { - Memory::Write_U32(total, idCountPtr); + Memory::WriteOrException_U32(total, idCountPtr); } return total > readBufSize ? readBufSize : total; } @@ -1420,8 +1420,9 @@ void __KernelWaitCurThread(WaitType type, SceUID waitID, u32 waitValue, u32 time thread->waitInfo.waitValue = waitValue; thread->waitInfo.timeoutPtr = timeoutPtr; - if (!reason) + if (!reason) { reason = "started wait"; + } hleReSchedule(processCallbacks, reason); } @@ -1513,7 +1514,7 @@ void __KernelStopThread(SceUID threadID, int exitStatus, const char *reason) { s64 cyclesLeft = CoreTiming::UnscheduleEvent(eventThreadEndTimeout, waitingThread); if (timeoutPtr != 0) - Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); + Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); HLEKernel::ResumeFromWait(waitingThread, WAITTYPE_THREADEND, threadID, exitStatus); } @@ -1956,8 +1957,8 @@ int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bo // At the bottom of those 64 bytes, the return syscall and ra is written. // Test Drive Unlimited actually depends on it being in the correct place. WriteHLESyscall("FakeSysCalls", NID_THREADRETURN, sp); - Memory::Write_U32(MIPS_MAKE_B(-1), sp + 8); - Memory::Write_U32(MIPS_MAKE_NOP(), sp + 12); + Memory::WriteOrException_U32(MIPS_MAKE_B(-1), sp + 8); + Memory::WriteOrException_U32(MIPS_MAKE_NOP(), sp + 12); // Point ra at our return stub, and start fp off matching sp. startThread->context.r[MIPS_REG_RA] = sp; @@ -2792,9 +2793,9 @@ u32 sceKernelExtendThreadStack(u32 size, u32 entryAddr, u32 entryParameter) { // The stack has been changed now, so it's do or die time. // Push the old SP, RA, and PC onto the stack (so we can restore them later.) - Memory::Write_U32(currentMIPS->r[MIPS_REG_RA], thread->currentStack.end - 4); - Memory::Write_U32(currentMIPS->r[MIPS_REG_SP], thread->currentStack.end - 8); - Memory::Write_U32(currentMIPS->pc, thread->currentStack.end - 12); + Memory::WriteOrException_U32(currentMIPS->r[MIPS_REG_RA], thread->currentStack.end - 4); + Memory::WriteOrException_U32(currentMIPS->r[MIPS_REG_SP], thread->currentStack.end - 8); + Memory::WriteOrException_U32(currentMIPS->pc, thread->currentStack.end - 12); KernelValidateThreadTarget(entryAddr); @@ -3116,11 +3117,11 @@ bool __KernelExecuteMipsCallOnCurrentThread(u32 callId, bool reschedAfter) // Let's just save regs generously. Better to be safe. sp -= 32 * 4; for (int i = MIPS_REG_A0; i <= MIPS_REG_T7; ++i) { - Memory::Write_U32(currentMIPS->r[i], sp + i * 4); + Memory::WriteOrException_U32(currentMIPS->r[i], sp + i * 4); } - Memory::Write_U32(currentMIPS->r[MIPS_REG_T8], sp + MIPS_REG_T8 * 4); - Memory::Write_U32(currentMIPS->r[MIPS_REG_T9], sp + MIPS_REG_T9 * 4); - Memory::Write_U32(currentMIPS->r[MIPS_REG_RA], sp + MIPS_REG_RA * 4); + Memory::WriteOrException_U32(currentMIPS->r[MIPS_REG_T8], sp + MIPS_REG_T8 * 4); + Memory::WriteOrException_U32(currentMIPS->r[MIPS_REG_T9], sp + MIPS_REG_T9 * 4); + Memory::WriteOrException_U32(currentMIPS->r[MIPS_REG_RA], sp + MIPS_REG_RA * 4); // Save the few regs that need saving call->savedPc = currentMIPS->pc; diff --git a/Core/HLE/sceMp3.cpp b/Core/HLE/sceMp3.cpp index e23d987b0b..7f6195b240 100644 --- a/Core/HLE/sceMp3.cpp +++ b/Core/HLE/sceMp3.cpp @@ -739,8 +739,8 @@ static u32 sceMp3LowLevelDecode(u32 mp3, u32 sourceAddr, u32 sourceBytesConsumed int outBytes = outSamples * sizeof(int16_t) * 2; NotifyMemInfo(MemBlockFlags::WRITE, samplesAddr, outBytes, "Mp3LowLevelDecode"); - Memory::Write_U32(inbytesConsumed, sourceBytesConsumedAddr); - Memory::Write_U32(outBytes, sampleBytesAddr); + Memory::WriteOrException_U32(inbytesConsumed, sourceBytesConsumedAddr); + Memory::WriteOrException_U32(outBytes, sampleBytesAddr); return hleLogDebug(Log::ME, 0); } diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index cfe367ddbb..fc45897771 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -509,15 +509,15 @@ static u32 sceMpegCreate(u32 mpegAddr, u32 dataPtr, u32 size, u32 ringbufferAddr // Generate, and write mpeg handle into mpeg data, for some reason int mpegHandle = dataPtr + 0x30; - Memory::Write_U32(mpegHandle, mpegAddr); + Memory::WriteUnchecked_U32(mpegHandle, mpegAddr); // Initialize fake mpeg struct. Memory::Memcpy(mpegHandle, "LIBMPEG\0", 8, "Mpeg"); Memory::Memcpy(mpegHandle + 8, "001\0", 4, "Mpeg"); - Memory::Write_U32(-1, mpegHandle + 12); + Memory::WriteUnchecked_U32(-1, mpegHandle + 12); if (ringbuffer.IsValid()) { - Memory::Write_U32(ringbufferAddr, mpegHandle + 16); - Memory::Write_U32(ringbuffer->dataUpperBound, mpegHandle + 20); + Memory::WriteUnchecked_U32(ringbufferAddr, mpegHandle + 16); + Memory::WriteUnchecked_U32(ringbuffer->dataUpperBound, mpegHandle + 20); } MpegContext *ctx = new MpegContext(); if (g_mpegCtxs.find(mpegHandle) != g_mpegCtxs.end()) { @@ -1158,11 +1158,11 @@ static u32 sceMpegAvcDecode(u32 mpeg, u32 auAddr, u32 frameWidth, u32 bufferAddr if (mpegLibVersion >= 0x0105 && mpegLibVersion < 0x010a) { //Killzone - Liberation expect , issue #16727 - Memory::Write_U32(1, initAddr); + Memory::WriteOrException_U32(1, initAddr); } else { // Save the current frame's status to initAddr - Memory::Write_U32(ctx->avc.avcFrameStatus, initAddr); + Memory::WriteOrException_U32(ctx->avc.avcFrameStatus, initAddr); } ctx->avc.avcDecodeResult = MPEG_AVC_DECODE_SUCCESS; @@ -1186,7 +1186,7 @@ static u32 sceMpegAvcDecodeStop(u32 mpeg, u32 frameWidth, u32 bufferAddr, u32 st } // No last frame generated - Memory::Write_U32(0, statusAddr); + Memory::WriteOrException_U32(0, statusAddr); return hleLogDebug(Log::Mpeg, 0); } @@ -1225,7 +1225,7 @@ static u32 sceMpegUnRegistStream(u32 mpeg, int streamUid) { } static int sceMpegAvcDecodeDetail(u32 mpeg, u32 detailAddr) { - if (!Memory::IsValidAddress(detailAddr)) { + if (!Memory::IsValidRange(detailAddr, 36)) { return hleLogError(Log::Mpeg, -1, "invalid addresses"); } @@ -1234,15 +1234,15 @@ static int sceMpegAvcDecodeDetail(u32 mpeg, u32 detailAddr) { return hleLogWarning(Log::Mpeg, -1, "bad mpeg handle"); } - Memory::Write_U32(ctx->avc.avcDecodeResult, detailAddr + 0); - Memory::Write_U32(ctx->videoFrameCount, detailAddr + 4); - Memory::Write_U32(ctx->avc.avcDetailFrameWidth, detailAddr + 8); - Memory::Write_U32(ctx->avc.avcDetailFrameHeight, detailAddr + 12); - Memory::Write_U32(0, detailAddr + 16); - Memory::Write_U32(0, detailAddr + 20); - Memory::Write_U32(0, detailAddr + 24); - Memory::Write_U32(0, detailAddr + 28); - Memory::Write_U32(ctx->avc.avcFrameStatus, detailAddr + 32); + Memory::WriteUnchecked_U32(ctx->avc.avcDecodeResult, detailAddr + 0); + Memory::WriteUnchecked_U32(ctx->videoFrameCount, detailAddr + 4); + Memory::WriteUnchecked_U32(ctx->avc.avcDetailFrameWidth, detailAddr + 8); + Memory::WriteUnchecked_U32(ctx->avc.avcDetailFrameHeight, detailAddr + 12); + Memory::WriteUnchecked_U32(0, detailAddr + 16); + Memory::WriteUnchecked_U32(0, detailAddr + 20); + Memory::WriteUnchecked_U32(0, detailAddr + 24); + Memory::WriteUnchecked_U32(0, detailAddr + 28); + Memory::WriteUnchecked_U32(ctx->avc.avcFrameStatus, detailAddr + 32); return hleLogDebug(Log::Mpeg, 0); } @@ -1378,7 +1378,7 @@ static int sceMpegInitAu(u32 mpeg, u32 bufferAddr, u32 auPointer) { } static int sceMpegQueryAtracEsSize(u32 mpeg, u32 esSizeAddr, u32 outSizeAddr) { - if (!Memory::IsValidAddress(esSizeAddr) || !Memory::IsValidAddress(outSizeAddr)) { + if (!Memory::IsValid4AlignedAddress(esSizeAddr) || !Memory::IsValid4AlignedAddress(outSizeAddr)) { return hleLogError(Log::Mpeg, -1, "invalid addresses"); } @@ -1387,8 +1387,8 @@ static int sceMpegQueryAtracEsSize(u32 mpeg, u32 esSizeAddr, u32 outSizeAddr) { return hleLogWarning(Log::Mpeg, -1, "bad mpeg handle"); } - Memory::Write_U32(MPEG_ATRAC_ES_SIZE, esSizeAddr); - Memory::Write_U32(MPEG_ATRAC_ES_OUTPUT_SIZE, outSizeAddr); + Memory::WriteUnchecked_U32(MPEG_ATRAC_ES_SIZE, esSizeAddr); + Memory::WriteUnchecked_U32(MPEG_ATRAC_ES_OUTPUT_SIZE, outSizeAddr); return hleLogDebug(Log::Mpeg, 0); } @@ -1611,8 +1611,8 @@ static int sceMpegGetAvcAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr) avcAu.dts = avcAu.pts - videoTimestampStep; avcAu.esBuffer = streamInfo->second.num; avcAu.write(auAddr); - if (Memory::IsValidAddress(attrAddr)) { - Memory::Write_U32(1, attrAddr); + if (Memory::IsValid4AlignedAddress(attrAddr)) { + Memory::WriteUnchecked_U32(1, attrAddr); } return hleDelayResult(hleLogDebug(Log::Mpeg, 0), "mpeg get avc ignore", 100); } @@ -1651,7 +1651,7 @@ static int sceMpegGetAvcAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr) if (result == 0) { // Jeanne d'Arc return 00000000 as attrAddr here and cause WriteMemoryOrRaiseException error if (Memory::IsValidAddress(attrAddr)) { - Memory::Write_U32(1, attrAddr); + Memory::WriteOrException_U32(1, attrAddr); } } @@ -1710,8 +1710,8 @@ static int sceMpegGetAtracAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr) atracAu.dts = atracAu.pts; atracAu.esBuffer = streamInfo->second.num; atracAu.write(auAddr); - if (Memory::IsValidAddress(attrAddr)) { - Memory::Write_U32(0, attrAddr); + if (Memory::IsValid4AlignedAddress(attrAddr)) { + Memory::WriteUnchecked_U32(0, attrAddr); } return hleDelayResult(hleLogDebug(Log::Mpeg, 0), "mpeg get atrac ignore", 100); } @@ -1750,8 +1750,8 @@ static int sceMpegGetAtracAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr) if (result == 0) { // 3rd birthday return 00000000 as attrAddr here and cause WriteMemoryOrRaiseException error - if (Memory::IsValidAddress(attrAddr)) { - Memory::Write_U32(0, attrAddr); + if (Memory::IsValid4AlignedAddress(attrAddr)) { + Memory::WriteUnchecked_U32(0, attrAddr); } } @@ -1761,7 +1761,7 @@ static int sceMpegGetAtracAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr) static int sceMpegQueryPcmEsSize(u32 mpeg, u32 esSizeAddr, u32 outSizeAddr) { - if (!Memory::IsValidAddress(esSizeAddr) || !Memory::IsValidAddress(outSizeAddr)) { + if (!Memory::IsValid4AlignedAddress(esSizeAddr) || !Memory::IsValid4AlignedAddress(outSizeAddr)) { return hleLogError(Log::Mpeg, -1, "invalid addresses"); } @@ -1770,8 +1770,8 @@ static int sceMpegQueryPcmEsSize(u32 mpeg, u32 esSizeAddr, u32 outSizeAddr) return hleLogWarning(Log::Mpeg, -1, "bad mpeg handle"); } - Memory::Write_U32(MPEG_PCM_ES_SIZE, esSizeAddr); - Memory::Write_U32(MPEG_PCM_ES_OUTPUT_SIZE, outSizeAddr); + Memory::WriteUnchecked_U32(MPEG_PCM_ES_SIZE, esSizeAddr); + Memory::WriteUnchecked_U32(MPEG_PCM_ES_OUTPUT_SIZE, outSizeAddr); return hleLogError(Log::Mpeg, 0, "UNIMPL"); } diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index b3ee54fda4..11b9ed20af 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -1521,7 +1521,7 @@ static int sceNetApctlGetState(u32 pStateAddr) { // Valid Arguments if (Memory::IsValidAddress(pStateAddr)) { // Return Thread Status - Memory::Write_U32(NetApctl_GetState(), pStateAddr); + Memory::WriteOrException_U32(NetApctl_GetState(), pStateAddr); // Return Success return hleLogDebug(Log::sceNet, 0); } @@ -1557,7 +1557,7 @@ int NetApctl_GetBSSDescIDListUser(u32 sizeAddr, u32 bufAddr) { int size = Memory::ReadUnchecked_U32(sizeAddr); // Return size required - Memory::Write_U32(entries * userInfoSize, sizeAddr); + Memory::WriteUnchecked_U32(entries * userInfoSize, sizeAddr); if (bufAddr != 0 && Memory::IsValidAddress(sizeAddr)) { int offset = 0; @@ -1570,16 +1570,16 @@ int NetApctl_GetBSSDescIDListUser(u32 sizeAddr, u32 bufAddr) { DEBUG_LOG(Log::sceNet, "%s writing ID#%d to %08x", __FUNCTION__, i, bufAddr + offset); // Pointer to next Network structure in list - Memory::Write_U32((i + 1) * userInfoSize + bufAddr, bufAddr + offset); + Memory::WriteUnchecked_U32((i + 1) * userInfoSize + bufAddr, bufAddr + offset); offset += 4; // Entry ID - Memory::Write_U32(i, bufAddr + offset); + Memory::WriteUnchecked_U32(i, bufAddr + offset); offset += 4; } // Fix the last Pointer if (offset > 0) - Memory::Write_U32(0, bufAddr + offset - userInfoSize); + Memory::WriteUnchecked_U32(0, bufAddr + offset - userInfoSize); } return hleLogInfo(Log::sceNet, 0); @@ -1762,8 +1762,8 @@ static int sceNetUpnpGetNatInfo() { } static int sceNetGetDropRate(u32 dropRateAddr, u32 dropDurationAddr) { - Memory::Write_U32(netDropRate, dropRateAddr); - Memory::Write_U32(netDropDuration, dropDurationAddr); + Memory::WriteOrException_U32(netDropRate, dropRateAddr); + Memory::WriteOrException_U32(netDropDuration, dropDurationAddr); return hleLogInfo(Log::sceNet, 0); } diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 457480f8b1..ddef583492 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -2023,7 +2023,7 @@ int sceNetAdhocctlGetState(u32 ptrToStatus) { int state = NetAdhocctl_GetState(); // Output Adhocctl State - Memory::Write_U32(state, ptrToStatus); + Memory::WriteOrException_U32(state, ptrToStatus); // Return Success return hleLogVerbose(Log::sceNet, 0, "state = %d", state); @@ -5788,7 +5788,7 @@ int sceNetAdhocGetSocketAlert(int id, u32 flagPtr) { return hleLogDebug(Log::sceNet, SCE_NET_ADHOC_ERROR_INVALID_SOCKET_ID, "invalid socket id"); s32_le flg = adhocSockets[id - 1]->flags; - Memory::Write_U32(flg, flagPtr); + Memory::WriteOrException_U32(flg, flagPtr); return hleLogDebug(Log::sceNet, 0, "flags = %08x", flg); } @@ -6216,7 +6216,7 @@ int sceNetAdhocDiscoverInitStart(u32 paramAddr) { Memory::Memset(netAdhocDiscoverBufAddr, 0, bufSize); } // FIME: Not sure what is this address 0x000010B0 used for (current Step may be?), but return 0x80411301 if (*((int *) 0x000010B0) != 0) - //if (Memory::Read_U32(netAdhocDiscoverBufAddr + 0x80) != 0) //if (*((int*)Memory::GetPointer(0x000010B0)) != 0) + //if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) != 0) //if (*((int*)Memory::GetPointer(0x000010B0)) != 0) // return 0x80411301; // Already Initialized/Started? // TODO: Need to findout whether using invalid params or param address will return an error code or not netAdhocDiscoverParam = (SceNetAdhocDiscoverParam*)Memory::GetPointer(paramAddr); @@ -6292,16 +6292,16 @@ int sceNetAdhocDiscoverTerm() { // if (sceKernelCheckThreadStack() < 0x00000FF0) // return 0x80410005; // - // if (!(Memory::Read_U32(netAdhocDiscoverBufAddr + 0x80) > 0 && (Memory::Read_U32(netAdhocDiscoverBufAddr + 0x80) ^ 0x13) > 0)) + // if (!(Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) > 0 && (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) ^ 0x13) > 0)) // return 0x80411301; // Not Initialized/Started yet? // TODO: Use sceNetAdhocctl_lib_1C679240 to remove adhocctl state callback handler setup in sceNetAdhocDiscoverInitStart - // if (Memory::Read_U32(netAdhocDiscoverBufAddr + 0x70) >= 0) { - // LinkDiscoverSkip(Memory::Read_U32(netAdhocDiscoverBufAddr + 0x70)); //sceNetAdhocctl_lib_1C679240 - // Memory::Write_U32(0xffffffff, netAdhocDiscoverBufAddr + 0x70); + // if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x70) >= 0) { + // LinkDiscoverSkip(Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x70)); //sceNetAdhocctl_lib_1C679240 + // Memory::WriteOrException_U32(0xffffffff, netAdhocDiscoverBufAddr + 0x70); // } - // Memory::Write_U32(0, netAdhocDiscoverBufAddr + 0x80); - // Memory::Write_U32(0, netAdhocDiscoverBufAddr + 0xA8); + // Memory::WriteOrException_U32(0, netAdhocDiscoverBufAddr + 0x80); + // Memory::WriteOrException_U32(0, netAdhocDiscoverBufAddr + 0xA8); netAdhocDiscoverStatus = NET_ADHOC_DISCOVER_STATUS_NONE; //if (netAdhocDiscoverParam) netAdhocDiscoverParam->result = NET_ADHOC_DISCOVER_RESULT_NO_PEER_FOUND; // Test: Using result = NET_ADHOC_DISCOVER_RESULT_NO_PEER_FOUND will trigger Legend Of The Dragon to call sceNetAdhocctlGetPeerList after DiscoverTerm @@ -6317,11 +6317,11 @@ int sceNetAdhocDiscoverGetStatus() { DEBUG_LOG(Log::sceNet, "UNIMPL sceNetAdhocDiscoverGetStatus() at %08x", currentMIPS->pc); if (sceKernelCheckThreadStack() < 0x00000FF0) return 0x80410005; - // if (Memory::Read_U32(netAdhocDiscoverBufAddr + 0x80) <= 0) + // if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) <= 0) // return 0; - // if (Memory::Read_U32(netAdhocDiscoverBufAddr + 0x80) <= 0x13) + // if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) <= 0x13) // return 1; - // if (Memory::Read_U32(netAdhocDiscoverBufAddr + 0x80) == 0x13) + // if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) == 0x13) // return 2; return hleLogDebug(Log::sceNet, netAdhocDiscoverStatus); // Returning 2 will trigger Legend Of The Dragon to call sceNetAdhocctlGetPeerList (only happened if it was the first sceNetAdhocDiscoverGetStatus after sceNetAdhocDiscoverInitStart) } @@ -6332,13 +6332,13 @@ int sceNetAdhocDiscoverRequestSuspend() // FIXME: Not sure what is this syscall used for, may be related to Sleep Mode and can be triggered by using Power/Hold Switch? (based on what's written on Dissidia 012) if (sceKernelCheckThreadStack() < 0x00000FF0) return 0x80410005; - // if (Memory::Read_U32(netAdhocDiscoverBufAddr + 0xA4) == 0) + // if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0xA4) == 0) // return 0x80411303; // Already Suspended? - // if (Memory::Read_U32(netAdhocDiscoverBufAddr + 0x80) != 0) + // if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) != 0) // return 0x80411303; // Already Suspended? // int ret = sceNetAdhocctl_lib_1572422C(); // if (ret >= 0) - // Memory::Write_U32(0, netAdhocDiscoverBufAddr + 0xA4); + // Memory::WriteOrException_U32(0, netAdhocDiscoverBufAddr + 0xA4); // return ret; // Since we don't know what this supposed to do, and we currently don't have a working AdhocDiscover yet, may be we should cancel the progress for now? netAdhocDiscoverIsStopping = true; diff --git a/Core/HLE/sceNetResolver.cpp b/Core/HLE/sceNetResolver.cpp index b4547b9289..7eaf796df5 100644 --- a/Core/HLE/sceNetResolver.cpp +++ b/Core/HLE/sceNetResolver.cpp @@ -112,7 +112,7 @@ static int NetResolver_StartNtoA(NetResolver *resolver, u32 hostnamePtr, u32 inA } } net::DNSResolveFree(resolved); - Memory::Write_U32(addr.in.sin_addr.s_addr, inAddrPtr); + Memory::WriteOrException_U32(addr.in.sin_addr.s_addr, inAddrPtr); INFO_LOG(Log::sceNet, "%s - Hostname: %s => IPv4: %s", __FUNCTION__, hostname.c_str(), ip2str(addr.in.sin_addr, false).c_str()); } diff --git a/Core/HLE/sceNp.cpp b/Core/HLE/sceNp.cpp index 2db1d98efc..80e931b2dc 100644 --- a/Core/HLE/sceNp.cpp +++ b/Core/HLE/sceNp.cpp @@ -173,8 +173,8 @@ static int sceNpGetContentRatingFlag(u32 parentalControlAddr, u32 userAgeAddr) INFO_LOG(Log::sceNet, "%s - Parental Control: %d", __FUNCTION__, npParentalControl); INFO_LOG(Log::sceNet, "%s - User Age: %d", __FUNCTION__, npUserAge); - Memory::Write_U32(npParentalControl, parentalControlAddr); - Memory::Write_U32(npUserAge, userAgeAddr); + Memory::WriteOrException_U32(npParentalControl, parentalControlAddr); + Memory::WriteOrException_U32(npUserAge, userAgeAddr); return hleLogWarning(Log::sceNet, 0, "UNTESTED"); } @@ -184,7 +184,7 @@ static int sceNpGetChatRestrictionFlag(u32 flagAddr) if (!Memory::IsValidAddress(flagAddr)) return hleLogError(Log::sceNet, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg"); - Memory::Write_U32(npChatRestriction, flagAddr); + Memory::WriteOrException_U32(npChatRestriction, flagAddr); return hleLogWarning(Log::sceNet, 0, "Chat restriction: %d", npChatRestriction); } diff --git a/Core/HLE/sceRtc.cpp b/Core/HLE/sceRtc.cpp index 8d0969e2c8..8a4111a411 100644 --- a/Core/HLE/sceRtc.cpp +++ b/Core/HLE/sceRtc.cpp @@ -449,7 +449,7 @@ static int sceRtcConvertLocalTimeToUTC(u32 tickLocalPtr,u32 tickUTCPtr) tm *time = localtime(&timezone); srcTick -= time->tm_gmtoff*1000000ULL; #endif - Memory::Write_U64(srcTick, tickUTCPtr); + Memory::WriteUnchecked_U64(srcTick, tickUTCPtr); } else { @@ -902,10 +902,10 @@ static bool rtcParseRFC2822(const char *s, RtcParseResult &r) { static int sceRtcParseDateTime(u32 destTickPtr, u32 dateStringPtr) { - if (!Memory::IsValidAddress(destTickPtr) || !Memory::IsValidAddress(dateStringPtr)) + if (!Memory::IsValid4AlignedRange(destTickPtr, 8) || !Memory::IsValidAddress(dateStringPtr)) return hleLogError(Log::sceRtc, -1, "bad address"); - const char *s = (const char *)Memory::GetPointer(dateStringPtr); + const char *s = Memory::GetCharPointer(dateStringPtr); if (!s) { return hleLogError(Log::sceRtc, -1, "null string"); } @@ -917,7 +917,7 @@ static int sceRtcParseDateTime(u32 destTickPtr, u32 dateStringPtr) u64 ticks = __RtcPspTimeToTicks(r.date); s64 offsetUs = (s64)r.tzOffsetMinutes * 60 * 1000000; ticks -= offsetUs; - Memory::Write_U64(ticks, destTickPtr); + Memory::WriteUnchecked_U64(ticks, destTickPtr); return hleLogDebug(Log::sceRtc, 0); } @@ -927,16 +927,16 @@ static int sceRtcParseDateTime(u32 destTickPtr, u32 dateStringPtr) static int sceRtcGetLastAdjustedTime(u32 tickPtr) { - if (Memory::IsValidAddress(tickPtr)) - Memory::Write_U64(rtcLastAdjustedTicks, tickPtr); + if (Memory::IsValid4AlignedRange(tickPtr, 8)) + Memory::WriteUnchecked_U64(rtcLastAdjustedTicks, tickPtr); DEBUG_LOG(Log::sceRtc, "sceRtcGetLastAdjustedTime(%d)", tickPtr); return 0; } static int sceRtcGetLastReincarnatedTime(u32 tickPtr) { - if (Memory::IsValidAddress(tickPtr)) - Memory::Write_U64(rtcLastReincarnatedTicks, tickPtr); + if (Memory::IsValid4AlignedRange(tickPtr, 8)) + Memory::WriteUnchecked_U64(rtcLastReincarnatedTicks, tickPtr); DEBUG_LOG(Log::sceRtc, "sceRtcGetLastReincarnatedTime(%d)", tickPtr); return 0; } diff --git a/Core/HLE/sceSas.cpp b/Core/HLE/sceSas.cpp index 95515570e0..cf78967e13 100644 --- a/Core/HLE/sceSas.cpp +++ b/Core/HLE/sceSas.cpp @@ -665,7 +665,7 @@ static u32 sceSasGetAllEnvelopeHeights(u32 core, u32 heightsAddr) { __SasDrain(); for (int i = 0; i < PSP_SAS_VOICES_MAX; i++) { int voiceHeight = sas->voices[i].envelope.GetHeight(); - Memory::Write_U32(voiceHeight, heightsAddr + i * 4); + Memory::WriteOrException_U32(voiceHeight, heightsAddr + i * 4); } return hleLogDebug(Log::sceSas, 0); @@ -735,7 +735,7 @@ static u32 __sceSasUnsetATRAC3(u32 core, int voiceNum) { v.on = false; // This unpauses. Some games, like Sol Trigger, depend on this. v.paused = false; - Memory::Write_U32(0, core + 56 * voiceNum + 20); + Memory::WriteOrException_U32(0, core + 56 * voiceNum + 20); return hleLogDebug(Log::sceSas, 0); } diff --git a/Core/HLE/sceSsl.cpp b/Core/HLE/sceSsl.cpp index f1c668c995..e20ae2d388 100644 --- a/Core/HLE/sceSsl.cpp +++ b/Core/HLE/sceSsl.cpp @@ -23,19 +23,17 @@ #include "Core/MemMap.h" #include "Core/HLE/sceSsl.h" -bool isSslInit; -u32 maxMemSize; -u32 currentMemSize; +static bool isSslInit; +static u32 maxMemSize; +static u32 currentMemSize; -void __SslInit() -{ +void __SslInit() { isSslInit = 0; maxMemSize = 0; currentMemSize = 0; } -void __SslDoState(PointerWrap &p) -{ +void __SslDoState(PointerWrap &p) { auto s = p.Section("sceSsl", 1); if (!s) return; @@ -45,67 +43,52 @@ void __SslDoState(PointerWrap &p) Do(p, currentMemSize); } -static int sceSslInit(int heapSize) -{ - DEBUG_LOG(Log::HLE, "sceSslInit %d", heapSize); - if (isSslInit) - { +static int sceSslInit(int heapSize) { + if (isSslInit) { return SCE_SSL_ERROR_ALREADY_INIT; } - if (heapSize <= 0) - { + if (heapSize <= 0) { return SCE_SSL_ERROR_INVALID_PARAMETER; } maxMemSize = heapSize; currentMemSize = heapSize / 2; // As per jpcsp isSslInit = true; - return 0; + return hleLogDebug(Log::HLE, 0); } -static int sceSslEnd() -{ +static int sceSslEnd() { DEBUG_LOG(Log::HLE, "sceSslEnd"); - if (!isSslInit) - { + if (!isSslInit) { return SCE_SSL_ERROR_NOT_INIT; } isSslInit = false; - return 0; + return hleLogDebug(Log::HLE, 0); } -static int sceSslGetUsedMemoryMax(u32 maxMemPtr) -{ - DEBUG_LOG(Log::HLE, "sceSslGetUsedMemoryMax %d", maxMemPtr); - if (!isSslInit) - { +static int sceSslGetUsedMemoryMax(u32 maxMemPtr) { + if (!isSslInit) { return SCE_SSL_ERROR_NOT_INIT; } - if (Memory::IsValidAddress(maxMemPtr)) - { - Memory::Write_U32(maxMemSize, maxMemPtr); + if (Memory::IsValid4AlignedAddress(maxMemPtr)) { + Memory::WriteUnchecked_U32(maxMemSize, maxMemPtr); } - return 0; + return hleLogDebug(Log::HLE, 0); } -static int sceSslGetUsedMemoryCurrent(u32 currentMemPtr) -{ - DEBUG_LOG(Log::HLE, "sceSslGetUsedMemoryCurrent %d", currentMemPtr); - if (!isSslInit) - { +static int sceSslGetUsedMemoryCurrent(u32 currentMemPtr) { + if (!isSslInit) { return SCE_SSL_ERROR_NOT_INIT; } - if (Memory::IsValidAddress(currentMemPtr)) - { - Memory::Write_U32(currentMemSize, currentMemPtr); + if (Memory::IsValid4AlignedAddress(currentMemPtr)) { + Memory::WriteUnchecked_U32(currentMemSize, currentMemPtr); } - return 0; + return hleLogDebug(Log::HLE, 0); } -const HLEFunction sceSsl[] = -{ +const HLEFunction sceSsl[] = { {0X957ECBE2, &WrapI_I, "sceSslInit", 'i', "i"}, {0X191CDEFF, &WrapI_V, "sceSslEnd", 'i', "" }, {0X5BFB6B61, nullptr, "sceSslGetNotAfter", '?', "" }, @@ -120,7 +103,6 @@ const HLEFunction sceSsl[] = {0XF57765D3, nullptr, "sceSslGetKeyUsage", '?', "" }, }; -void Register_sceSsl() -{ +void Register_sceSsl() { RegisterHLEModule("sceSsl", ARRAY_SIZE(sceSsl), sceSsl); } diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index 864bfb0496..34eb6a169b 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -1090,7 +1090,7 @@ static int sceUtilityGetNetParam(int id, int param, u32 dataAddr) { static int sceUtilityGetNetParamLatestID(u32 idAddr) { DEBUG_LOG(Log::sceUtility, "sceUtilityGetNetParamLatestID(%08x)", idAddr); // This function is saving the last net param ID (non-zero ID?) and not the number of net configurations. - Memory::Write_U32(netParamLatestId, idAddr); + Memory::WriteOrException_U32(netParamLatestId, idAddr); return 0; } @@ -1269,7 +1269,7 @@ static u32 sceUtilityGetSystemParamInt(u32 id, u32 destaddr) { // FIXME: Outputted channel (might be unchanged?) either 0 when not connected to a group yet (ie. adhocctlState == ADHOCCTL_STATE_DISCONNECTED), // or -1 (0xFFFFFFFF) when a scan is in progress (ie. adhocctlState == ADHOCCTL_STATE_SCANNING), // or 0x60 early when in connected state (ie. adhocctlState == ADHOCCTL_STATE_CONNECTED) right after Creating a group, regardless the channel settings. - Memory::Write_U32(param, destaddr); + Memory::WriteOrException_U32(param, destaddr); return 0x800ADF4; } break; @@ -1309,7 +1309,7 @@ static u32 sceUtilityGetSystemParamInt(u32 id, u32 destaddr) { return hleLogError(Log::sceUtility, SCE_ERROR_UTILITY_INVALID_SYSTEM_PARAM_ID); } - Memory::Write_U32(param, destaddr); + Memory::WriteOrException_U32(param, destaddr); return hleLogInfo(Log::sceUtility, 0, "(%s): %08x", SystemParamToString(id), param); } diff --git a/Core/HW/SimpleAudioDec.cpp b/Core/HW/SimpleAudioDec.cpp index a5d46c8e5e..56d017e6c2 100644 --- a/Core/HW/SimpleAudioDec.cpp +++ b/Core/HW/SimpleAudioDec.cpp @@ -496,7 +496,7 @@ u32 AuCtx::AuDecode(u32 pcmAddr) { int outpcmbufsize = 0; if (pcmAddr) - Memory::Write_U32(outptr, pcmAddr); + Memory::WriteOrException_U32(outptr, pcmAddr); // Decode a single frame in sourcebuff and output into PCMBuf. if (!sourcebuff.empty()) { diff --git a/Core/LuaContext.cpp b/Core/LuaContext.cpp index 973cf9ea60..193c06275e 100644 --- a/Core/LuaContext.cpp +++ b/Core/LuaContext.cpp @@ -55,7 +55,7 @@ static int r32(int address) { static void w32(int address, int value) { if (Memory::IsValid4AlignedAddress(address)) { - Memory::Write_U32(value, address); // NOTE: These are backwards for historical reasons. + Memory::WriteUnchecked_U32(value, address); // NOTE: These are backwards for historical reasons. } else { g_lua.Print(LogLineType::Error, StringFromFormat("w32: bad address %08x trying to write %08x", address, value)); } diff --git a/Core/MIPS/ARM/ArmCompVFPU.cpp b/Core/MIPS/ARM/ArmCompVFPU.cpp index 021d1f7f7b..05ddf8464d 100644 --- a/Core/MIPS/ARM/ArmCompVFPU.cpp +++ b/Core/MIPS/ARM/ArmCompVFPU.cpp @@ -281,7 +281,7 @@ namespace MIPSComp } break; - case 58: //sv.s // Memory::Write_U32(VI(vt), addr); + case 58: //sv.s { if (!gpr.IsImm(rs) && jo.cachePointers && g_Config.bFastMemory && (offset & 3) == 0 && offset < 0x400 && offset > -0x400) { gpr.MapRegAsPointer(rs); diff --git a/Core/MIPS/x86/JitSafeMem.cpp b/Core/MIPS/x86/JitSafeMem.cpp index c0644eb535..91ef1200b4 100644 --- a/Core/MIPS/x86/JitSafeMem.cpp +++ b/Core/MIPS/x86/JitSafeMem.cpp @@ -346,7 +346,7 @@ void JitSafeMem::IndirectCALL(const void *safeFunc) { void JitSafeMem::Finish() { - // Memory::Read_U32/etc. may have tripped coreState. + // Memory::ReadOrException_U32/etc. may have tripped coreState. if (needsCheck_ && !g_Config.bIgnoreBadMemAccess) jit_->js.afterOp |= JitState::AFTER_CORE_STATE; if (needsSkip_) @@ -365,18 +365,18 @@ void JitSafeMemFuncs::Init(ThunkManager *thunks) { BeginWrite(1024); readU32 = GetCodePtr(); - CreateReadFunc(32, (const void *)&Memory::Read_U32); + CreateReadFunc(32, (const void *)&Memory::ReadOrException_U32); readU16 = GetCodePtr(); - CreateReadFunc(16, (const void *)&Memory::Read_U16); + CreateReadFunc(16, (const void *)&Memory::ReadOrException_U16); readU8 = GetCodePtr(); - CreateReadFunc(8, (const void *)&Memory::Read_U8); + CreateReadFunc(8, (const void *)&Memory::ReadOrException_U8); writeU32 = GetCodePtr(); - CreateWriteFunc(32, (const void *)&Memory::Write_U32); + CreateWriteFunc(32, (const void *)&Memory::WriteOrException_U32); writeU16 = GetCodePtr(); - CreateWriteFunc(16, (const void *)&Memory::Write_U16); + CreateWriteFunc(16, (const void *)&Memory::WriteOrException_U16); writeU8 = GetCodePtr(); - CreateWriteFunc(8, (const void *)&Memory::Write_U8); + CreateWriteFunc(8, (const void *)&Memory::WriteOrException_U8); EndWrite(); } diff --git a/Core/MemMap.h b/Core/MemMap.h index 29bca2d6d6..76c421f659 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -137,9 +137,9 @@ void Write_Opcode_JIT(const u32 _Address, const Opcode& _Value); Opcode Read_Instruction(const u32 _Address, bool resolveReplacements = false); Opcode ReadUnchecked_Instruction(const u32 _Address, bool resolveReplacements = false); -u8 Read_U8(const u32 _Address); -u16 Read_U16(const u32 _Address); -u32 Read_U32(const u32 _Address); +u8 ReadOrException_U8(const u32 _Address); +u16 ReadOrException_U16(const u32 _Address); +u32 ReadOrException_U32(const u32 _Address); inline u8* GetPointerWriteUnchecked(const u32 address) { #ifdef MASKED_PSP_MEMORY @@ -237,10 +237,10 @@ inline void WriteUnchecked_U8(u8 data, u32 address) { #endif } -void Write_U8(const u8 data, const u32 address); -void Write_U16(const u16 data, const u32 address); -void Write_U32(const u32 data, const u32 address); -void Write_U64(const u64 data, const u32 address); +void WriteOrException_U8(const u8 data, const u32 address); +void WriteOrException_U16(const u16 data, const u32 address); +void WriteOrException_U32(const u32 data, const u32 address); +void WriteOrException_U64(const u64 data, const u32 address); u8* GetPointerWrite(const u32 address); const u8* GetPointer(const u32 address); diff --git a/Core/MemMapFunctions.cpp b/Core/MemMapFunctions.cpp index c2ef321593..363a997f6d 100644 --- a/Core/MemMapFunctions.cpp +++ b/Core/MemMapFunctions.cpp @@ -124,19 +124,19 @@ bool IsScratchpadAddress(const u32 address) { return (address & 0xBFFFC000) == 0x00010000; } -u8 Read_U8(const u32 address) { +u8 ReadOrException_U8(const u32 address) { u8 value = 0; ReadMemoryOrRaiseException(value, address); return (u8)value; } -u16 Read_U16(const u32 address) { +u16 ReadOrException_U16(const u32 address) { u16_le value = 0; ReadMemoryOrRaiseException(value, address); return (u16)value; } -u32 Read_U32(const u32 address) { +u32 ReadOrException_U32(const u32 address) { u32_le value = 0; ReadMemoryOrRaiseException(value, address); return value; @@ -148,19 +148,19 @@ u64 Read_U64(const u32 address) { return value; } -void Write_U8(const u8 _Data, const u32 address) { +void WriteOrException_U8(const u8 _Data, const u32 address) { WriteMemoryOrRaiseException(address, _Data); } -void Write_U16(const u16 _Data, const u32 address) { +void WriteOrException_U16(const u16 _Data, const u32 address) { WriteMemoryOrRaiseException(address, _Data); } -void Write_U32(const u32 _Data, const u32 address) { +void WriteOrException_U32(const u32 _Data, const u32 address) { WriteMemoryOrRaiseException(address, _Data); } -void Write_U64(const u64 _Data, const u32 address) { +void WriteOrException_U64(const u64 _Data, const u32 address) { WriteMemoryOrRaiseException(address, _Data); } diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index e3d28df4a8..6fb7dd7e0a 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -156,7 +156,7 @@ void PPGeSetTexture(u32 dataAddr, int width, int height); //only 0xFFFFFF of data is used static void WriteCmd(u8 cmd, u32 data) { - Memory::Write_U32((cmd << 24) | (data & 0xFFFFFF), dlWritePtr); + Memory::WriteUnchecked_U32((cmd << 24) | (data & 0xFFFFFF), dlWritePtr); dlWritePtr += 4; _dbg_assert_(dlWritePtr <= dlPtr + dlSize); } diff --git a/GPU/Debugger/Playback.cpp b/GPU/Debugger/Playback.cpp index 017102ca04..b954703332 100644 --- a/GPU/Debugger/Playback.cpp +++ b/GPU/Debugger/Playback.cpp @@ -434,7 +434,7 @@ void DumpExecute::Registers(u32 ptr, u32 sz) { } execListPos = execListBuf; - Memory::Write_U32(GE_CMD_NOP << 24, execListPos); + Memory::WriteUnchecked_U32(GE_CMD_NOP << 24, execListPos); execListPos += 4; // TODO: Why do we disable interrupts here? @@ -447,8 +447,8 @@ void DumpExecute::Registers(u32 ptr, u32 sz) { // Validate space for jump. u32 allocSize = pendingSize + sz + 8; if (execListPos + allocSize >= execListBuf + LIST_BUF_SIZE) { - Memory::Write_U32((GE_CMD_BASE << 24) | ((execListBuf >> 8) & 0x00FF0000), execListPos); - Memory::Write_U32((GE_CMD_JUMP << 24) | (execListBuf & 0x00FFFFFF), execListPos + 4); + Memory::WriteUnchecked_U32((GE_CMD_BASE << 24) | ((execListBuf >> 8) & 0x00FF0000), execListPos); + Memory::WriteUnchecked_U32((GE_CMD_JUMP << 24) | (execListBuf & 0x00FFFFFF), execListPos + 4); execListPos = execListBuf; lastBase_ = execListBuf & 0xFF000000; @@ -506,8 +506,8 @@ void DumpExecute::SubmitListEnd() { } // There's always space for the end, same size as a jump. - Memory::Write_U32(GE_CMD_FINISH << 24, execListPos); - Memory::Write_U32(GE_CMD_END << 24, execListPos + 4); + Memory::WriteUnchecked_U32(GE_CMD_FINISH << 24, execListPos); + Memory::WriteUnchecked_U32(GE_CMD_END << 24, execListPos + 4); execListPos += 8; for (int i = 0; i < 8; ++i) diff --git a/UI/ImDebugger/ImDisasmView.cpp b/UI/ImDebugger/ImDisasmView.cpp index b4aaac9fbe..2e2e9d58d8 100644 --- a/UI/ImDebugger/ImDisasmView.cpp +++ b/UI/ImDebugger/ImDisasmView.cpp @@ -782,8 +782,10 @@ void ImDisasmView::PopupMenu(ImControl &control) { assembleOpcode(curAddress_, ""); } if (ImGui::MenuItem("NOP instructions (destructive)")) { - for (u32 addr = selectRangeStart_; addr < selectRangeEnd_; addr += 4) { - Memory::Write_U32(0, addr); + if (Memory::IsValid4AlignedRange(selectRangeStart_, selectRangeEnd_ - selectRangeStart_)) { + for (u32 addr = selectRangeStart_; addr < selectRangeEnd_; addr += 4) { + Memory::WriteUnchecked_U32(0, addr); + } } if (currentMIPS) { currentMIPS->InvalidateICache(selectRangeStart_, selectRangeEnd_ - selectRangeStart_); diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index 214f64cd88..2fcde81d91 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -954,8 +954,10 @@ void CtrlDisAsmView::NopInstructions(u32 selectRangeStart, u32 selectRangeEnd) { // Route the memory writes to the CPU thread instead of poking at it directly from this GUI // thread - see Core_RunOnCPUThread() in Core.h. Core_RunOnCPUThread([&] { - for (u32 addr = selectRangeStart; addr < selectRangeEnd; addr += 4) { - Memory::Write_U32(0, addr); + if (Memory::IsValidRange(selectRangeStart, selectRangeEnd - selectRangeStart)) { + for (u32 addr = selectRangeStart; addr < selectRangeEnd; addr += 4) { + Memory::WriteUnchecked_U32(0, addr); + } } if (currentMIPS) {