<!-- SPDX-License-Identifier: BSD-2-Clause OR CC-BY-4.0 -->

<!--
This file is dual-licensed. You may choose to use this file under the terms of
either of the above licenses.

Note: This dual licensing does not apply to other files that may be part of the
same project unless stated otherwise.
-->

<registers name="JTAG DTM TAP Registers" label="jtag_registers" prefix="DTM_">
    <!-- JTAG standard registers, everything starting with 0 -->
    <register name="BYPASS" address="0x00" sdesc="JTAG recommends this encoding"/>
    <register name="IDCODE" address="0x01" sdesc="To identify a specific silicon version">
        This register is selected (in IR) when the TAP state machine is reset.
        Its definition is exactly as defined in IEEE Std 1149.1-2013.

        <field name="Version" bits="31:28" access="R" reset="Preset">
            Identifies the release version of this part.
        </field>
        <field name="PartNumber" bits="27:12" access="R" reset="Preset">
            Identifies the designer's part number of this part.
        </field>
        <field name="ManufId" bits="11:1" access="R" reset="Preset">
            Identifies the designer/manufacturer of this part. Bits 6:0 must be
            bits 6:0 of the designer/manufacturer's Identification Code as
            assigned by JEDEC Standard JEP106. Bits 10:7 contain the modulo-16
            count of the number of continuation characters (0x7f) in that same
            Identification Code.
        </field>
        <field name="1" bits="0" access="R" reset="1"></field>
    </register>
    <!-- All our registers start with 1. -->

    <register name="DTM Control and Status" short="dtmcs" address="0x10"
        sdesc="For Debugging" define="1">
        The size of this register will remain constant in future versions so
        that a debugger can always determine the version of the DTM.
        <field name="0" bits="31:21" access="R" reset="0" />
        <field name="errinfo" bits="20:18" access="R" reset="4">
            This optional field may provide additional detail about an error
            that occurred when communicating with a DM. It is updated whenever
            {dmi-op} is updated by the hardware or when 1 is written to
            {dtmcs-dmireset}.

            <value v="0" name="not implemented">
                This field is not implemented.
            </value>

            <value v="1" name="dmi error">
                There was an error between the DTM and DMI.
            </value>

            <value v="2" name="communication error">
                There was an error between the DMI and a DMI subordinate.
            </value>

            <value v="3" name="device error">
                The DMI subordinate reported an error.
            </value>

            <value v="4" name="unknown">
                There is no error to report, or no further information available
                about the error. This is the reset value if the field is implemented.
            </value>

            Other values are reserved for future use by this specification.
        </field>
        <field name="dtmhardreset" bits="17" access="W1" reset="-">
          Writing 1 to this bit does a hard reset of the DTM,
          causing the DTM to forget about any outstanding DMI transactions, and
          returning all registers and internal state to their reset value.
          In general this should only be used when the Debugger has
          reason to expect that the outstanding DMI transaction will never
          complete (e.g. a reset condition caused an inflight DMI transaction to
          be cancelled).
        </field>
        <field name="dmireset" bits="16" access="W1" reset="-">
            Writing 1 to this bit clears the sticky error state and resets
            {dtmcs-errinfo}, but does not affect outstanding DMI transactions.
        </field>
        <field name="0" bits="15" access="R" reset="0" />
        <field name="idle" bits="14:12" access="R" reset="Preset">
            This is a hint to the debugger of the minimum number of
            cycles a debugger should spend in
            Run-Test/Idle after every DMI scan to avoid a `busy'
            return code ({dtmcs-dmistat} of 3). A debugger must still
            check {dtmcs-dmistat} when necessary.

            0: It is not necessary to enter Run-Test/Idle at all.

            1: Enter Run-Test/Idle and leave it immediately.

            2: Enter Run-Test/Idle and stay there for 1 cycle before leaving.

            And so on.
        </field>
        <field name="dmistat" bits="11:10" access="R" reset="0">
            Read-only alias of {dmi-op}.
        </field>
        <field name="abits" bits="9:4" access="R" reset="Preset">
            The size of {sbaddress0-address} in {dtm-dmi}.
        </field>
        <field name="version" bits="3:0" access="R" reset="1">
            <value v="0" name="0.11">
            Version described in spec version 0.11.
            </value>

            <value v="1" name="1.0">
            Version described in spec versions 0.13 and 1.0.
            </value>

            <value v="15" name="custom">
            Version not described in any available version of this spec.
            </value>
        </field>
    </register>

    <register name="Debug Module Interface Access" short="dmi" address="0x11"
        sdesc="For Debugging">
        This register allows access to the Debug Module Interface (DMI).

        In Update-DR, the DTM starts the operation specified in {dmi-op} unless the
        current status reported in {dmi-op} is sticky.

        In Capture-DR, the DTM updates {sbdata0-data} with the result from that
        operation, updating {dmi-op} if the current {dmi-op} isn't sticky.

        See xref:dmiaccess[] for examples of how this is used.

        [NOTE]
        ====
        The still-in-progress status is sticky to accommodate debuggers that
        batch together a number of scans, which must all be executed or stop as
        soon as there's a problem.

        For instance a series of scans may write a Debug Program and execute
        it.  If one of the writes fails but the execution continues, then the
        Debug Program may hang or have other unexpected side effects.
        ====

        <field name="address" bits="abits+33:34" access="R/W" reset="0">
            Address used for DMI access. In Update-DR this value is used
            to access the DM over the DMI.
            {dmi-op} defines what this register contains after every possible
            operation.
        </field>
        <field name="data" bits="33:2" access="R/W" reset="0">
            The data to send to the DM over the DMI during Update-DR, and
            the data returned from the DM as a result of the previous operation.
        </field>
        <field name="op" bits="1:0" access="R/W" reset="0">
            When the debugger writes this field, it has the following meaning:

            <value v="0" name="nop">
            Ignore {sbdata0-data} and {sbaddress0-address}.

            Don't send anything over the DMI during Update-DR.
            This operation should never result in a busy or error response.
            The address and data reported in the following Capture-DR
            are undefined.

            This operation leaves the values in {dmi-address} and {dmi-data}
            UNSPECIFIED.
            </value>

            <value v="1" name="read">
            Read from {dmi-address}.

            When this operation succeeds, {dmi-address} contains the address
            that was read from, and {dmi-data} contains the value that was
            read.
            </value>

            <value v="2" name="write">
            Write {dmi-data} to {dmi-address}.

            This operation leaves the values in {dmi-address} and {dmi-data}
            UNSPECIFIED.
            </value>

            <value v="3" name="reserved">
            Reserved.
            </value>

            When the debugger reads this field, it means the following:

            <value v="0" name="success" duplicate="1">
            The previous operation completed successfully.
            </value>

            <value v="1" name="reserved" duplicate="1">
            Reserved.
            </value>

            <value v="2" name="failed" duplicate="1">
            A previous operation failed.  The data scanned into {dtm-dmi} in
            this access will be ignored.  This status is sticky and can be
            cleared by writing {dtmcs-dmireset} in {dtm-dtmcs}.

            This indicates that the DM itself or the DMI responded with an error.
            There are no specified cases in which the DM would
            respond with an error, and DMI is not required to support
            returning errors.

            If a debugger sees this status, there might be additional
            information in {dtmcs-errinfo}.
            </value>

            <value v="3" name="busy" duplicate="1">
            An operation was attempted while a DMI request is still in
            progress. The data scanned into {dtm-dmi} in this access will be
            ignored. This status is sticky and can be cleared by writing
            {dtmcs-dmireset} in {dtm-dtmcs}. If a debugger sees this status, it
            needs to give the target more TCK edges between Update-DR and
            Capture-DR. The simplest way to do that is to add extra transitions
            in Run-Test/Idle.
            </value>
        </field>
    </register>

    <register name="Reserved (BYPASS)" address="0x12" sdesc="Reserved for future RISC-V debugging"/>
    <register name="Reserved (BYPASS)" address="0x13" sdesc="Reserved for future RISC-V debugging"/>
    <register name="Reserved (BYPASS)" address="0x14" sdesc="Reserved for future RISC-V debugging"/>
    <register name="Reserved (BYPASS)" address="0x15" sdesc="Reserved for future RISC-V standards"/>
    <register name="Reserved (BYPASS)" address="0x16" sdesc="Reserved for future RISC-V standards"/>
    <register name="Reserved (BYPASS)" address="0x17" sdesc="Reserved for future RISC-V standards"/>

    <register name="BYPASS" address="0x1f" sdesc="JTAG requires this encoding">
        1-bit register that has no effect. It is used when a debugger does not
        want to communicate with this TAP.

        <field name="0" bits="0" access="R" reset="0" />
    </register>

</registers>
