12.11.1. Debug communications channel

There are two ways that an external debugger can send data to or receive data from the processor:

Rules for accessing the DCC

At the processor side, the debug communications channel resources are:

  • CP14 Debug Register c5 (DTR, comprising DBGDTRTXint and DBGDTRRXint)

  • CP14 Debug Register c1 (DBGDSCRint).

The ARMv7 debug architecture is implemented on the processor so that:

  • If a read of the DBGDSCRint returns 1 for the RXfull flag, a following read of the DBGDTRRXint returns valid data and RXfull is cleared. No ISB is required between these two CP14 instructions.

  • If a read of the CP14 DBGDSCRint returns 1 for the TXfull flag, a following write to the DBGDTRTXext is Unpredictable.

  • If a read of the CP14 DBGDSCRint returns 0 for the RXfull flag, a following read of the CP14 DTR returns an Unpredictable value.

  • If a read of the CP14 DBGDSCRint returns 0 for the TXfull flag, a following write to the CP14 DTR writes the intended 32-bit word, and sets TXfull to 1. No ISB is required between these two CP14 instructions.

When Nonblocking mode is selected for DTR accesses, the following conditions are true for memory-mapped DBGDSCR, DBGDTRRXext, and DBGDTRTXext registers:

  • If a read of the DBGDSCRext returns 0 for the TXfull flag, a following read of the memory-mapped DBGDTRTX is ignored. The content of TXfull is unchanged and the read returns an UNKNOWN value.

  • If a read of the DBGDSCRext returns 0 for the RXfull flag, a following write of the memory-mapped DBGDTRRX passes valid data to the processor and sets RXfull to 1.

  • If a read of the DBGDSCRext returns 1 for the TXfull flag, a following read of the DBGDTRTXext returns valid data and clears TXfull.

  • If a read of the DBGDSCRext returns 1 for the RXfull flag, a following write of the memory-mapped DBGDTRRXext is ignored, that is, both RXfull and DBGDTRRX contents are unchanged.

Software access to the DCC

Software running on the processor that sends data to the debugger through the target-to-host channel can use the sequence of instructions that Example 12.2 shows.

Example 12.2. Target to host data transfer (target end)

            ; r0 -> word to send to the debugger
WriteDCC    MRC        p14, 0, PC, c0, c1, 0
            BEQ        WriteDCC
            MCR        p14, 0, Rd, c0, c5, 0
            BX         lr

Example 12.3 shows the sequence of instructions for sending data to the debugger through the host-to-target channel.

Example 12.3. Host to target data transfer (target end)

            ; r0 -> word sent by the debugger
ReadDCC     MRC        p14, 0, PC, c0, c1, 0
            BCC        ReadDCC
            MRC        p14, 0, Rd, c0, c5, 0
            BX         lr

Debugger access to the DCC

A debugger can access the DCC through the external interface. The following examples show the pseudo-code operations for these accesses.

Example 12.4 shows the code for target-to-host data transfer.

Example 12.4. Target to host data transfer (host end)

uint32        ReadDCC()
{
        // Step 1. Poll DBGDSCR until TXfull is set to 1.
        repeat
        {
            dbgdscr := ReadDebugRegister(34);
        }
        until (dbgdscr & (1<<29));
        // Step 2. Read the value from DBGDTRTX.
        dtr_val := ReadDebugRegister(35);

        return dtr_val;
}

Example 12.5 shows the code for host-to-target data transfer.

Example 12.5. Host to target data transfer (host end)

WriteDCC(uint32 dtr_val)
{
        // Step 1. Poll DBGDSCR until RXfull is clear.
        repeat
        {
            dbgdscr := ReadDebugRegister(34);
        }
        until (!(dbgdscr & (1<<30)));
        // Step 2. Write the value to DBGDTRRX.
        WriteDebugRegister(32, dtr_val);
}

While the processor is running, if the DCC is used as a data channel, it might be appropriate to poll the DCC regularly.

Example 12.6 shows the code for polling the DCC.

Example 12.6. Polling the DCC (host end)

PollDCC
{
    dbgdscr := ReadDebugRegister(34);
    if (dbgdscr & (1<<29))
    {
        // DBGDTRTX (target -> host transfer register) full
        dtr := ReadDebugRegister(35)
        ProcessTargetToHostWord(dtr);
    }
    if (!(dbgdscr & (1<<30)))
    {
        // DBGDTRRX (host -> target transfer register) empty
        dtr := GetNextHostToTargetWord()
        WriteDebugRegister(32, dtr);
    }
}

Copyright © 2010-2011 ARM. All rights reserved.ARM DDI 0460C
Non-ConfidentialID021511