12.11.2. Programming breakpoints and watchpoints

The following operations are described in this section:

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 or ThumbEE, 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.58 shows:

Table 12.58. Values to write to BCR for a simple breakpoint

BitsValue to writeDescription
[31:29]b000Reserved
[28:24]b00000Breakpoint address mask
[23]b0Reserved
[22:20]b000Meaning of BVR
[19:16]b0000Linked BRP number
[15:14]b00Secure state access control
[13:9]b00000Reserved
[8:5]Derived from addressByte address select
[4:3]b00Reserved
[2:1]b11Supervisor access control
[0]b1Breakpoint 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 BVR, 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 state,
    // but the ARMv7 Debug architecture does
when JAZELLE:
        byte_address_select := (1'b1 << (address & 3));
    when THUMB, THUMBEE:
        byte_address_select := (2'b11 << (address & 2));
    when ARM:
        byte_address_select := 4'b1111;
    }
    // Step 4. Write the mask and control register to enable the breakpoint.
    WriteDebugRegister(80 + break_num, 3'b111 | (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.59 shows:

Table 12.59. Values to write to WCR for a simple watchpoint

BitsValue to writeDescription
[31:29]b000Reserved
[28:24]b00000Watchpoint address mask
[23:21]b000Reserved
[20]b0Enable linking
[19:16]b0000Linked BRP number
[15:14]b00Secure state access control
[13]b0Reserved
[12:5]Derived from addressByte address select
[4:3]b10Load/Store access control
[2:1]b11Privileged access control
[0]b1Watchpoint 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 WVR, 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'b1 << (address & 7));
    when 2:
        byte_address_select := (2'b11 << (address & 6));
    when 4:
        byte_address_select := (4'b1111 << (address & 4));
    when 8:
        byte_address_select := 8'b11111111;
    }
    // Step 4. Write the mask and control register to enable the watchpoint.
    WriteDebugRegister(112 + watch_num, 5'b10111 | (byte_address_select << 5));
}

Setting a simple unaligned watchpoint

Using the byte address select bits, certain unaligned objects up to a double-word (64 bits) can be watched in a single watchpoint. However, not all cases can be covered and in many cases, a second watchpoint might be required.

Table 12.60 shows some examples.

Table 12.60. Example byte address masks for watchpointed objects

Address of objectObject size in bytesFirst address valueFirst byte address maskSecond address valueSecond byte address mask
0x0000800010x00008000b00000001Not required-
0x0000800710x00008000b10000000Not required-
0x0000900020x00009000b00000011Not required-
0x0000900c20x00009000b11000000Not required-
0x0000900d20x00009000b100000000x00009008b00000001
0x0000A00040x0000A000b00001111Not required-
0x0000A00340x0000A000b01111000Not required-
0x0000A00540x0000A000b111000000x0000A008b00000001
0x0000B00080x0000B000b11111111Not required-
0x0000B00180x0000B000b111111100x0000B008b00000001

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 WVRs, 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'b1 << size) - 1;
    byte_address_select := (byte_address_select) << (address & 3'b111);
    // Step 4. Write the mask and control register to enable the breakpoint.
    WriteDebugRegister (112 + watch_num, 5'b10111 | ((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 >= 9'b100000000)
    {
        WriteDebugRegister(112 + watch_num + 1, 0);
        WriteDebugRegister(96 + watch_num + 1, (address & 0xFFFFFF8) + 8);
        WriteDebugRegister(112 + watch_num + 1 5'b10111 | ((byte_address_select & 0xFF00) >> 3));
    }
    // Step 6. Return flag to caller indicating if second watchpoint was used.
    return (byte_address_select >= 9'b100000000)
}

Copyright © 2006-2009 ARM Limited. All rights reserved.ARM DDI 0344I
Non-Confidential