Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions pcsx2-qt/Debugger/DebuggerWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,7 @@ void DebuggerWindow::onStepOut()
cpu->getPC(),
cpu->getRegister(0, 31),
cpu->getRegister(0, 29),
thread->EntryPoint(),
thread->StackTop());
thread->EntryPoint());
break;
}
}
Expand Down
3 changes: 1 addition & 2 deletions pcsx2-qt/Debugger/StackModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,7 @@ void StackModel::refreshData()
{
if (thread->Status() == ThreadStatus::THS_RUN)
{
m_stackFrames = MipsStackWalk::Walk(&m_cpu, m_cpu.getPC(), m_cpu.getRegister(0, 31), m_cpu.getRegister(0, 29),
thread->EntryPoint(), thread->StackTop());
m_stackFrames = m_cpu.StackTrace(*thread);
break;
}
}
Expand Down
2 changes: 0 additions & 2 deletions pcsx2-qt/Debugger/ThreadModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ class ThreadModel : public QAbstractTableModel
//: Refers to a Thread Wait State in the Debugger.
{WaitState::NONE, tr("NONE")},
//: Refers to a Thread Wait State in the Debugger.
{WaitState::WAKEUP_REQ, tr("WAKEUP REQUEST")},
//: Refers to a Thread Wait State in the Debugger.
{WaitState::SEMA, tr("SEMAPHORE")},
//: Refers to a Thread Wait State in the Debugger.
{WaitState::SLEEP, tr("SLEEP")},
Expand Down
7 changes: 4 additions & 3 deletions pcsx2/DebugTools/BiosDebugData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,18 @@ std::vector<std::unique_ptr<BiosThread>> getIOPThreads()
return {};
}

data.stackTop = iopMemRead32(item + 0x3c);
data.stacMem = iopMemRead32(item + 0x3c);
data.stackSize = iopMemRead32(item + 0x40);
data.status = iopMemRead8(item + 0xc);
data.tid = iopMemRead16(item + 0xa);
data.entrypoint = iopMemRead32(item + 0x38);
data.waitstate = iopMemRead16(item + 0x1c);
data.waitId = iopMemRead32(item + 0x20);
data.initPriority = iopMemRead16(item + 0xe);

data.SavedSP = iopMemRead32(item + 0x10);
data.regCtx = iopMemRead32(item + 0x10);

data.PC = iopMemRead32(data.SavedSP + 0x8c);
data.PC = iopMemRead32(data.regCtx + 0x8c);

threads.emplace_back(std::make_unique<IOPThread>(data));

Expand Down
45 changes: 29 additions & 16 deletions pcsx2/DebugTools/BiosDebugData.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,37 @@ enum class ThreadStatus
THS_DORMANT = 0x10,
};

struct EEInternalCtx
{
u32 sa;
u32 fcsr;
u32 float_thing;
u32 unk;
// gpr excluding $zero
// k0/k1 contains hi, hi1, lo, lo1
u128 gpr[31];
float fpr[32];
};

