\chapter{Sdext ISA Extension}
\label{sec:core_debug}

This chapter describes the Sdext ISA extension. It must be implemented to make
external debug work, and is only useful in conjunction with external debug.

Modifications to the RISC-V core to support debug are kept to a minimum.  There
is a special execution mode (Debug Mode) and a few extra CSRs. The DM takes care
of the rest.

In order to be compatible with this specification an implementation must
implement everything described in this section that is not explicitly listed as
optional.

\section{Debug Mode} \label{debugmode}

Debug Mode is a special processor mode used only when a hart is halted for
external debugging. Because the hart is halted, there is no forward progress in
the normal instruction stream.
How Debug Mode is implemented is not specified here.

\begin{steps}{When executing code due to an abstract command, the hart stays in
    Debug Mode and the following apply:}
\item All implemented instructions operate just as they do in M-mode, unless
    an exception is mentioned in this section.
\item All operations are executed with machine mode privilege, except that
    additional Debug Mode CSRs are accessible and
    \FcsrMstatusMprv in \Rmstatus may be ignored according to \FcsrDcsrMprven.
    Full permission checks, or a relaxed set of permission checks, will apply
    according to \FdmAbstractcsRelaxedpriv.
\item All interrupts (including NMI) are masked.
\item Traps don't take place. Instead, they end execution of the program buffer
    and the hart remains in Debug Mode. Because they do not trap to M-mode, they
    do not update registers such as \Rmstatus, {\tt mepc}, {\tt mcause}, {\tt
    mtval}, {\tt mtval2}, and {\tt mtinst}.  The same is true for the equivalent
    privileged registers that are updated when trapping to other modes.
    Registers that may be updated as part of execution before the exception are
    allowed to be updated.  For example, vector load/store instructions which
    raise exceptions may partially update the destination register and set
    {\tt vstart} appropriately.
\item Triggers don't match or fire.
\item If \FcsrDcsrStopcount is 0 then counters continue. If it is 1 then
    counters are stopped.
\item If \FcsrDcsrStoptime is 0 then \Rtime continues to update. If
    it is 1 then \Rtime will not update. It will resynchronize with
    \Rmtime after leaving Debug Mode.
\item Instructions that place the hart into a stalled state act as a {\tt nop}.
    This includes {\tt wfi}, {\tt wrs.sto}, and {\tt wrs.nto}.
\item Almost all instructions that change the privilege mode have \unspecified\
    behavior.  This includes {\tt ecall}, {\tt mret}, {\tt sret}, and {\tt uret}.
    (To change the privilege mode, the debugger can write
    \FcsrDcsrPrv and \FcsrDcsrV in \RcsrDcsr). The only exception is {\tt ebreak}, which ends
    execution of the Program Buffer when executed.
\item All control transfer instructions may act as illegal instructions if
    their destination is in the Program Buffer. If one such instruction acts as
    an illegal instruction, all such instructions must act as illegal
    instructions.
\item All control transfer instructions may act as illegal instructions if
    their destination is outside the Program Buffer. If one such instruction
    acts as an illegal instruction, all such instructions must act as
    illegal instructions.
\item Instructions that depend on the value of the PC (e.g.\ {\tt auipc}) may act
    as illegal instructions.
\item Effective XLEN is DXLEN.
\item Forward progress is guaranteed.
\end{steps}

\begin{commentary}
    When \FcsrDcsrMprven=1, the external debugger can set MPRV and MPP appropriately to
    have hardware perform memory accesses with the appropriate endianness, address
    translation, permission checks, and PMP/PMA checks (subject to \FdmAbstractcsRelaxedpriv).
    This is also the only way to access all of physical memory when 34-bit physical
    addresses are supported on a Sv32 hart. If hardware ties \FcsrDcsrMprven to 0 then the
    external debugger is expected to simulate all the effects of MPRV, including
    any extensions that affect memory accesses.
    For these reasons it is recommended to tie \FcsrDcsrMprven to 1.
\end{commentary}

\section{Load-Reserved/Store-Conditional Instructions}

The reservation registered by an {\tt lr} instruction on a memory address may
be lost when entering Debug Mode or while in Debug Mode.  This means that there
may be no forward progress if Debug Mode is entered between {\tt lr} and {\tt
sc} pairs.

\begin{commentary}
    This is a behavior that debug users must be aware of. If they have a
    breakpoint set between a {\tt lr} and {\tt sc} pair, or are stepping
    through such code, the {\tt sc} may never succeed.  Fortunately in general use
    there will be very few instructions in such a sequence, and anybody
    debugging it will quickly notice that the reservation is not occurring.
    The solution in that case is to set a breakpoint on the first instruction
    after the {\tt sc} and run to it. A higher level debugger may choose to
    automate this.
