12.11.2. Programming breakpoints and watchpoints

This section describes the following operations:

Programming simple breakpoints and the byte address select

When programming a simple breakpoint, you must set the byte address select bits in the control register appropriately. For a breakpoint in ARM state, this is simple. For Thumb state, you must calculate the value based on the address.

For a simple breakpoint, you can program the settings for the other control bits as Table 12.42 shows:

Table 12.42. Values to write to DBGBCR for a simple breakpoint

BitsValue to writeDescription
[31:29]0b000Reserved
[28:24]0b00000Breakpoint address mask
[23]0b0Reserved
[22:20]0b000Meaning of DBGBVR
[19:16]0b0000Linked BRP number
[15:9]0b00Reserved
[8:5]Derived from addressByte address select
[4:3]0b00Reserved
[2:1]0b11Supervisor access control
[0]0b1Breakpoint enable

Example 12.7 shows the sequence of instructions for setting a simple breakpoint.

Example 12.7. Setting a simple breakpoint

SetSimpleBreakpoint(int break_num, uint32 address, iset_t isa)
{
    // Step 1. Disable the breakpoint being set.
    WriteDebugRegister(80 + break_num, 0x0);
    // Step 2. Write address to the DBGBVR, leaving the bottom 2 bits zero.
    WriteDebugRegister(64 + break_num, address & 0xFFFFFFC);
    // Step 3. Determine the byte address select value to use.
    case (isa) of
    {
    // Note: The processor does not support Jazelle or ThumbEE states
    when THUMB:
        byte_address_select := (3 << (address & 2));
    when ARM:
        byte_address_select := 15;
    }
    // Step 4. Write the mask and control register to enable the breakpoint.
    WriteDebugRegister(80 + break_num, 7 | (byte_address_select << 5));
}

Setting a simple aligned watchpoint

The simplest and most common type of watchpoint watches for a write to a given address in memory. In practice, a data object spans a range of addresses but is aligned to a boundary corresponding to its size, so you must set the byte address select bits in the same way as for a breakpoint.

For a simple watchpoint, you can program the settings for the other control bits as Table 12.43 shows:

Table 12.43. Values to write to DBGWCR for a simple watchpoint

BitsValue to writeDescription
[31:29]0b000Reserved
[28:24]0b00000Watchpoint address mask
[23:21]0b000Reserved
[20]0b0Enable linking
[19:16]0b0000Linked BRP number
[15:13]0b00Reserved
[12:5]Derived from addressByte address select
[4:3]0b10Load/Store access control
[2:1]0b11Privileged access control
[0]0b1Watchpoint enable

Example 12.8 shows the code for setting a simple aligned watchpoint.

Example 12.8. Setting a simple aligned watchpoint

SetSimpleAlignedWatchpoint(int watch_num, uint32 address, int size)
{
    // Step 1. Disable the watchpoint being set.
    WriteDebugRegister(112 + watch_num, 0);
    // (Step 2. Write address to the DBGWVR, leaving the bottom 3 bits zero.
    WriteDebugRegister(96 + watch_num, address & 0xFFFFFF8);
    // Step 3. Determine the byte address select value to use.
    case (size) of
    {
    when 1:
        byte_address_select := (1 << (address & 7));
    when 2:
        byte_address_select := (3 << (address & 6));
    when 4:
        byte_address_select := (15 << (address & 4));
    when 8:
        byte_address_select := 255;
    }
    // Step 4. Write the mask and control register to enable the watchpoint.
    WriteDebugRegister(112 + watch_num, 23 | (byte_address_select << 5));
}

Setting a simple unaligned watchpoint

Using the byte address select bits, certain unaligned objects up to a doubleword (64 bits) can be watched in a single watchpoint. However, this cannot cover all cases, and in many cases a second watchpoint might be required.

Table 12.44 shows some examples.

Table 12.44. Example byte address masks for watchpointed objects

Address of object

Object size in bytes

First address value

First byte address mask

Second address value

Second byte address mask

0x0000800010x000080000b00000001Not required-
0x0000800710x000080000b10000000Not required-
0x0000900020x000090000b00000011Not required-
0x0000900c20x000090000b11000000Not required-
0x0000900d20x000090000b100000000x000090080b00000001
0x0000A00040x0000A0000b00001111Not required-
0x0000A00340x0000A0000b01111000Not required-
0x0000A00540x0000A0000b111000000x0000A0080b00000001
0x0000B00080x0000B0000b11111111Not required-
0x0000B00180x0000B0000b111111100x0000B0080b00000001

Example 12.9 shows the code for setting a simple unaligned watchpoint.

Example 12.9. Setting a simple unaligned watchpoint

bool SetSimpleWatchpoint(int watch_num, uint32 address, int size)
{
    // Step 1. Disable the watchpoint being set.
    WriteDebugRegister(112 + watch_num, 0x0);
    // Step 2. Write addresses to the DBGWVRs, leaving the bottom 3 bits zero.
    WriteDebugRegister(96 + watch_num, (address & 0xFFFFFF8));
    // Step 3. Determine the byte address select value to use.
    byte_address_select := (1 << size) - 1;
    byte_address_select := (byte_address_select) << (address & 7);
    // Step 4. Write the mask and control register to enable the breakpoint.
    WriteDebugRegister (112 + watch_num, 5'b23 | ((byte_address_select & 0xFF) << 5));
    // Step 5. Set second watchpoint if required. This is the case if the byte
    // address mask is more than 8 bits.
    if (byte_address_select >= 256)
    {
        WriteDebugRegister(112 + watch_num + 1, 0);
        WriteDebugRegister(96 + watch_num + 1, (address & 0xFFFFFF8) + 8);
        WriteDebugRegister(112 + watch_num + 1 23| ((byte_address_select & 0xFF00) >> 3));
    }
    // Step 6. Return flag to caller indicating if second watchpoint was used.
    return (byte_address_select >= 256)
}

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