53 lines
3.9 KiB
Plaintext
53 lines
3.9 KiB
Plaintext
== Debug
|
|
|
|
Currently the plan is for Hazard3, with its associated debug module (DM), to support the following:
|
|
|
|
* Run/halt/reset control as required
|
|
* Abstract GPR access as required
|
|
* Program buffer: 2 words plus `impebreak`
|
|
* Automatic program buffer execution triggered by abstract GPR access (`abstractauto`)
|
|
* Some minimum useful trigger unit -- likely just breakpoints, no watchpoints
|
|
|
|
The core itself will implement the following, enabling the DM to provide a compliant debug interface:
|
|
|
|
* Debug mode CSRs
|
|
* Ability to enter debug mode with correct update of `dpc` etc
|
|
** Synchronously via exception, `ebreak` or trigger match
|
|
** Asynchronously via external halt request
|
|
* Ability to exit debug mode to M mode
|
|
* Address query/match interface for external trigger unit
|
|
* Ability to inject words into the instruction prefetch queue when the processor is halted
|
|
* Ability to suppress exception entry when executing instructions in debug mode, and provide an external signal to indicate the exception took place
|
|
* A read/write data bus which allows the DM to intercept core CSR accesses
|
|
|
|
The DM implements abstract GPR access by injecting a dummy CSR access instruction, and manipulating the CSR port to get data in/out of the core. A `csrr` is used to write to a core register, and a `csrw` to read from a core register. By injecting a `csrrw`, the DM can _swap_ a GPR with one of its own internal registers, though this is not exposed through the abstract GPR access command.
|
|
|
|
The debugger implements memory and CSR access using the Program Buffer, which uses the same instruction injection interface used by the DM to implement abstract GPR access. The `abstractauto` feature allows the DM to execute the program buffer automatically following every abstract GPR access, which can be used for e.g. autoincrementing read/write memory bursts.
|
|
|
|
=== UART DTM
|
|
|
|
Hazard3 defines a minimal UART Debug Transport Module, which allows the Debug Module to be accessed via a standard 8n1 asynchronous serial port. The UART DTM is always accessed by the host using a two-wire serial interface (TXD RXD) running at 1 Mbaud. The interface between the DTM and DM is an AMBA 3 APB port with a 32-bit data bus and 8-bit address bus.
|
|
|
|
This is not intended for production systems:
|
|
|
|
* Debug hardware should not expect a frequency reference for a UART to be present
|
|
* The UART DTM does not implement any flow control or error detection/correction
|
|
|
|
However, it suffices for bringup and playing around on FPGA boards. The host sends a 6-byte packet:
|
|
|
|
* Command:
|
|
** `0x00` nop, ignored, next command can follow immediately (no address or data bytes, no response)
|
|
** `0x01` read
|
|
** `0x02` write
|
|
** `0xa5` return to idle (no address or data bytes, no response)
|
|
* One address byte
|
|
* 4 data bytes (write) or 4 zero-padding bytes (read)
|
|
|
|
The 6-byte framing can be recovered at any time by writing 6 zero-bytes, which will be interpreted as between 1 and 6 nops depending on current DTM state.
|
|
|
|
The DTM always responds with four data bytes. For a read command this will be the data read from the given address. For a write command this will echo back the write data.
|
|
|
|
This interface assumes the actual data transfer takes very little time compared with the UART access (typically less than one baud period). Because the host-to-DTM bandwidth is always greater than the DTM-to-host bandwidth, the host can queue up batches of commands in its transmit buffer, and this should never overrun the DTM's response channel. So, the 1 Mbaud 8n1 UART link provides 67 kB/s of half-duplex data bandwidth between host and DM, which is enough to get your system off the ground.
|
|
|
|
Initially after power-on the DTM is in the idle state, and will ignore any commands. The host sends the magic sequence `'S', 'U', 'P', '?'` (`0x53, 0x55, 0x50, 0x3f`) to wake the DTM, and then attempts to access a read-only DM register such as `dmstatus` to make sure the link is up. The DTM can be returned to the idle at any time using the `0xa5` return-to-idle command.
|