More MIPSState * plumbing (manual)

This commit is contained in:
Henrik Rydgård committed 2026-08-12 14:02:19 +02:00
1 parent c9c886d78f
commit e9a3449ede
37 files changed
+130 -123

No files matched your search

+29 -32
View File
@@ -75,7 +75,7 @@ bool SetClockFrequencyHz(int cpuHz) {
// When the mhz changes, we keep track of what "time" it was before hand.
// This way, time always moves forward, even if mhz is changed.
lastGlobalTimeUs = GetGlobalTimeUs();
lastGlobalTimeTicks = GetTicks();
lastGlobalTimeTicks = GetTicks(currentMIPS);
CPU_HZ = cpuHz;
@@ -93,13 +93,13 @@ u64 GetGlobalTimeUsScaled() {
}
u64 GetGlobalTimeUs() {
s64 ticksSinceLast = GetTicks() - lastGlobalTimeTicks;
s64 ticksSinceLast = GetTicks(currentMIPS) - lastGlobalTimeTicks;
int freq = GetClockFrequencyHz();
s64 usSinceLast = ticksSinceLast * 1000000 / freq;
if (ticksSinceLast > UINT_MAX) {
// Adjust the calculated value to avoid overflow errors.
lastGlobalTimeUs += usSinceLast;
lastGlobalTimeTicks = GetTicks();
lastGlobalTimeTicks = GetTicks(currentMIPS);
usSinceLast = 0;
}
return lastGlobalTimeUs + usSinceLast;
@@ -178,9 +178,8 @@ void UnregisterAllEvents() {
restoredEventTypes.clear();
}
void Init()
{
currentMIPS->downcount = INITIAL_SLICE_LENGTH;
void Init(MIPSState *mips) {
mips->downcount = INITIAL_SLICE_LENGTH;
slicelength = INITIAL_SLICE_LENGTH;
globalTimer = 0;
idledCycles = 0;
@@ -201,18 +200,16 @@ void Shutdown()
}
}
u64 GetTicks()
{
if (currentMIPS) {
return (u64)globalTimer + slicelength - currentMIPS->downcount;
u64 GetTicks(MIPSState *mips) {
if (mips) {
return (u64)globalTimer + slicelength - mips->downcount;
} else {
// Reporting can actually end up here during weird task switching sequences on Android
return false;
}
}
u64 GetIdleTicks()
{
u64 GetIdleTicks() {
return (u64)idledCycles;
}
@@ -252,7 +249,7 @@ void ScheduleEvent(s64 cyclesIntoFuture, int event_type, u64 userdata)
Event *ne = GetNewEvent();
ne->userdata = userdata;
ne->type = event_type;
ne->time = GetTicks() + cyclesIntoFuture;
ne->time = GetTicks(currentMIPS) + cyclesIntoFuture;
AddEventToQueue(ne);
}
@@ -266,7 +263,7 @@ s64 UnscheduleEvent(int event_type, u64 userdata)
{
if (first->type == event_type && first->userdata == userdata)
{
result = first->time - GetTicks();
result = first->time - GetTicks(currentMIPS);
Event *next = first->next;
FreeEvent(first);
@@ -285,7 +282,7 @@ s64 UnscheduleEvent(int event_type, u64 userdata)
{
if (ptr->type == event_type && ptr->userdata == userdata)
{
result = ptr->time - GetTicks();
result = ptr->time - GetTicks(currentMIPS);
prev->next = ptr->next;
FreeEvent(ptr);
@@ -352,12 +349,12 @@ void RemoveEvent(int event_type)
void ProcessEvents() {
while (first) {
if (first->time <= (s64)GetTicks()) {
// INFO_LOG(Log::CPU, "%s (%lld, %lld) ", first->name ? first->name : "?", (u64)GetTicks(), (u64)first->time);
if (first->time <= (s64)GetTicks(currentMIPS)) {
// INFO_LOG(Log::CPU, "%s (%lld, %lld) ", first->name ? first->name : "?", (u64)GetTicks(currentMIPS), (u64)first->time);
Event *evt = first;
first = first->next;
if (evt->type >= 0 && evt->type < (int)event_types.size()) {
event_types[evt->type].callback(evt->userdata, (int)(GetTicks() - evt->time));
event_types[evt->type].callback(evt->userdata, (int)(GetTicks(currentMIPS) - evt->time));
} else {
_dbg_assert_msg_(false, "Bad event type %d", evt->type);
}
@@ -369,12 +366,11 @@ void ProcessEvents() {
}
}
void ForceCheck()
{
int cyclesExecuted = slicelength - currentMIPS->downcount;
void ForceCheck(MIPSState *mips) {
int cyclesExecuted = slicelength - mips->downcount;
globalTimer += cyclesExecuted;
// This will cause us to check for new events immediately.
currentMIPS->downcount = -1;
mips->downcount = -1;
// But let's not eat a bunch more time in Advance() because of this.
slicelength = -1;
@@ -384,10 +380,11 @@ void ForceCheck()
}
void Advance() {
MIPSState *mips = currentMIPS; // TODO: Move to parameter
PROFILE_THIS_SCOPE("advance");
int cyclesExecuted = slicelength - currentMIPS->downcount;
int cyclesExecuted = slicelength - mips->downcount;
globalTimer += cyclesExecuted;
currentMIPS->downcount = slicelength;
mips->downcount = slicelength;
ProcessEvents();
@@ -395,7 +392,7 @@ void Advance() {
// This should never happen in PPSSPP.
if (slicelength < 10000) {
slicelength += 10000;
currentMIPS->downcount += 10000;
mips->downcount += 10000;
}
} else {
// Note that events can eat cycles as well.
@@ -405,7 +402,7 @@ void Advance() {
const int diff = target - slicelength;
slicelength += diff;
currentMIPS->downcount += diff;
mips->downcount += diff;
}
}
@@ -417,13 +414,13 @@ void LogPendingEvents() {
}
}
void Idle(int maxIdle) {
int cyclesDown = currentMIPS->downcount;
void Idle(MIPSState *mips, int maxIdle) {
int cyclesDown = mips->downcount;
if (maxIdle != 0 && cyclesDown > maxIdle)
cyclesDown = maxIdle;
if (first && cyclesDown > 0) {
int cyclesExecuted = slicelength - currentMIPS->downcount;
int cyclesExecuted = slicelength - mips->downcount;
int cyclesNextEvent = (int) (first->time - globalTimer);
if (cyclesNextEvent < cyclesExecuted + cyclesDown)
@@ -437,9 +434,9 @@ void Idle(int maxIdle) {
// VERBOSE_LOG(Log::CPU, "Idle for %i cycles! (%f ms)", cyclesDown, cyclesDown / (float)(CPU_HZ * 0.001f));
idledCycles += cyclesDown;
currentMIPS->downcount -= cyclesDown;
if (currentMIPS->downcount == 0)
currentMIPS->downcount = -1;
mips->downcount -= cyclesDown;
if (mips->downcount == 0)
mips->downcount = -1;
}
std::string GetScheduledEventsSummary() {
+6 -4
View File
@@ -72,6 +72,8 @@ inline s64 cyclesToUs(s64 cycles) {
return (cycles * 1000000) / CPU_HZ;
}
class MIPSState;
namespace CoreTiming {
typedef void (*TimedCallback)(u64 userdata, int cyclesLate);
@@ -87,10 +89,10 @@ namespace CoreTiming {
};
typedef LinkedListItem<BaseEvent> Event;
void Init();
void Init(MIPSState *mips);
void Shutdown();
u64 GetTicks();
u64 GetTicks(MIPSState *mips);
u64 GetIdleTicks();
u64 GetGlobalTimeUs();
u64 GetGlobalTimeUsScaled();
@@ -112,10 +114,10 @@ namespace CoreTiming {
void RemoveEvent(int event_type);
bool IsScheduled(int event_type);
void Advance();
void ForceCheck();
void ForceCheck(MIPSState *mips);
// Pretend that the main CPU has executed enough cycles to reach the next event.
void Idle(int maxIdle = 0);
void Idle(MIPSState *mips, int maxIdle = 0);
// Clear all pending events. This should ONLY be done on exit or state load.
void ClearPendingEvents();
+2 -2
View File
@@ -495,12 +495,12 @@ BreakAction BreakpointManager::ExecOpMemCheck(u32 address, u32 pc) {
void BreakpointManager::SetSkipFirst(u32 pc) {
breakSkipFirstAt_ = pc;
breakSkipFirstTicks_ = CoreTiming::GetTicks();
breakSkipFirstTicks_ = CoreTiming::GetTicks(currentMIPS);
}
u32 BreakpointManager::CheckSkipFirst() {
u32 pc = breakSkipFirstAt_;
if (breakSkipFirstTicks_ == CoreTiming::GetTicks())
if (breakSkipFirstTicks_ == CoreTiming::GetTicks(currentMIPS))
return pc;
return 0;
}
+2 -2
View File
@@ -501,7 +501,7 @@ void NotifyMemInfoPC(MemBlockFlags flags, uint32_t start, uint32_t size, uint32_
// When the setting is off, we skip smaller info to keep things fast.
if (MemBlockInfoDetailed(size) && flags != MemBlockFlags::READ) {
PendingNotifyMem info{ flags, start, size };
info.ticks = CoreTiming::GetTicks();
info.ticks = CoreTiming::GetTicks(currentMIPS);
info.pc = pc;
size_t copyLength = strLength;
@@ -565,7 +565,7 @@ void NotifyMemInfoCopy(uint32_t destPtr, uint32_t srcPtr, uint32_t size, const c
PendingNotifyMem info{ MemBlockFlags::WRITE, destPtr, size };
info.copySrc = srcPtr;
info.ticks = CoreTiming::GetTicks();
info.ticks = CoreTiming::GetTicks(currentMIPS);
info.pc = currentMIPS->pc;
// Store the prefix for now. The correct tag will be calculated on flush.
@@ -126,7 +126,7 @@ void WebSocketCPUStatus(DebuggerRequest &req) {
// Avoid NULL deference.
json.writeUint("pc", pspInited ? currentMIPS->pc : 0);
// A double ought to be good enough for a 156 day debug session.
json.writeFloat("ticks", pspInited ? CoreTiming::GetTicks() : 0);
json.writeFloat("ticks", pspInited ? CoreTiming::GetTicks(currentMIPS) : 0);
}
// Retrieve all regs and their values (cpu.getAllRegs)
@@ -32,7 +32,7 @@ struct CPUSteppingEvent {
j.writeString("event", "cpu.stepping");
j.writeUint("pc", currentMIPS->pc);
// A double ought to be good enough for a 156 day debug session.
j.writeFloat("ticks", CoreTiming::GetTicks());
j.writeFloat("ticks", CoreTiming::GetTicks(currentMIPS));
if (reason_.reason != BreakReason::None) {
j.writeString("reason", BreakReasonToString(reason_.reason));
j.writeUint("relatedAddress", reason_.relatedAddress);
+2 -2
View File
@@ -85,7 +85,7 @@ void PSPDialog::UpdateCommon() {
}
PSPDialog::DialogStatus PSPDialog::GetStatus() {
if (pendingStatusTicks != 0 && CoreTiming::GetTicks() >= pendingStatusTicks) {
if (pendingStatusTicks != 0 && CoreTiming::GetTicks(currentMIPS) >= pendingStatusTicks) {
bool changeAllowed = true;
if (pendingStatus == SCE_UTILITY_STATUS_NONE && status == SCE_UTILITY_STATUS_SHUTDOWN) {
FinishVolatile();
@@ -126,7 +126,7 @@ void PSPDialog::ChangeStatus(DialogStatus newStatus, int delayUs) {
pendingStatusTicks = 0;
} else {
pendingStatus = newStatus;
pendingStatusTicks = CoreTiming::GetTicks() + usToCycles(delayUs);
pendingStatusTicks = CoreTiming::GetTicks(currentMIPS) + usToCycles(delayUs);
}
}
+1 -1
View File
@@ -770,7 +770,7 @@ static void hleFinishSyscall(const HLEFunction *info) {
}
if (hleAfterSyscall & HLE_AFTER_CORETIMING_FORCE_CHECK) {
CoreTiming::ForceCheck();
CoreTiming::ForceCheck(currentMIPS);
}
if ((hleAfterSyscall & HLE_AFTER_SKIP_DEADBEEF) == 0)
+2 -2
View File
@@ -144,7 +144,7 @@ WaitBeginEndCallbackResult WaitBeginCallback(SceUID threadID, SceUID prevCallbac
u64 pausedTimeout = 0;
if (doTimeout && waitTimer != -1) {
s64 cyclesLeft = CoreTiming::UnscheduleEvent(waitTimer, threadID);
pausedTimeout = CoreTiming::GetTicks() + cyclesLeft;
pausedTimeout = CoreTiming::GetTicks(currentMIPS) + cyclesLeft;
}
if (!WaitPauseHelperUpdate(pauseKey, threadID, waitingThreads, pausedWaits, pausedTimeout)) {
@@ -214,7 +214,7 @@ WaitBeginEndCallbackResult WaitEndCallback(SceUID threadID, SceUID prevCallbackI
}
// We only check if it timed out if it couldn't unlock.
s64 cyclesLeft = waitDeadline - CoreTiming::GetTicks();
s64 cyclesLeft = waitDeadline - CoreTiming::GetTicks(currentMIPS);
if (cyclesLeft < 0 && waitDeadline != 0) {
if (timeoutPtr != 0 && waitTimer != -1) {
Memory::WriteOrException_U32(0, timeoutPtr);
+4 -4
View File
@@ -284,7 +284,7 @@ void __DisplayDoState(PointerWrap &p) {
}
if (s < 7) {
u64 now = CoreTiming::GetTicks();
u64 now = CoreTiming::GetTicks(currentMIPS);
lastFlipCycles = now;
nextFlipCycles = now;
} else {
@@ -796,7 +796,7 @@ static u32 sceDisplayIsVblank() {
}
void __DisplayWaitForVblanks(const char *reason, int vblanks, bool callbacks) {
const s64 ticksIntoFrame = CoreTiming::GetTicks() - DisplayFrameStartTicks();
const s64 ticksIntoFrame = CoreTiming::GetTicks(currentMIPS) - DisplayFrameStartTicks();
const s64 cyclesToNextVblank = msToCycles(frameMs) - ticksIntoFrame;
// These syscalls take about 115 us, so if the next vblank is before then, we're waiting extra.
@@ -905,7 +905,7 @@ int sceDisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int sync)
// Otherwise it'll always be ahead if the game messes up even once.
const s64 LEEWAY_CYCLES_PER_FLIP = usToCycles(10);
u64 now = CoreTiming::GetTicks();
u64 now = CoreTiming::GetTicks(currentMIPS);
s64 cyclesAhead = nextFlipCycles - now;
if (cyclesAhead > FLIP_DELAY_CYCLES_MIN) {
if (lastFlipsTooFrequent >= FLIP_DELAY_MIN_FLIPS) {
@@ -1078,7 +1078,7 @@ static u32 sceDisplayGetMode(u32 modeAddr, u32 widthAddr, u32 heightAddr) {
}
static u32 sceDisplayIsVsync() {
u64 now = CoreTiming::GetTicks();
u64 now = CoreTiming::GetTicks(currentMIPS);
u64 start = DisplayFrameStartTicks() + msToCycles(vsyncStartMs);
u64 end = DisplayFrameStartTicks() + msToCycles(vsyncEndMs);
+3 -3
View File
@@ -66,7 +66,7 @@ static int __DmacMemcpy(u32 dst, u32 src, u32 size) {
if (size >= 272) {
// Approx. 225 MiB/s or 235929600 B/s, so let's go with 236 B/us.
int delayUs = size / 236;
dmacMemcpyDeadline = CoreTiming::GetTicks() + usToCycles(delayUs);
dmacMemcpyDeadline = CoreTiming::GetTicks(currentMIPS) + usToCycles(delayUs);
return delayUs;
} else {
return 0;
@@ -85,7 +85,7 @@ static u32 sceDmacMemcpy(u32 dst, u32 src, u32 size) {
return hleLogError(Log::HLE, SCE_KERNEL_ERROR_PRIV_REQUIRED, "illegal size");
}
if (dmacMemcpyDeadline > CoreTiming::GetTicks()) {
if (dmacMemcpyDeadline > CoreTiming::GetTicks(currentMIPS)) {
WARN_LOG(Log::HLE, "sceDmacMemcpy(dest=%08x, src=%08x, size=%d): overlapping read", dst, src, size);
// TODO: Should block, seems like copy doesn't start until previous finishes.
// Might matter for overlapping copies.
@@ -107,7 +107,7 @@ static u32 sceDmacTryMemcpy(u32 dst, u32 src, u32 size) {
return hleLogError(Log::HLE, SCE_KERNEL_ERROR_PRIV_REQUIRED, "illegal size");
}
if (dmacMemcpyDeadline > CoreTiming::GetTicks()) {
if (dmacMemcpyDeadline > CoreTiming::GetTicks(currentMIPS)) {
return hleLogDebug(Log::HLE, SCE_KERNEL_ERROR_BUSY, "busy");
}
+4 -4
View File
@@ -274,7 +274,7 @@ void __GeShutdown() {
bool __GeTriggerSync(GPUSyncType type, int id, u64 atTicks) {
u64 userdata = (u64)id << 32 | (u64)type;
s64 future = atTicks - CoreTiming::GetTicks();
s64 future = atTicks - CoreTiming::GetTicks(currentMIPS);
if (type == GPU_SYNC_DRAW) {
s64 left = CoreTiming::UnscheduleEvent(geSyncEvent, userdata);
if (left > future)
@@ -293,7 +293,7 @@ bool __GeTriggerInterrupt(int listid, u32 pc, u64 atTicks) {
ge_pending_cb.push_back(intrdata);
u64 userdata = (u64)listid << 32 | (u64) pc;
CoreTiming::ScheduleEvent(atTicks - CoreTiming::GetTicks(), geInterruptEvent, userdata);
CoreTiming::ScheduleEvent(atTicks - CoreTiming::GetTicks(currentMIPS), geInterruptEvent, userdata);
return true;
}
@@ -370,14 +370,14 @@ u32 sceGeListEnQueue(u32 listAddress, u32 stallAddress, int callbackId, u32 optP
hleCoreTimingForceCheck();
DEBUG_LOG(Log::sceGe,
"%08x=sceGeListEnQueue(addr=%08x, stall=%08x, cbid=%08x, param=%08x) ticks=%lld", listID,
listAddress, stallAddress, callbackId, optParamAddr, (long long)CoreTiming::GetTicks());
listAddress, stallAddress, callbackId, optParamAddr, (long long)CoreTiming::GetTicks(currentMIPS));
return hleNoLog(listID); // We already logged above, logs get confusing if we use hleLogSuccess.
}
u32 sceGeListEnQueueHead(u32 listAddress, u32 stallAddress, int callbackId, u32 optParamAddr) {
DEBUG_LOG(Log::sceGe,
"sceGeListEnQueueHead(addr=%08x, stall=%08x, cbid=%08x, param=%08x) ticks=%lld",
listAddress, stallAddress, callbackId, optParamAddr, (long long)CoreTiming::GetTicks());
listAddress, stallAddress, callbackId, optParamAddr, (long long)CoreTiming::GetTicks(currentMIPS));
auto optParam = PSPPointer<PspGeListArgs>::Create(optParamAddr);
bool runList;
+6 -6
View File
@@ -446,9 +446,9 @@ static void __IoAsyncNotify(u64 userdata, int cyclesLate) {
__IoCompleteAsyncIO(f);
} else if (ioTimingMethod == IOTIMING_REALISTIC) {
u64 finishTicks = __IoCompleteAsyncIO(f);
if (finishTicks > CoreTiming::GetTicks()) {
if (finishTicks > CoreTiming::GetTicks(currentMIPS)) {
// Reschedule for later, since we now know how long it ought to take.
CoreTiming::ScheduleEvent(finishTicks - CoreTiming::GetTicks(), asyncNotifyEvent, userdata);
CoreTiming::ScheduleEvent(finishTicks - CoreTiming::GetTicks(currentMIPS), asyncNotifyEvent, userdata);
return;
}
} else {
@@ -502,9 +502,9 @@ static void __IoSyncNotify(u64 userdata, int cyclesLate) {
}
} else if (ioTimingMethod == IOTIMING_REALISTIC) {
u64 finishTicks = ioManager.ResultFinishTicks(f->handle);
if (finishTicks > CoreTiming::GetTicks()) {
if (finishTicks > CoreTiming::GetTicks(currentMIPS)) {
// Reschedule for later when the result should finish.
CoreTiming::ScheduleEvent(finishTicks - CoreTiming::GetTicks(), syncNotifyEvent, userdata);
CoreTiming::ScheduleEvent(finishTicks - CoreTiming::GetTicks(currentMIPS), syncNotifyEvent, userdata);
return;
}
}
@@ -587,7 +587,7 @@ static void __IoManagerThread() {
INFO_LOG(Log::sceIo, "Entering __IoManagerThread");
AndroidJNIThreadContext jniContext;
while (ioManagerThreadEnabled) {
ioManager.RunEventsUntil(CoreTiming::GetTicks() + msToCycles(1000));
ioManager.RunEventsUntil(CoreTiming::GetTicks(currentMIPS) + msToCycles(1000));
}
INFO_LOG(Log::sceIo, "Leaving __IoManagerThread");
}
@@ -887,7 +887,7 @@ u64 __IoCompleteAsyncIO(FileNode *f) {
int ioTimingMethod = GetIOTimingMethod();
if (ioTimingMethod == IOTIMING_REALISTIC) {
u64 finishTicks = ioManager.ResultFinishTicks(f->handle);
if (finishTicks > CoreTiming::GetTicks()) {
if (finishTicks > CoreTiming::GetTicks(currentMIPS)) {
return finishTicks;
}
}
+5 -5
View File
@@ -1781,7 +1781,7 @@ void __KernelLoadReset() {
__KernelInit();
}
bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_string) {
bool __KernelLoadExec(MIPSState *mips, const char *filename, u32 paramPtr, std::string *error_string) {
SceKernelLoadExecParam param{};
auto paramData = PSPPointer<SceKernelLoadExecParam>::Create(paramPtr);
@@ -1836,9 +1836,9 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str
truncate_cpy(moduleName, module->nm.name);
Reporting::NotifyExecModule(moduleName, moduleVersion, module->crc);
mipsr4k.pc = module->nm.entry_addr;
currentMIPS->pc = module->nm.entry_addr;
INFO_LOG(Log::Loader, "Module entry: %08x (%s %04x)", mipsr4k.pc, moduleName, moduleVersion);
INFO_LOG(Log::Loader, "Module entry: %08x (%s %04x)", currentMIPS->pc, moduleName, moduleVersion);
SceKernelSMOption option;
option.size = sizeof(SceKernelSMOption);
@@ -1957,7 +1957,7 @@ int sceKernelLoadExec(const char *filename, u32 paramPtr) {
DEBUG_LOG(Log::sceModule, "sceKernelLoadExec(name=%s,...): loading %s", filename, exec_filename.c_str());
std::string error_string;
if (!__KernelLoadExec(exec_filename.c_str(), paramPtr, &error_string)) {
if (!__KernelLoadExec(currentMIPS, exec_filename.c_str(), paramPtr, &error_string)) {
Core_UpdateState(CORE_RUNTIME_ERROR);
return hleLogError(Log::sceModule, -1, "failed: %s", error_string.c_str());;
}
@@ -2054,7 +2054,7 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) {
if (gpu) {
gpu->Reinitialize();
}
return __KernelLoadExec(safeName.c_str(), 0, &error_string);
return __KernelLoadExec(currentMIPS, safeName.c_str(), 0, &error_string);
} else {
return hleDelayResult(hleLogError(Log::Loader, error, "failed to load"), "module loaded", 500);
}
+3 -1
View File
@@ -231,10 +231,12 @@ KernelObject *__KernelModuleObject();
void __KernelModuleDoState(PointerWrap &p);
void __KernelModuleShutdown();
class MIPSState;
u32 __KernelGetModuleGP(SceUID module);
bool KernelModuleIsKernelMode(SceUID module);
bool __KernelLoadGEDump(std::string_view base_filename, std::string *error_string);
bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_string);
bool __KernelLoadExec(MIPSState *mips, const char *filename, u32 paramPtr, std::string *error_string);
bool KernelFindImportByStubAddr(u32 stubAddr, std::string *importModuleName, u32 *nid, std::string *importingModuleName);
// Describes which loaded module (and section within it) an address falls in, e.g. "EBOOT.BIN.text+1234".
// Returns an empty string if the address isn't inside any currently loaded module.
+4 -4
View File
@@ -664,7 +664,7 @@ static void __KernelDelayEndCallback(SceUID threadID, SceUID prevCallbackId) {
// TODO: Don't wake up if __KernelCurHasReadyCallbacks()?
s64 cyclesLeft = delayDeadline - CoreTiming::GetTicks();
s64 cyclesLeft = delayDeadline - CoreTiming::GetTicks(currentMIPS);
if (cyclesLeft < 0) {
__KernelResumeThreadFromWait(threadID, 0);
} else {
@@ -884,7 +884,7 @@ void __KernelThreadingDoState(PointerWrap &p)
Do(p, pausedDelays);
__SetCurrentThread(kernelObjects.GetFast<PSPThread>(currentThread), currentThread, __KernelGetThreadName(currentThread));
lastSwitchCycles = CoreTiming::GetTicks();
lastSwitchCycles = CoreTiming::GetTicks(currentMIPS);
if (s >= 2)
Do(p, threadEventHandlers);
@@ -1037,7 +1037,7 @@ void __KernelIdle()
// Don't skip 0xDEADBEEF here, this is called directly bypassing CallSyscall().
// That means the hle flag would stick around until the next call.
CoreTiming::Idle();
CoreTiming::Idle(currentMIPS);
// We Advance within __KernelReSchedule(), so anything that has now happened after idle
// will be triggered properly upon reschedule.
__KernelReSchedule("idle");
@@ -2943,7 +2943,7 @@ void __KernelSwitchContext(PSPThread *target, const char *reason) {
#if DEBUG_LEVEL <= MAX_LOGLEVEL || DEBUG_LOG == NOTICE_LOG
if (!(fromIdle && toIdle))
{
u64 nowCycles = CoreTiming::GetTicks();
u64 nowCycles = CoreTiming::GetTicks(currentMIPS);
s64 consumedCycles = nowCycles - lastSwitchCycles;
lastSwitchCycles = nowCycles;
+2 -2
View File
@@ -207,7 +207,7 @@ static void __UmdBeginCallback(SceUID threadID, SceUID prevCallbackId)
_dbg_assert_msg_(umdStatTimeoutEvent != -1, "Must have a umd timer");
s64 cyclesLeft = CoreTiming::UnscheduleEvent(umdStatTimeoutEvent, threadID);
if (cyclesLeft != 0)
umdPausedWaits[pauseKey] = CoreTiming::GetTicks() + cyclesLeft;
umdPausedWaits[pauseKey] = CoreTiming::GetTicks(currentMIPS) + cyclesLeft;
else
umdPausedWaits[pauseKey] = 0;
@@ -244,7 +244,7 @@ static void __UmdEndCallback(SceUID threadID, SceUID prevCallbackId)
return;
}
s64 cyclesLeft = waitDeadline - CoreTiming::GetTicks();
s64 cyclesLeft = waitDeadline - CoreTiming::GetTicks(currentMIPS);
if (cyclesLeft < 0 && waitDeadline != 0)
__KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_TIMEOUT);
else
+3 -3
View File
@@ -55,7 +55,7 @@ struct AsyncIOResult {
explicit AsyncIOResult(s64 r) : result(r), finishTicks(0), invalidateAddr(0) {}
AsyncIOResult(s64 r, int usec, u32 addr = 0) : result(r), invalidateAddr(addr) {
finishTicks = CoreTiming::GetTicks() + usToCycles(usec);
finishTicks = CoreTiming::GetTicks(currentMIPS) + usToCycles(usec);
}
void DoState(PointerWrap &p) {
@@ -156,7 +156,7 @@ public:
for (AsyncIOEvent ev = GetNextEvent(); AsyncIOEventType(ev) != IO_EVENT_INVALID; ev = GetNextEvent()) {
ProcessEventIfApplicable(ev, globalticks);
}
} while (CoreTiming::GetTicks() < globalticks);
} while (CoreTiming::GetTicks(currentMIPS) < globalticks);
return;
}
@@ -177,7 +177,7 @@ public:
ProcessEventIfApplicable(ev, globalticks);
guard.lock();
}
} while (CoreTiming::GetTicks() < globalticks);
} while (CoreTiming::GetTicks(currentMIPS) < globalticks);
// This will force the waiter to check coreState, even if we didn't actually drain.
NotifyDrain();
+3 -2
View File
@@ -26,6 +26,7 @@
#include "Common/Data/Text/StringWriter.h"
#include "Core/Config.h"
#include "Core/System.h"
#include "Core/MIPS/MIPS.h"
#include "Core/CoreTiming.h"
#include "Core/HLE/sceKernel.h"
#include "Core/HLE/sceCtrl.h"
@@ -155,7 +156,7 @@ uint64_t DisplayFrameStartTicks() {
}
uint32_t __DisplayGetCurrentHcount() {
const int ticksIntoFrame = (int)(CoreTiming::GetTicks() - frameStartTicks);
const int ticksIntoFrame = (int)(CoreTiming::GetTicks(currentMIPS) - frameStartTicks);
const int ticksPerVblank = CoreTiming::GetClockFrequencyHz() / 60 / hCountPerVblank;
// Can't seem to produce a 0 on real hardware, offsetting by 1 makes things look right.
return 1 + (ticksIntoFrame / ticksPerVblank);
@@ -227,7 +228,7 @@ bool DisplayIsRunningSlow() {
}
void DisplayFireVblankStart() {
frameStartTicks = CoreTiming::GetTicks();
frameStartTicks = CoreTiming::GetTicks(currentMIPS);
numVBlanks++;
isVblank = 1;
+3 -2
View File
@@ -31,6 +31,7 @@
#include "Core/FileSystems/MetaFileSystem.h"
#include "Core/HW/MemoryStick.h"
#include "Core/System.h"
#include "Core/MIPS/MIPS.h"
#include "Common/CommonTypes.h"
#include "Common/TimeUtil.h"
#include "Common/Thread/Promise.h"
@@ -85,7 +86,7 @@ MemStickState MemoryStick_State() {
}
MemStickFatState MemoryStick_FatState() {
if (memStickNeedsAssign && CoreTiming::GetTicks() > memStickInsertedAt + msToCycles(500)) {
if (memStickNeedsAssign && CoreTiming::GetTicks(currentMIPS) > memStickInsertedAt + msToCycles(500)) {
// It's been long enough for us to be done mounting the memory stick.
memStickFatState = PSP_FAT_MEMORYSTICK_STATE_ASSIGNED;
memStickNeedsAssign = false;
@@ -181,7 +182,7 @@ void MemoryStick_SetState(MemStickState state) {
if (state == PSP_MEMORYSTICK_STATE_NOT_INSERTED) {
MemoryStick_SetFatState(PSP_FAT_MEMORYSTICK_STATE_UNASSIGNED);
} else {
memStickInsertedAt = CoreTiming::GetTicks();
memStickInsertedAt = CoreTiming::GetTicks(currentMIPS);
memStickNeedsAssign = true;
}
}
+7 -7
View File
@@ -1206,7 +1206,7 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst) {
MIPSOpcode op(inst->constant);
CallSyscall(op);
if (coreState != CORE_RUNNING_CPU)
CoreTiming::ForceCheck();
CoreTiming::ForceCheck(mips);
break;
}
@@ -1258,39 +1258,39 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst) {
case IROp::Breakpoint:
if (IRRunBreakpoint(inst->constant)) {
CoreTiming::ForceCheck();
CoreTiming::ForceCheck(mips);
return mips->pc;
}
break;
case IROp::MemoryCheck:
if (IRRunMemCheck(mips->pc + inst->dest, mips->r[inst->src1] + inst->constant)) {
CoreTiming::ForceCheck();
CoreTiming::ForceCheck(mips);
return mips->pc;
}
break;
case IROp::ValidateAddress8:
if (RunValidateAddress<1>(mips->pc, mips->r[inst->src1] + inst->constant, inst->src2)) {
CoreTiming::ForceCheck();
CoreTiming::ForceCheck(mips);
return mips->pc;
}
break;
case IROp::ValidateAddress16:
if (RunValidateAddress<2>(mips->pc, mips->r[inst->src1] + inst->constant, inst->src2)) {
CoreTiming::ForceCheck();
CoreTiming::ForceCheck(mips);
return mips->pc;
}
break;
case IROp::ValidateAddress32:
if (RunValidateAddress<4>(mips->pc, mips->r[inst->src1] + inst->constant, inst->src2)) {
CoreTiming::ForceCheck();
CoreTiming::ForceCheck(mips);
return mips->pc;
}
break;
case IROp::ValidateAddress128:
if (RunValidateAddress<16>(mips->pc, mips->r[inst->src1] + inst->constant, inst->src2)) {
CoreTiming::ForceCheck();
CoreTiming::ForceCheck(mips);
return mips->pc;
}
break;
+1 -1
View File
@@ -172,6 +172,7 @@ void IRJit::RunLoopUntil(u64 globalticks) {
// ApplyRoundingMode(true);
// IR Dispatcher
MIPSState *mips = mips_;
while (true) {
// RestoreRoundingMode(true);
CoreTiming::Advance();
@@ -180,7 +181,6 @@ void IRJit::RunLoopUntil(u64 globalticks) {
break;
}
MIPSState *mips = mips_;
#ifdef _DEBUG
compilerEnabled_ = false;
#endif
+1 -1
View File
@@ -382,7 +382,7 @@ void MIPSState::ClearJitCache() {
if (coreState == CORE_RUNNING_CPU || insideJit) {
pendingClears.emplace_back(0, 0);
hasPendingClears = true;
CoreTiming::ForceCheck();
CoreTiming::ForceCheck(this);
} else {
MIPSComp::jit->ClearCache();
}
+2 -1
View File
@@ -273,7 +273,8 @@ public:
class MIPSDebugInterface;
//The one we are compiling or running currently
// The one we are compiling or running currently
// TODO: These globals should be refactored away.
extern MIPSState *currentMIPS;
extern MIPSDebugInterface *currentDebugMIPS;
extern MIPSState mipsr4k;
+1 -1
View File
@@ -159,7 +159,7 @@ public:
if (referenceIndex == REF_INDEX_USEC)
return (uint32_t)CoreTiming::GetGlobalTimeUs(); // Loses information
if (referenceIndex == REF_INDEX_TICKS)
return (uint32_t)CoreTiming::GetTicks();
return (uint32_t)CoreTiming::GetTicks(currentMIPS);
if ((referenceIndex & ~(REF_INDEX_FPU | REF_INDEX_FPU_INT)) < 32)
return cpu->GetRegValue(1, referenceIndex & ~(REF_INDEX_FPU | REF_INDEX_FPU_INT));
if ((referenceIndex & ~(REF_INDEX_VFPU | REF_INDEX_VFPU_INT)) < 128)
+1
View File
@@ -25,6 +25,7 @@
class MIPSDebugInterface : public DebugInterface {
private:
MIPSState *cpu;
public:
MIPSDebugInterface(MIPSState *_cpu) { cpu = _cpu; }
+8 -8
View File
@@ -1187,25 +1187,25 @@ static void RunUntilWithChecks(MIPSState *mips, u64 globalTicks) {
}
} while (mips->inDelaySlot);
if (CoreTiming::GetTicks() > globalTicks)
if (CoreTiming::GetTicks(currentMIPS) > globalTicks)
return;
}
}
#undef _RS
int MIPSInterpret_RunUntil(MIPSState *curMips, u64 globalTicks) {
int MIPSInterpret_RunUntil(MIPSState *mips, u64 globalTicks) {
while (coreState == CORE_RUNNING_CPU) {
CoreTiming::Advance();
uint64_t ticksLeft = globalTicks - CoreTiming::GetTicks();
if (g_breakpoints.HasBreakPoints() || g_breakpoints.HasMemChecks() || ticksLeft <= curMips->downcount) {
RunUntilWithChecks(curMips, globalTicks);
uint64_t ticksLeft = globalTicks - CoreTiming::GetTicks(currentMIPS);
if (g_breakpoints.HasBreakPoints() || g_breakpoints.HasMemChecks() || ticksLeft <= mips->downcount) {
RunUntilWithChecks(mips, globalTicks);
} else {
RunUntilFast(curMips);
RunUntilFast(mips);
}
if (CoreTiming::GetTicks() > globalTicks) {
// DEBUG_LOG(Log::CPU, "Hit the max ticks, bailing 1 : %llu, %llu", globalTicks, CoreTiming::GetTicks());
if (CoreTiming::GetTicks(mips) > globalTicks) {
// DEBUG_LOG(Log::CPU, "Hit the max ticks, bailing 1 : %llu, %llu", globalTicks, CoreTiming::GetTicks(mips));
return 1;
}
}
+3 -2
View File
@@ -42,6 +42,7 @@
#include "Core/MemMap.h"
#include "Core/HDRemaster.h"
#include "Core/Util/PathUtil.h"
#include "Core/MIPS/MIPS.h"
#include "Core/Config.h"
#include "Core/ConfigValues.h"
@@ -307,7 +308,7 @@ bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string) {
System_PostUIMessage(UIMessage::CONFIG_LOADED);
INFO_LOG(Log::Loader, "Loading %s...", bootpath.c_str());
// TODO: We can't use the initial error_string pointer.
return __KernelLoadExec(bootpath.c_str(), 0, &PSP_CoreParameter().errorString);
return __KernelLoadExec(currentMIPS, bootpath.c_str(), 0, &PSP_CoreParameter().errorString);
}
// TODO: Move this to common. Merge with ResolvePath?
@@ -451,7 +452,7 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string_view discId, bool load
g_Config.LoadGameConfig(discID);
}
return __KernelLoadExec(finalName.c_str(), 0, error_string);
return __KernelLoadExec(currentMIPS, finalName.c_str(), 0, error_string);
}
bool Load_PSP_GE_Dump(FileLoader *fileLoader, std::string *error_string) {
+2 -1
View File
@@ -50,6 +50,7 @@ extern "C" {
#include "Core/Loaders.h"
#include "Core/SaveState.h"
#include "Core/System.h"
#include "Core/MIPS/MIPS.h"
#include "Core/ELF/ParamSFO.h"
#include "Core/FileSystems/BlockDevices.h"
#include "Core/FileSystems/MetaFileSystem.h"
@@ -457,7 +458,7 @@ namespace Reporting
{
// Just to get an idea of how long they played.
if (PSP_GetBootState() == BootState::Complete)
postdata.Add("ticks", (const uint64_t)CoreTiming::GetTicks());
postdata.Add("ticks", (const uint64_t)CoreTiming::GetTicks(currentMIPS));
float vps, fps;
__DisplayGetAveragedFPS(&vps, &fps);
+2 -2
View File
@@ -437,7 +437,7 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin
mipsr4k.Reset();
CoreTiming::Init();
CoreTiming::Init(&mipsr4k);
DisplayHWInit();
@@ -798,7 +798,7 @@ void PSP_RunLoopWhileState() {
}
void PSP_RunLoopFor(int cycles) {
Core_RunLoopUntil(CoreTiming::GetTicks() + cycles);
Core_RunLoopUntil(CoreTiming::GetTicks(currentMIPS) + cycles);
}
const char *DumpFileTypeToString(DumpFileType type) {
+1 -1
View File
@@ -409,7 +409,7 @@ void DumpExecute::SyncStall() {
s64 listTicks = gpu->GetListTicks(execListID);
if (listTicks != -1) {
s64 nowTicks = CoreTiming::GetTicks();
s64 nowTicks = CoreTiming::GetTicks(currentMIPS);
if (listTicks > nowTicks) {
currentMIPS->downcount -= listTicks - nowTicks;
}
+4 -4
View File
@@ -186,7 +186,7 @@ u32 GPUCommon::DrawSync(int mode) {
return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT;
}
if (drawCompleteTicks > CoreTiming::GetTicks()) {
if (drawCompleteTicks > CoreTiming::GetTicks(currentMIPS)) {
__GeWaitCurrentThread(GPU_SYNC_DRAW, 1, "GeDrawSync");
} else {
for (int i = 0; i < DisplayListMaxCount; ++i) {
@@ -262,7 +262,7 @@ int GPUCommon::ListSync(int listid, int mode) {
return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT;
}
if (dl.waitUntilTicks > CoreTiming::GetTicks()) {
if (dl.waitUntilTicks > CoreTiming::GetTicks(currentMIPS)) {
__GeWaitCurrentThread(GPU_SYNC_LIST, listid, "GeListSync");
}
@@ -367,7 +367,7 @@ u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<Ps
}
int id = -1;
u64 currentTicks = CoreTiming::GetTicks();
u64 currentTicks = CoreTiming::GetTicks(currentMIPS);
u32 stackAddr = args.IsValid() && args->size >= 16 ? (u32)args->stackAddr : 0;
// Check compatibility
// TODO: Figure out what games are affected by this...
@@ -735,7 +735,7 @@ inline void GPUCommon::UpdateState(GPURunState state) {
// This is now called when coreState == CORE_RUNNING_GE, in addition to from the various sceGe commands.
DLResult GPUCommon::ProcessDLQueue() {
if (!resumingFromDebugBreak_) {
startingTicks = CoreTiming::GetTicks();
startingTicks = CoreTiming::GetTicks(currentMIPS);
cyclesExecuted = 0;
// ?? Seems to be correct behaviour to process the list anyway?
+1 -1
View File
@@ -195,7 +195,7 @@ void DrawSchedulerView(ImConfig &cfg) {
ImGui::End();
return;
}
s64 ticks = CoreTiming::GetTicks();
s64 ticks = CoreTiming::GetTicks(currentMIPS);
if (ImGui::BeginChild("event_list", ImVec2(300.0f, 0.0))) {
const CoreTiming::Event *event = CoreTiming::GetFirstEvent();
while (event) {
+6 -6
View File
@@ -93,7 +93,7 @@ static constexpr UINT UPDATE_DELAY = 1000 / 60;
CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, MIPSDebugInterface *_cpu) : Dialog((LPCSTR)IDD_DISASM, _hInstance, _hParent) {
cpu = _cpu;
lastTicks_ = PSP_IsInited() ? CoreTiming::GetTicks() : 0;
lastTicks_ = PSP_IsInited() ? CoreTiming::GetTicks(currentMIPS) : 0;
breakpoints_ = &g_breakpoints;
SetWindowText(m_hDlg, L"R4");
@@ -204,7 +204,7 @@ void CDisasm::step(CPUStepType stepType) {
CtrlDisAsmView *ptr = DisAsmView();
ptr->setDontRedraw(true);
lastTicks_ = CoreTiming::GetTicks();
lastTicks_ = CoreTiming::GetTicks(currentMIPS);
// Route the actual step request to the CPU thread instead of poking at it directly from this
// GUI thread - see Core_RunOnCPUThread() in Core.h.
@@ -219,7 +219,7 @@ void CDisasm::runToLine() {
CtrlDisAsmView *ptr = DisAsmView();
u32 pos = ptr->getSelection();
lastTicks_ = CoreTiming::GetTicks();
lastTicks_ = CoreTiming::GetTicks(currentMIPS);
ptr->setDontRedraw(true);
// Route the breakpoint mutation to the CPU thread instead of poking at it directly from this
// GUI thread - see Core_RunOnCPUThread() in Core.h. Core_Resume() itself is free-threaded.
@@ -401,7 +401,7 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
ptr->setDontRedraw(false);
Core_Break(BreakReason::DebugBreak, 0);
} else { // go
lastTicks_ = CoreTiming::GetTicks();
lastTicks_ = CoreTiming::GetTicks(currentMIPS);
Core_Resume();
}
}
@@ -423,7 +423,7 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
{
if (Core_IsActive())
break;
lastTicks_ = CoreTiming::GetTicks();
lastTicks_ = CoreTiming::GetTicks(currentMIPS);
// Route the actual HLE-break mutation to the CPU thread instead of poking at
// it directly from this GUI thread - see Core_RunOnCPUThread() in Core.h.
@@ -799,7 +799,7 @@ void CDisasm::ProcessUpdateDialog() {
// Update Debug Counter
if (PSP_IsInited()) {
wchar_t tempTicks[24]{};
_snwprintf(tempTicks, 23, L"%lld", CoreTiming::GetTicks() - lastTicks_);
_snwprintf(tempTicks, 23, L"%lld", CoreTiming::GetTicks(currentMIPS) - lastTicks_);
SetDlgItemText(m_hDlg, IDC_DEBUG_COUNT, tempTicks);
}
+2 -2
View File
@@ -164,8 +164,8 @@ BOOL CVFPUDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
for (int row = 0; row<4; row++)
{
float val = mipsr4k.v[voffset[column*32+row+matrix*4]];
u32 hex = mipsr4k.vi[voffset[column*32+row+matrix*4]];
float val = currentMIPS->v[voffset[column*32+row+matrix*4]];
u32 hex = currentMIPS->vi[voffset[column*32+row+matrix*4]];
switch (mode)
{
case 0: temp_len = sprintf_s(temp,"%f",val); break;
+1 -1
View File
@@ -247,7 +247,7 @@ namespace Libretro
}
// Get elapsed time (us) for this run
s64 runTicks = CoreTiming::GetTicks();
s64 runTicks = CoreTiming::GetTicks(currentMIPS);
s64 runTimeUs = cyclesToUs(runTicks - runTicksLast);
// Check if current internal frame rate is a
+1 -1
View File
@@ -100,7 +100,7 @@ static void SetupJitHarness() {
Memory::Init(Memory::MemMapSetupFlags::Default);
mipsr4k.Reset();
CoreTiming::Init();
CoreTiming::Init(currentMIPS);
InitVFPU();
}