\end{commentary}

\section{Wait for Interrupt Instruction}

If halt is requested while {\tt wfi} is executing, then the hart must leave the
stalled state, completing this instruction's execution, and then enter Debug
Mode.

\section{Wait-on-Reservation-Set Instructions}

If halt is requested while {\tt wrs.sto} or {\tt wrs.nto} is executing, then the
hart must leave the stalled state, completing this instruction's execution, and
then enter Debug Mode.

\section{Single Step}

\subsection{Step Bit In Dcsr} \label{stepBit}

This method is only available to external debuggers, and is the preferred way
to single step.

An external debugger can cause a halted hart to execute a single instruction or
trap and then re-enter Debug Mode by setting \FcsrDcsrStep before resuming.  If
\FcsrDcsrStep is set when a hart resumes then it will single step, regardless
of the reason for resuming.

If control is transferred to a trap handler while executing the instruction,
then Debug Mode is re-entered immediately after the PC is changed to the trap
handler, and the appropriate {\tt tval} and {\tt cause} registers are updated.
In this case none of the trap handler is executed, and if the cause was a
pending interrupt no instructions might be executed at all.

If executing or fetching the instruction causes a trigger to fire with action=1, Debug Mode
is re-entered immediately after that trigger has fired. In that case \FcsrDcsrCause is
set to 2 (trigger) instead of 4 (single step).  Whether the instruction is
executed or not depends on the specific configuration of the trigger.

If the instruction that is executed causes the PC to change to an address where
an instruction fetch causes an exception, that exception does not occur until
the next time the hart is resumed. Similarly, a trigger at the new address does
not fire until the hart actually attempts to execute that instruction.

If the instruction being stepped over would normally stall the hart, then
instead the instruction is treated as a {\tt nop}. This includes {\tt wfi},
{\tt wrs.sto}, and {\tt wrs.nto}.

\subsection{Icount Trigger}

Native debuggers won't have access to \RcsrDcsr, but can use the \RcsrIcount
trigger by setting \FcsrIcountCount to 1.

\begin{steps}{This approach does have some limitations:}
    \item Interrupts will fire as usual. Debuggers that want to disable
        interrupts while stepping must disable them by changing \Rmstatus, and
        specially handle instructions that read \Rmstatus.
    \item {\tt wfi} instructions are not treated specially and might take a
        very long time to complete.
\end{steps}

This mechanism cleanly supports a system which supports multiple privilege
levels, where the OS or a debug stub runs in M-Mode while the program being
debugged runs in a less privileged mode. Systems that only support M-Mode can
use \RcsrIcount as well, but count must be able to count several instructions
(depending on the software implementation). See Section \ref{nativestep}.

\section{Reset}

If the halt signal (driven by the hart's halt request bit in the Debug Module)
or \Fresethaltreq are asserted when a hart comes out of reset, the hart must
enter Debug Mode before executing any instructions, but after performing any
initialization that would usually happen before the first instruction is
executed.

\section{Halt}

\begin{steps}{When a hart halts:}
    \item \FcsrDcsrCause is updated.
    \item \FcsrDcsrPrv and \FcsrDcsrV are set to reflect current privilege mode.
    \item \RcsrDpc is set to the next instruction that should be executed.
    \item If the current instruction can be partially executed and should be
        restarted to complete, then the relevant state for that is updated. E.g.
        if a halt occurs during a partially executed vector instruction, then
        {\tt vstart} is updated, and \RcsrDpc is updated to the address of the
        partially executed instruction. This is analogous to how vector
        instructions behave for exceptions.
    \item The hart enters Debug Mode.
\end{steps}

\section{Resume}

\begin{steps}{When a hart resumes:}
    \item \Rpc changes to the value stored in \RcsrDpc.
    \item The current privilege mode and virtualization mode are changed to that specified by
        \FcsrDcsrPrv and \FcsrDcsrV.
    \item If the new privilege mode is less privileged than M-mode,
        \FcsrMstatusMprv in \Rmstatus is cleared.
    \item The hart is no longer in debug mode.
\end{steps}

\section{XLEN}

While in Debug Mode, XLEN is DXLEN. It is up to the debugger to determine the
XLEN during normal program execution (by looking at \Rmisa) and to clearly
communicate this to the user.

\section{Core Debug Registers} \label{debreg}

The supported Core Debug Registers must be implemented for each hart that can
be debugged. They are CSRs, accessible using the RISC-V {\tt csr} opcodes and
optionally also using abstract debug commands.

Attempts to access a non-existent Core Debug Register raise an illegal
instruction exception.

\input{core_registers.tex}

\section{Virtual Debug Registers} \label{virtreg}

\input{sw_registers.tex}
