diff options
| author | lameguy64 <lameguy64@github.com> | 2024-05-04 18:55:05 +0800 |
|---|---|---|
| committer | lameguy64 <lameguy64@github.com> | 2024-05-04 18:55:05 +0800 |
| commit | 702bb601fb5712e2ae962a34b89204c646fe98f5 (patch) | |
| tree | 765f400d1535d37c5ff4df61d01229a7dc7d8207 /indev/psn00bdbg-mk2/doc | |
| parent | 00abe5963fbead092f91935b90390aa5a9111c43 (diff) | |
| download | psn00bsdk-702bb601fb5712e2ae962a34b89204c646fe98f5.tar.gz | |
Included PSn00bDBG-mk2 monitor and test utility
Diffstat (limited to 'indev/psn00bdbg-mk2/doc')
| -rw-r--r-- | indev/psn00bdbg-mk2/doc/commands.txt | 321 | ||||
| -rw-r--r-- | indev/psn00bdbg-mk2/doc/overview.txt | 140 |
2 files changed, 461 insertions, 0 deletions
diff --git a/indev/psn00bdbg-mk2/doc/commands.txt b/indev/psn00bdbg-mk2/doc/commands.txt new file mode 100644 index 0000000..8169007 --- /dev/null +++ b/indev/psn00bdbg-mk2/doc/commands.txt @@ -0,0 +1,321 @@ +== Debugger commands ==
+
+ CMD_DB_GETSTAT (D0h) - Get target status
+
+ Get current status of the target. Issue this command at regular
+ intervals to monitor for breakpoints or exceptions during program
+ execution.
+
+ Arguments:
+
+ None.
+
+ Response:
+
+ [u8] Status byte.
+ 0 - Program stopped
+ 1 - Breakpoint hit/trace complete
+ 2 - Unhandled exception (see CMD_DB_GETREGS to
+ determine cause of exception via CAUSE)
+ 3 - Running
+
+
+ CMD_DB_GETINFO (D1h) - Get debug monitor info string
+
+ Obtain information string of the debug monitor. Normally the
+ response would be 'PSnDBmk2'.
+
+ Arguments:
+
+ None.
+
+ Response:
+
+ [...] Zero terminated string. Transmission ends when a zero
+ character has been received.
+
+
+ CMD_DB_SETEXEC (D2h) - Execution control
+
+ Control program execution on the target.
+
+ Arguments:
+
+ [u8] Set execution.
+ 0 - stop target
+ 1 - step single instruction
+ 2 - resume execution
+
+ Response:
+
+ [u8] New target status (see CMD_DB_GETSTAT).
+
+
+ CMD_DB_RUNTO (D3h) - Run to address
+
+ Resume execution up to the specified program counter address. If the
+ trace bit is set, and a non-sequential instruction was encountered
+ (ie. jump or branch instruction) before the target address is reached,
+ the monitor will break on the destination address of the non-sequential
+ instruction instead. Intended for run-to cursor and source level trace
+ operations- so the destination of a function call, conditional line or
+ a loop while tracing can be determined.
+
+ If a previously defined breakpoint or hard breakpoint (hard-coded break
+ instruction) was encountered before the target address is reached, the
+ monitor will break on the breakpoints instead.
+
+ This command automatically resumes execution if the target was in a
+ stopped state.
+
+ Arguments:
+
+ [u8] Flags.
+ bit 0 : Trace enable
+ bit 1-7 : Reserved
+
+ [u32] Target program counter address.
+
+ Response:
+
+ [u8] New execution status (see D0).
+
+
+ CMD_DB_SETBRK (D4h) - Set program breakpoint
+
+ Defines a program breakpoint on the specified address. Up to 32 program
+ breakpoints can be set at a time.
+
+ Breakpoints can only be set to writable memory regions as the
+ breakpoint mechanism works by patching break instructions into the
+ program text- a modification that is automatically undone and redone
+ between monitor interactions to appear invisible to the debugging host.
+ The patched instruction is also undone and immediately redone when
+ resuming from a breakpoint so program execution continues normally
+ between each break iteration.
+
+ FlushCache() is called to clear the instruction cache whenever
+ breakpoints get patched and unpatched.
+
+ Avoid placing a program breakpoint inside the delay slot of a
+ non-sequential instruction such as a jump or branch instruction,
+ otherwise the monitor will not be able to trace or resume execution
+ from the branch instruction.
+
+ Setting a breakpoint to an already existing breakpoint will update
+ the existing breakpoint with the specified flags and target count,
+ as well as clearing the breakpoint counter.
+
+ Arguments:
+
+ [u32] Breakpoint address.
+ [u16] Flags
+ Bits 0-1 : Breakpoint mode
+ 0 - No break, but increment counter.
+ 1 - Stop execution when encountered.
+ 2 - Break when counter reaches target value.
+ 3 - Reserved.
+ Bits 2-15 : Reserved
+ [u16] Target Count
+
+ Response:
+
+ [u8] Result byte
+ 0 - Invalid address
+ 1 - Breakpoint set
+ 2 - Breakpoint updated
+
+
+
+ CMD_DB_CLRBRK (D5h) - Clear program breakpoints
+
+ Clears all previously defined program breakpoints.
+
+ Arguments:
+
+ none
+
+ Response:
+
+ [u8] Status byte (acknowledge)
+
+
+ CMD_DB_GETREGS (D6h) - Get registers
+
+ Obtain all 32 general purpose register values and some special
+ registers- such as the hi/lo registers, EPC (program counter), CAUSE,
+ BADVADDR, JUMPDEST and DCIC. Two op-codes from EPC are also retrieved
+ totalling about 42 32-bit register words.
+
+ The value of register k0 is superfluous for it is used immediately by
+ the jump routines of the exception vectors. Software is not meant to
+ use the k0/k1 registers as it is used by the kernel's jump vector.
+
+ Refer to the LSI L64360 datasheet for details on cop0 registers SR,
+ CAUSE, BADVADDR, JUMPDEST, and DCIC.
+
+ Arguments:
+
+ None.
+
+ Response:
+
+ [u32] 42 Processor register values in the following order:
+
+ r0,at,v0,v1,a0,a1,a2,a3,
+ t0,t1,t2,t3,t4,t5,t6,t7,
+ s0,s1,s2,s3,s4,s5,s6,s7,
+ t8,t9,k0,k1,gp,sp,fp,ra,
+ EPC,hi,lo,
+ SR,CAUSE,BADVADDR,JUMPDEST,DCIC
+ opcode(EPC+0),opcode(EPC+4)
+
+
+ CMD_DB_MEM (D7h) - Read/write n bytes from address
+
+ Reads or writes n bytes of memory to or from the specified address.
+
+ Arguments:
+
+ [u8] Operation
+ 0 - read
+ 1 - write
+ [u32] Read source address/write destination address
+ [u32] Number of bytes
+
+ [u8] Write data of n bytes (only when writing to memory)
+
+ Response (only when reading from memory):
+
+ [...] Bytes read of specified length.
+
+
+ CMD_DB_WORD (D8h) - Read/write word
+
+ Reads or writes a word from memory.
+
+ The specified memory address must be aligned to two or four bytes
+ when performing a 16-bit word or 32-bit memory operation respectively.
+ Failing to do so will cause an in-monitor exception and crash the
+ target.
+
+ Arguments:
+
+ [u8] Operation
+ 0 - read
+ 1 - write
+ [u8] Word size (0 - [u8], 1 - [u16], 2 - [u32]).
+ [u32] Memory address.
+
+ [u8/u16/u32] Word value to write (only when writing to memory)
+
+ Response (only when reading from memory):
+
+ [u32] Word value read (always 32-bit regardless of word size).
+
+
+ CMD_DB_GETBRK (D9h) - Get all breakpoints
+
+ Returns an array of currently set breakpoints with their flag settings
+ and counter values.
+
+ Arguments:
+
+ None.
+
+ Response:
+
+ [u32] Breakpoint address.
+ [u16] Breakpoint flag
+ [u16] Breakpoint counter target value.
+ [u16] Breakpoint counter.
+ ...
+
+ The list is terminated with a breakpoint of address FFFFFFFFh.
+
+
+ CMD_DB_SETREG (DAh) - Set register
+
+ Sets any of the register values of the running target.
+
+ This command, coupled with CMD_DB_MEM, can be used to upload and
+ execute a PS-EXE without a loader as long as the monitor program
+ is installed and responsive. To do this, stop the target with
+ CMD_DB_SETEXEC, upload the program text to its target address
+ using CMD_DB_MEM, then use CMD_DB_SETREG to reset the stack pointer
+ (sp) to the initial stacktop (801FFFF0h) and PC to the program text's
+ entrypoint (pc0), clear bits 0-5 of the SR register then execute the
+ program by resuming with CMD_DB_SETEXEC.
+
+ Arguments:
+
+ [u8] Register number
+ 0 - r0* 1 - at 2 - v0 3 - v1
+ 4 - a0 5 - a1 6 - a2 7 - a3
+ 8 - t0 9 - t1 10 - t2 11 - t3
+ 12 - t4 13 - t5 14 - t6 15 - t7
+ 16 - s0 17 - s1 18 - s2 19 - s3
+ 20 - s4 21 - s5 22 - s6 23 - s7
+ 24 - t8 25 - t9 26 - k0 27 - k1
+ 28 - gp 29 - sp 30 - fp 31 - ra
+ 32 - EPC 33 - hi 34 - lo 35 - SR
+
+ * Ignored
+
+ [u32] Register value
+
+ Response:
+
+ [u8] 0 - Response byte
+
+
+ CMD_DB_MEMBRK (DBh) - Set data access breakpoint registers
+
+ Set breakpoint registers for memory access operations. Only a single
+ breakpoint address or a range of addresses with the compare mask can
+ be set with this command.
+
+ The mask register is used to mask which bits between the address of
+ a memory access operation and the memory breakpoint address are
+ compared. For example, a mask value of FF000000h compares bits
+ 31-24 of the addresses- the remaining bits are ignored.
+
+ To deactivate data access breakpoint, simply set the address, mask
+ and flags to zero.
+
+ Arguments:
+
+ [u32] Memory breakpoint address
+ [u32] Memory breakpoint compare mask
+ [u8] Breakpoint flags
+ Bit 0: Break on memory read
+ Bit 1: Break on memory write
+ Bit 2-7: Reserved
+
+ Response:
+ [u8] 0 - Response byte
+
+
+ CMD_REBOOT (A0h) - Reboot console
+
+ While not necessarily a debug command, it is a convenience command
+ that allows remote reboot of the target. Soft reboot is performed by
+ simply jumping to the base address of the BIOS ROM segment, which is
+ equivalent to pressing the reset button on the console.
+
+
+ Command numbers DC-DFh are not yet defined and are reserved.
+
+
+== Multiple Program Breakpoints Implementation ==
+
+ Because the hardware only supports one software breakpoint at a time,
+ performing rapid breakpoint cycles on every non-sequential instruction
+ via the trace bit in DCIC would incur a massive performance penalty and
+ potentially introduce system instability. Multiple software breakpoints
+ are instead implemented by patching break instructions to specified
+ breakpoint locations and the patched instructions are undone when the
+ original instruction needs to be executed (ie. resume program from break
+ address). This limits breakpoints to code residing in RAM, but this
+ method does not incur a performance penalty that can break speed
+ sensitive code.
diff --git a/indev/psn00bdbg-mk2/doc/overview.txt b/indev/psn00bdbg-mk2/doc/overview.txt new file mode 100644 index 0000000..867b610 --- /dev/null +++ b/indev/psn00bdbg-mk2/doc/overview.txt @@ -0,0 +1,140 @@ +== Summary == + + The new PSn00bDBG-Mk2 monitor is a significant revision of the + original, mostly proof-of-concept version from 2018. Written from the + groud-up, such improvements include: + + * Abandoned event-based messages system in favor of a much simpler + command-acknowledge protocol and polling-based status monitoring. + + * Communication functions are consolidated to a single include file, + giving provision to replace communication routines by swapping out + this include file. + + * Improved instruction step operation, with correct following of + branching and non-sequential instructions. + + * Enhanced run-to-address with optional break on branching or non- + sequential instructions- ideal for source-level trace operations. + + * Support for up to 32 program breakpoints with counters. + + * Block memory read and write- can be used to upload program text + directly through the debug monitor (similar to that of official + development systems). + + * Utilizes kernel stack instead of user stack- preserving the latter + during debugging operations. + + The new monitor is also better integrated into the kernel space- + taking advantage of TCB structures and hooking to more appropriate vectors + of both BIOS and kernel, reducing code size and improving system stability + when compared to the old debugger. The pollhost() macro (break 1024) is + also supported, and can be used to keep the debug monitor serviced for + instances where interrupts are disabled. + + Unlike the old proof-of-concept debugger, a specifically written debugger + is not provided. Instead this debug monitor is to be used with GNU GDB as + the debugger, with a simple protocol middle-man that serves to translate + between the GDB remote debugging protocol and PSn00bDBG-Mk2 command set. + + +== Installation and Operation == + + Three files are provided after assembling the debug monitor; patchcode.bin, + patchinst.bin and patch.bin. The former file is the assembled debug monitor, + while the latter file is a small software routine whose purpose is to + install and patch the debug monitor (patchcode.bin) into the kernel. + Finally, patch.bin are the two files combined, with patchcode.bin conca- + tenated over patchinst.bin as a payload. + + The patch.bin file is intended for use with LITELOAD and n00bROM's 'Patch + Binary' loader- this function simply downloads the binary file to a fixed + address (80010000h), flush the instruction cache with FlushCache() and calls + it as a function routine. The binary would perform a call-return jump + to return to the loader after performing kernel patches, so LITELOAD or + n00bROM can resume for downloading a PS-EXE next. + + The monitor code resides in the reserved kernel memory region between + address 8000C000h to 8000DFFFh (8KBytes) and is generally unused by + most if not all software titles, with exception of unlicensed CD + based cheat software such as Gameshark CD. + + Once copied, the monitor is patched into the kernel with the following + operations: + + * Exception vector on 80000080h is modified to preserved the contents + of the cop0 DCIC register to a predetermined address, before the jump + to the BIOS exception hander with DCIC cleared. + + * The debug exception vector at 80000040h is patched with a jump + to the debug monitor for trapping exceptions pertaining to debugging + (ie. trace, break on address). The routine also preserves k0, k1 and + cop0 DCIC registers to predetermined addresses for use by the monitor + later. + + * The monitor is hooked to BIOS functions ReturnFromException() (B(57h)) + and SysErrUnresolvedException() (A(40h)) by patching the BIOS function + tables. The original address of ReturnFromException() is preserved in + the monitor for use as a return address after it has finished servicing + itself for pending commands. + + Since the debug monitor is hooked to the exception handling subsystem, the + monitor operates like a background task over the current program and can + carry out debug operations completely transparently to the main program. + By design, the monitor depends on constant interrupts (such as Vblank) to + be able to service incoming commands- so when a program disables interrupts + and enters an infinite loop, the debugger is no longer able to respond to + commands. + + To mitigate this a special break instruction provided in the pollhost() + macro (break 1024) can be used inside loops suspected for locking up the + program. The debug monitor will catch the breakpoint exception of this + instruction and ignore it by resuming execution, but this will allow the + monitor to service itself without interrupts via break exceptions. + + Alternatively setting a program breakpoint that only counts iterations + can be used over pollhost() to keep the debug monitor serviced. + + +== Improved Single Step == + + The old debugger implemented instruction step by simply setting the Program + Break address from the Program Counter address, adjusted to be just an inst- + ruction ahead of the current Program Counter. While the same method is also + employed in this new debugger for instruction step, this method does not + work directly for non-sequential, or branching, instructions. + + The old debugger would inefficiently decipher the non-sequential instruction + and manually determine whether a branch is taken or not just to predict where + the next program counter is going to be on- despite cop0 providing debug + registers specifically for this purpose. This method, of course, is + inefficient, and wastes a lot of code space just for the branch interpreter. + + The new PSn00bDBG-Mk2 debugger makes use of the debug registers and eliminates + the need for code to interpret non-sequential instructions, freeing up code + space for other features. + + +== Multiple Program Breakpoints == + + PSn00bDBG-Mk2 supports up to 32 simultaneous program breakpoints with + execution counters and optional conditions. These breakpoints are + implemented by patching break instructions to designated points of the + program text- not without backing up the original instruction of + course. + + When one of these breakpoints is encountered by the Program Counter, a break + exception occurs and the debug monitor halts program execution. Before debu + operations are carried out the break instruction is restored to the original + instruction, both so the breakpoint patches would not be visible from the + debugger's perspective, but also to restore the original program logic when + program execution is resumed from a break. The patches are re-applied when + resuming execution, and is done in such a way that the patches are performed + transparently from the debugging host. + + This allows the debugger to support up to 32 program breakpoints with + virtually zero impact on processing performance. However, because it + relies on patching the program text to place break instructions, this does + not work on code located outside of RAM- such as the BIOS ROM or an + expansion cartridge ROM. |