struct EEInternalThread
{ // internal struct
u32 prev;
u32 next;
int status;
u32 entry;
u32 stack;
u32 resumeAddr; // address to return to when switching
u32 regCtx; // points to the saved regs on stack
u32 gpReg;
short currentPriority;
short initPriority;
short currentPriority;
int waitType;
int semaId;
int wakeupCount;
int attr;
int option;
u32 entry_init;
u32 entry;
int argc;
u32 argstring;
u32 stack_bottom; //FIXME
u32 stackMem;
int stackSize;
u32 root;
u32 heap_base;
Expand All @@ -48,8 +59,9 @@ struct IOPInternalThread
{
u32 tid;
u32 PC;
u32 stackTop;
u32 SavedSP;
u32 stacMem;
u32 stackSize;
u32 regCtx;
u32 status;
u32 entrypoint;
u32 waitstate;
Expand All @@ -71,14 +83,13 @@ enum class IOPWaitStatus
enum class EEWaitStatus
{
WAIT_NONE = 0,
WAIT_WAKEUP_REQ = 1,
WAIT_SLEEP = 1,
WAIT_SEMA = 2,
};

enum class WaitState
{
NONE,
WAKEUP_REQ,
SEMA,
SLEEP,
DELAY,
Expand All @@ -98,8 +109,10 @@ class BiosThread
[[nodiscard]] virtual WaitState Wait() const = 0;
[[nodiscard]] virtual u32 WaitId() const = 0;
[[nodiscard]] virtual u32 EntryPoint() const = 0;
[[nodiscard]] virtual u32 StackTop() const = 0;
[[nodiscard]] virtual u32 Priority() const = 0;

// Only call RegCtx on threads that aren't running
[[nodiscard]] virtual u32 RegCtx() const = 0;
};

class EEThread : public BiosThread
Expand All @@ -113,7 +126,7 @@ class EEThread : public BiosThread
~EEThread() override = default;

[[nodiscard]] u32 TID() const override { return tid; };
[[nodiscard]] u32 PC() const override { return data.entry; };
[[nodiscard]] u32 PC() const override { return data.resumeAddr; };
[[nodiscard]] ThreadStatus Status() const override { return static_cast<ThreadStatus>(data.status); };
[[nodiscard]] WaitState Wait() const override
{
Expand All @@ -122,17 +135,17 @@ class EEThread : public BiosThread
{
case EEWaitStatus::WAIT_NONE:
return WaitState::NONE;
case EEWaitStatus::WAIT_WAKEUP_REQ:
return WaitState::WAKEUP_REQ;
case EEWaitStatus::WAIT_SLEEP:
return WaitState::SLEEP;
case EEWaitStatus::WAIT_SEMA:
return WaitState::SEMA;
}
return WaitState::NONE;
};
[[nodiscard]] u32 WaitId() const override { return data.semaId; };
[[nodiscard]] u32 EntryPoint() const override { return data.entry_init; };
[[nodiscard]] u32 StackTop() const override { return data.stack; };
[[nodiscard]] u32 EntryPoint() const override { return data.entry; };
[[nodiscard]] u32 Priority() const override { return data.currentPriority; };
[[nodiscard]] u32 RegCtx() const override { return data.regCtx; };

private:
u32 tid;
Expand Down Expand Up @@ -175,8 +188,8 @@ class IOPThread : public BiosThread
};
[[nodiscard]] u32 WaitId() const override { return data.waitId; };
[[nodiscard]] u32 EntryPoint() const override { return data.entrypoint; };
[[nodiscard]] u32 StackTop() const override { return data.stackTop; };
[[nodiscard]] u32 Priority() const override { return data.initPriority; };
[[nodiscard]] u32 RegCtx() const override { return data.regCtx; };

private:
IOPInternalThread data;
Expand Down
33 changes: 33 additions & 0 deletions pcsx2/DebugTools/DebugInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,23 @@ std::vector<std::unique_ptr<BiosThread>> R5900DebugInterface::GetThreadList() co
return getEEThreads();
}

std::vector<MipsStackWalk::StackFrame> R5900DebugInterface::StackTrace(const BiosThread& thread)
{
if (thread.Status() == ThreadStatus::THS_RUN)
{
return MipsStackWalk::Walk(this, getPC(), getRegister(0, 31), getRegister(0, 29),
thread.EntryPoint());
}

EEInternalCtx* ctx = static_cast<EEInternalCtx*>(PSM(thread.RegCtx()));
u32 pc = thread.PC();
// $zero is not in the array so subtract 1
u32 ra = ctx->gpr[31 - 1]._u32[0];
u32 sp = ctx->gpr[29 - 1]._u32[0];

return MipsStackWalk::Walk(this, pc, ra, sp, thread.EntryPoint());
}

std::vector<IopMod> R5900DebugInterface::GetModuleList() const
{
return {};
Expand Down Expand Up @@ -1049,6 +1066,22 @@ std::vector<std::unique_ptr<BiosThread>> R3000DebugInterface::GetThreadList() co
return getIOPThreads();
}

std::vector<MipsStackWalk::StackFrame> R3000DebugInterface::StackTrace(const BiosThread& thread)
{
if (thread.Status() == ThreadStatus::THS_RUN)
{
return MipsStackWalk::Walk(this, getPC(), getRegister(0, 31), getRegister(0, 29),
thread.EntryPoint());
}

u32 p = thread.RegCtx();
u32 pc = Read32(p + 0x8c);
u32 ra = Read32(p + 0x7c);
u32 sp = Read32(p + 0x74);

return MipsStackWalk::Walk(this, pc, ra, sp, thread.EntryPoint());
}

std::vector<IopMod> R3000DebugInterface::GetModuleList() const
{
return getIOPModules();
Expand Down
4 changes: 4 additions & 0 deletions pcsx2/DebugTools/DebugInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "ExpressionParser.h"
#include "SymbolGuardian.h"
#include "SymbolImporter.h"
#include "MipsStackWalk.h"

#include "common/MemoryInterface.h"

Expand Down Expand Up @@ -72,6 +73,7 @@ class DebugInterface : public MemoryInterface
virtual SymbolGuardian& GetSymbolGuardian() const = 0;
virtual SymbolImporter* GetSymbolImporter() const = 0;
virtual std::vector<std::unique_ptr<BiosThread>> GetThreadList() const = 0;
virtual std::vector<MipsStackWalk::StackFrame> StackTrace(const BiosThread& thread) = 0;
virtual std::vector<IopMod> GetModuleList() const = 0;

bool isAlive();
Expand Down Expand Up @@ -135,6 +137,7 @@ class R5900DebugInterface : public DebugInterface
SymbolGuardian& GetSymbolGuardian() const override;
SymbolImporter* GetSymbolImporter() const override;
std::vector<std::unique_ptr<BiosThread>> GetThreadList() const override;
std::vector<MipsStackWalk::StackFrame> StackTrace(const BiosThread& thread) override;
std::vector<IopMod> GetModuleList() const override;

std::string disasm(u32 address, bool simplify) override;
Expand Down Expand Up @@ -180,6 +183,7 @@ class R3000DebugInterface : public DebugInterface
SymbolGuardian& GetSymbolGuardian() const override;
SymbolImporter* GetSymbolImporter() const override;
std::vector<std::unique_ptr<BiosThread>> GetThreadList() const override;
std::vector<MipsStackWalk::StackFrame> StackTrace(const BiosThread& thread) override;
std::vector<IopMod> GetModuleList() const override;

std::string disasm(u32 address, bool simplify) override;
Expand Down
2 changes: 1 addition & 1 deletion pcsx2/DebugTools/MipsStackWalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ namespace MipsStackWalk
return ScanForEntry(cpu, frame, newPossibleEntry, ra);
}

std::vector<StackFrame> Walk(DebugInterface* cpu, u32 pc, u32 ra, u32 sp, u32 threadEntry, u32 threadStackTop)
std::vector<StackFrame> Walk(DebugInterface* cpu, u32 pc, u32 ra, u32 sp, u32 threadEntry)
{
std::vector<StackFrame> frames;
StackFrame current;
Expand Down
2 changes: 1 addition & 1 deletion pcsx2/DebugTools/MipsStackWalk.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ namespace MipsStackWalk {
int stackSize;
};

std::vector<StackFrame> Walk(DebugInterface* cpu, u32 pc, u32 ra, u32 sp, u32 threadEntry, u32 threadStackTop);
std::vector<StackFrame> Walk(DebugInterface* cpu, u32 pc, u32 ra, u32 sp, u32 threadEntry);
};
Loading