## 10 TAP Declaration ¶

Test Access Ports (TAPs) are the core of JTAG. TAPs serve many roles, including:

- Debug Target A CPU TAP can be used as a GDB debug target.
- Flash Programming Some chips program the flash directly via JTAG. Others do it indirectly, making a CPU do it.
- Program Download Using the same CPU support GDB uses, you can initialize a DRAM controller, download code to DRAM, and then start running that code.
- Boundary Scan Most chips support boundary scan, which helps test for board assembly problems like solder bridges and missing connections.

OpenOCD must know about the active TAPs on your board(s). Setting up the TAPs is the core task of your configuration files. Once those TAPs are set up, you can pass their names to code which sets up CPUs and exports them as GDB targets, probes flash memory, performs low-level JTAG operations, and more.

### 10.1 Scan Chains ¶

TAPs are part of a hardware scan chain, which is a daisy chain of TAPs. They also need to be added to OpenOCD’s software mirror of that hardware list, giving each member a name and associating other data with it. Simple scan chains, with a single TAP, are common in systems with a single microcontroller or microprocessor. More complex chips may have several TAPs internally. Very complex scan chains might have a dozen or more TAPs: several in one chip, more in the next, and connecting to other boards with their own chips and TAPs.

You can display the list with the `scan_chain` command. (Don’t confuse this with the list displayed by the `targets` command, presented in the next chapter. That only displays TAPs for CPUs which are configured as debugging targets.) Here’s what the scan chain might look like for a chip more than one TAP:

       TapName            Enabled IdCode     Expected   IrLen IrCap IrMask
    -- ------------------ ------- ---------- ---------- ----- ----- ------
     0 omap5912.dsp          Y    0x03df1d81 0x03df1d81    38 0x01  0x03
     1 omap5912.arm          Y    0x0692602f 0x0692602f     4 0x01  0x0f
     2 omap5912.unknown      Y    0x00000000 0x00000000     8 0x01  0x03

OpenOCD can detect some of that information, but not all of it. See Autoprobing. Unfortunately, those TAPs can’t always be autoconfigured, because not all devices provide good support for that. JTAG doesn’t require supporting IDCODE instructions, and chips with JTAG routers may not link TAPs into the chain until they are told to do so.

The configuration mechanism currently supported by OpenOCD requires explicit configuration of all TAP devices using `jtag newtap` commands, as detailed later in this chapter. A command like this would declare one tap and name it `chip1.cpu`:

    jtag newtap chip1 cpu -irlen 4 -expected-id 0x3ba00477

Each target configuration file lists the TAPs provided by a given chip. Board configuration files combine all the targets on a board, and so forth. Note that the order in which TAPs are declared is very important. That declaration order must match the order in the JTAG scan chain, both inside a single chip and between them. See FAQ TAP Order.

For example, the STMicroelectronics STR912 chip has three separate TAPs5. To configure those taps, `target/str912.cfg` includes commands something like this:

    jtag newtap str912 flash ... params ...
    jtag newtap str912 cpu ... params ...
    jtag newtap str912 bs ... params ...

Actual config files typically use a variable such as `$_CHIPNAME` instead of literals like `str912`, to support more than one chip of each type. See Config File Guidelines.

Command: jtag names ¶

  Returns the names of all current TAPs in the scan chain. Use `jtag cget` or `jtag tapisenabled` to examine attributes and state of each TAP.

      foreach t [jtag names] {
          puts [format "TAP: %s\n" $t]
      }

Command: scan_chain ¶

  Displays the TAPs in the scan chain configuration, and their status. The set of TAPs listed by this command is fixed by exiting the OpenOCD configuration stage, but systems with a JTAG router can enable or disable TAPs dynamically.

### 10.2 TAP Names ¶

When TAP objects are declared with `jtag newtap`, a dotted.name is created for the TAP, combining the name of a module (usually a chip) and a label for the TAP. For example: `xilinx.tap`, `str912.flash`, `omap3530.jrc`, `dm6446.dsp`, or `stm32.cpu`. Many other commands use that dotted.name to manipulate or refer to the TAP. For example, CPU configuration uses the name, as does declaration of NAND or NOR flash banks.

The components of a dotted name should follow “C” symbol name rules: start with an alphabetic character, then numbers and underscores are OK; while others (including dots!) are not.

### 10.3 TAP Declaration Commands ¶

Config Command: jtag newtap chipname tapname configparams... ¶

  Declares a new TAP with the dotted name chipname.tapname, and configured according to the various configparams.

  The chipname is a symbolic name for the chip. Conventionally target config files use `$_CHIPNAME`, defaulting to the model name given by the chip vendor but overridable.

  The tapname reflects the role of that TAP, and should follow this convention:

  - `bs` – For boundary scan if this is a separate TAP;
  - `cpu` – The main CPU of the chip, alternatively `arm` and `dsp` on chips with both ARM and DSP CPUs, `arm1` and `arm2` on chips with two ARMs, and so forth;
  - `etb` – For an embedded trace buffer (example: an ARM ETB11);
  - `flash` – If the chip has a flash TAP, like the str912;
  - `jrc` – For JTAG route controller (example: the ICEPick modules on many Texas Instruments chips, like the OMAP3530 on Beagleboards);
  - `tap` – Should be used only for FPGA- or CPLD-like devices with a single TAP;
  - `unknownN` – If you have no idea what the TAP is for (N is a number);
  - when in doubt – Use the chip maker’s name in their data sheet. For example, the Freescale i.MX31 has a SDMA (Smart DMA) with a JTAG TAP; that TAP should be named `sdma`.

  Every TAP requires at least the following configparams:

  - `-irlen` NUMBER
    The length in bits of the instruction register, such as 4 or 5 bits.

  A TAP may also provide optional configparams:

  - `-disable` (or `-enable`)
    Use the `-disable` parameter to flag a TAP which is not linked into the scan chain after a reset using either TRST or the JTAG state machine’s RESET state. You may use `-enable` to highlight the default state (the TAP is linked in). See Enabling and Disabling TAPs.
  - `-expected-id` NUMBER
    A non-zero number represents a 32-bit IDCODE which you expect to find when the scan chain is examined. These codes are not required by all JTAG devices. Repeat the option as many times as required if more than one ID code could appear (for example, multiple versions). Specify number as zero to suppress warnings about IDCODE values that were found but not included in the list.

    Provide this value if at all possible, since it lets OpenOCD tell when the scan chain it sees isn’t right. These values are provided in vendors’ chip documentation, usually a technical reference manual. Sometimes you may need to probe the JTAG hardware to find these values. See Autoprobing.

  - `-ignore-version`
    Specify this to ignore the JTAG version field in the `-expected-id` option. When vendors put out multiple versions of a chip, or use the same JTAG-level ID for several largely-compatible chips, it may be more practical to ignore the version field than to update config files to handle all of the various chip IDs. The version field is defined as bit 28-31 of the IDCODE.
  - `-ignore-bypass`
    Specify this to ignore the ’bypass’ bit of the idcode. Some vendor put an invalid idcode regarding this bit. Specify this to ignore this bit and to not consider this tap in bypass mode.
  - `-ircapture` NUMBER
    The bit pattern loaded by the TAP into the JTAG shift register on entry to the IRCAPTURE state, such as 0x01. JTAG requires the two LSBs of this value to be 01. By default, `-ircapture` and `-irmask` are set up to verify that two-bit value. You may provide additional bits if you know them, or indicate that a TAP doesn’t conform to the JTAG specification.
  - `-irmask` NUMBER
    A mask used with `-ircapture` to verify that instruction scans work correctly. Such scans are not used by OpenOCD except to verify that there seems to be no problems with JTAG scan chain operations.
  - `-ignore-syspwrupack`
    Specify this to ignore the CSYSPWRUPACK bit in the ARM DAP DP CTRL/STAT register during initial examination and when checking the sticky error bit. This bit is normally checked after setting the CSYSPWRUPREQ bit, but some devices do not set the ack bit until sometime later.

### 10.4 Other TAP commands ¶

Command: jtag cget dotted.name `-idcode` ¶

  Get the value of the IDCODE found in hardware.

Command: jtag cget dotted.name `-event` event_name ¶
Command: jtag configure dotted.name `-event` event_name handler ¶

  At this writing this TAP attribute mechanism is limited and used mostly for event handling. (It is not a direct analogue of the `cget`/`configure` mechanism for debugger targets.) See the next section for information about the available events.

  The `configure` subcommand assigns an event handler, a TCL string which is evaluated when the event is triggered. The `cget` subcommand returns that handler.

### 10.5 TAP Events ¶

OpenOCD includes two event mechanisms. The one presented here applies to all JTAG TAPs. The other applies to debugger targets, which are associated with certain TAPs.

The TAP events currently defined are:

- post-reset
  The TAP has just completed a JTAG reset. The tap may still be in the JTAG RESET state. Handlers for these events might perform initialization sequences such as issuing TCK cycles, TMS sequences to ensure exit from the ARM SWD mode, and more.

  Because the scan chain has not yet been verified, handlers for these events should not issue commands which scan the JTAG IR or DR registers of any particular target. NOTE: As this is written (September 2009), nothing prevents such access.

- setup
  The scan chain has been reset and verified. This handler may enable TAPs as needed.
- tap-disable
  The TAP needs to be disabled. This handler should implement `jtag tapdisable` by issuing the relevant JTAG commands.
- tap-enable
  The TAP needs to be enabled. This handler should implement `jtag tapenable` by issuing the relevant JTAG commands.

If you need some action after each JTAG reset which isn’t actually specific to any TAP (since you can’t yet trust the scan chain’s contents to be accurate), you might:

    jtag configure CHIP.jrc -event post-reset {
      echo "JTAG Reset done"
      ... non-scan jtag operations to be done after reset
    }

### 10.6 Enabling and Disabling TAPs ¶

In some systems, a JTAG Route Controller (JRC) is used to enable and/or disable specific JTAG TAPs. Many ARM-based chips from Texas Instruments include an “ICEPick” module, which is a JRC. Such chips include DaVinci and OMAP3 processors.

A given TAP may not be visible until the JRC has been told to link it into the scan chain; and if the JRC has been told to unlink that TAP, it will no longer be visible. Such routers address problems that JTAG “bypass mode” ignores, such as:

- The scan chain can only go as fast as its slowest TAP.
- Having many TAPs slows instruction scans, since all TAPs receive new instructions.
- TAPs in the scan chain must be powered up, which wastes power and prevents debugging some power management mechanisms.

The IEEE 1149.1 JTAG standard has no concept of a “disabled” tap, as implied by the existence of JTAG routers. However, the upcoming IEEE 1149.7 framework (layered on top of JTAG) does include a kind of JTAG router functionality.

In OpenOCD, tap enabling/disabling is invoked by the Tcl commands shown below, and is implemented using TAP event handlers. So for example, when defining a TAP for a CPU connected to a JTAG router, your `target.cfg` file should define TAP event handlers using code that looks something like this:

    jtag configure CHIP.cpu -event tap-enable {
      ... jtag operations using CHIP.jrc
    }
    jtag configure CHIP.cpu -event tap-disable {
      ... jtag operations using CHIP.jrc
    }

Then you might want that CPU’s TAP enabled almost all the time:

    jtag configure $CHIP.jrc -event setup "jtag tapenable $CHIP.cpu"

Note how that particular setup event handler declaration uses quotes to evaluate `$CHIP` when the event is configured. Using brackets { } would cause it to be evaluated later, at runtime, when it might have a different value.

Command: jtag tapdisable dotted.name ¶

  If necessary, disables the tap by sending it a `tap-disable` event. Returns the string "1" if the tap specified by dotted.name is enabled, and "0" if it is disabled.

Command: jtag tapenable dotted.name ¶

  If necessary, enables the tap by sending it a `tap-enable` event. Returns the string "1" if the tap specified by dotted.name is enabled, and "0" if it is disabled.

Command: jtag tapisenabled dotted.name ¶

  Returns the string "1" if the tap specified by dotted.name is enabled, and "0" if it is disabled.

  > Note: Humans will find the `scan_chain` command more helpful for querying the state of the JTAG taps.

### 10.7 Autoprobing ¶

TAP configuration is the first thing that needs to be done after interface and reset configuration. Sometimes it’s hard finding out what TAPs exist, or how they are identified. Vendor documentation is not always easy to find and use.

To help you get past such problems, OpenOCD has a limited autoprobing ability to look at the scan chain, doing a blind interrogation and then reporting the TAPs it finds. To use this mechanism, start the OpenOCD server with only data that configures your JTAG interface, and arranges to come up with a slow clock (many devices don’t support fast JTAG clocks right when they come out of reset).

For example, your `openocd.cfg` file might have:

    source [find interface/olimex-arm-usb-tiny-h.cfg]
    reset_config trst_and_srst
    jtag_rclk 8

When you start the server without any TAPs configured, it will attempt to autoconfigure the TAPs. There are two parts to this:

1. TAP discovery ... After a JTAG reset (sometimes a system reset may be needed too), each TAP’s data registers will hold the contents of either the IDCODE or BYPASS register. If JTAG communication is working, OpenOCD will see each TAP, and report what `-expected-id` to use with it.
2. IR Length discovery ... Unfortunately JTAG does not provide a reliable way to find out the value of the `-irlen` parameter to use with a TAP that is discovered. If OpenOCD can discover the length of a TAP’s instruction register, it will report it. Otherwise you may need to consult vendor documentation, such as chip data sheets or BSDL files.

In many cases your board will have a simple scan chain with just a single device. Here’s what OpenOCD reported with one board that’s a bit more complex:

    clock speed 8 kHz
    There are no enabled taps. AUTO PROBING MIGHT NOT WORK!!
    AUTO auto0.tap - use "jtag newtap auto0 tap -expected-id 0x2b900f0f ..."
    AUTO auto1.tap - use "jtag newtap auto1 tap -expected-id 0x07926001 ..."
    AUTO auto2.tap - use "jtag newtap auto2 tap -expected-id 0x0b73b02f ..."
    AUTO auto0.tap - use "... -irlen 4"
    AUTO auto1.tap - use "... -irlen 4"
    AUTO auto2.tap - use "... -irlen 6"
    no gdb ports allocated as no target has been specified

Given that information, you should be able to either find some existing config files to use, or create your own. If you create your own, you would configure from the bottom up: first a `target.cfg` file with these TAPs, any targets associated with them, and any on-chip resources; then a `board.cfg` with off-chip resources, clocking, and so forth.

### 10.8 DAP declaration (ARMv6-M, ARMv7 and ARMv8 targets) ¶

Since OpenOCD version 0.11.0, the Debug Access Port (DAP) is no longer implicitly created together with the target. It must be explicitly declared using the `dap create` command. For all ARMv6-M, ARMv7 and ARMv8 targets, the option "`-dap` dap_name" has to be used instead of "`-chain-position` dotted.name" when the target is created.

The `dap` command group supports the following sub-commands:

Command: dap create dap_name `-chain-position` dotted.name configparams... ¶

  Declare a DAP instance named dap_name linked to the JTAG tap dotted.name. This also creates a new command (`dap_name`) which is used for various purposes including additional configuration. There can only be one DAP for each JTAG tap in the system.

  A DAP may also provide optional configparams:

  - `-adiv5` Specify that it’s an ADIv5 DAP. This is the default if not specified.
  - `-adiv6` Specify that it’s an ADIv6 DAP.
  - `-ignore-syspwrupack` Specify this to ignore the CSYSPWRUPACK bit in the ARM DAP DP CTRL/STAT register during initial examination and when checking the sticky error bit. This bit is normally checked after setting the CSYSPWRUPREQ bit, but some devices do not set the ack bit until sometime later.
  - `-dp-id` number
    Debug port identification number for SWD DPv2 multidrop. The number is written to bits 0..27 of DP TARGETSEL during DP selection. To find the id number of a single connected device read DP TARGETID: `device.dap dpreg 0x24` Use bits 0..27 of TARGETID.
  - `-instance-id` number
    Instance identification number for SWD DPv2 multidrop. The number is written to bits 28..31 of DP TARGETSEL during DP selection. To find the instance number of a single connected device read DP DLPIDR: `device.dap dpreg 0x34` The instance number is in bits 28..31 of DLPIDR value.

Command: dap names ¶

  This command returns a list of all registered DAP objects. It it useful mainly for TCL scripting.

Command: dap info [num|`root`] ¶

  Displays the ROM table for MEM-AP num, defaulting to the currently selected AP of the currently selected target. On ADIv5 DAP num is the numeric index of the AP. On ADIv6 DAP num is the base address of the AP. With ADIv6 only, `root` specifies the root ROM table.

Command: dap init ¶

  Initialize all registered DAPs. This command is used internally during initialization. It can be issued at any time after the initialization, too.

The following commands exist as subcommands of DAP instances:

Command: $dap_name info [num|`root`] ¶

  Displays the ROM table for MEM-AP num, defaulting to the currently selected AP. On ADIv5 DAP num is the numeric index of the AP. On ADIv6 DAP num is the base address of the AP. With ADIv6 only, `root` specifies the root ROM table.

Command: $dap_name apid [num] ¶

  Displays ID register from AP num, defaulting to the currently selected AP. On ADIv5 DAP num is the numeric index of the AP. On ADIv6 DAP num is the base address of the AP.

Command: $dap_name apreg ap_num reg [value] ¶

  Displays content of a register reg from AP ap_num or set a new value value. On ADIv5 DAP ap_num is the numeric index of the AP. On ADIv6 DAP ap_num is the base address of the AP. reg is byte address of a word register, 0, 4, 8 ... 0xfc.

Command: $dap_name apsel [num] ¶

  Select AP num, defaulting to 0. On ADIv5 DAP num is the numeric index of the AP. On ADIv6 DAP num is the base address of the AP.

Command: $dap_name dpreg reg [value] ¶

  Displays the content of DP register at address reg, or set it to a new value value.

  In case of SWD, reg is a value in packed format dpbanksel << 4 | addr and assumes values 0, 4, 8 ... 0xfc. In case of JTAG it only assumes values 0, 4, 8 and 0xc.

  Note: Consider using `poll off` to avoid any disturbing background activity by OpenOCD while you are operating at such low-level.

Command: $dap_name baseaddr [num] ¶

  Displays debug base address from MEM-AP num, defaulting to the currently selected AP. On ADIv5 DAP num is the numeric index of the AP. On ADIv6 DAP num is the base address of the AP.

Command: $dap_name memaccess [value] ¶

  Displays the number of extra tck cycles in the JTAG idle to use for MEM-AP memory bus access [0-255], giving additional time to respond to reads. If value is defined, first assigns that.

Command: $dap_name apcsw [value [mask]] ¶

  Displays or changes CSW bit pattern for MEM-AP transfers.

  At the begin of each memory access the CSW pattern is extended (bitwise or-ed) by Size and AddrInc bit-fields according to transfer requirements and the result is written to the real CSW register. All bits except dynamically updated fields Size and AddrInc can be changed by changing the CSW pattern. Refer to ARM ADI v5 manual chapter 7.6.4 and appendix A for details.

  Use value only syntax if you want to set the new CSW pattern as a whole. The example sets HPROT1 bit (required by Cortex-M) and clears the rest of the pattern:

      kx.dap apcsw 0x2000000

  If mask is also used, the CSW pattern is changed only on bit positions where the mask bit is 1. The following example sets HPROT3 (cacheable) and leaves the rest of the pattern intact. It configures memory access through DCache on Cortex-M7.

      set CSW_HPROT3_CACHEABLE [expr {1 << 27}]
      samv.dap apcsw $CSW_HPROT3_CACHEABLE $CSW_HPROT3_CACHEABLE

  Another example clears SPROT bit and leaves the rest of pattern intact:

      set CSW_SPROT [expr {1 << 30}]
      samv.dap apcsw 0 $CSW_SPROT

  Note: If you want to check the real value of CSW, not CSW pattern, use `xxx.dap apreg 0`. See DAP subcommand apreg.

  Warning: Some of the CSW bits are vital for working memory transfer. If you set a wrong CSW pattern and MEM-AP stopped working, use the following example with a proper dap name:

      xxx.dap apcsw default

Config Command: $dap_name ti_be_32_quirks [`enable`] ¶

  Set/get quirks mode for TI TMS450/TMS570 processors Disabled by default

Config Command: $dap_name nu_npcx_quirks [`enable`] ¶

  Set/get quirks mode for Nuvoton NPCX/NPCD MCU families Disabled by default

#### Footnotes

##### (5)

See the ST document titled: STR91xFAxxx, Section 3.15 Jtag Interface, Page: 28/102, Figure 3: JTAG chaining inside the STR91xFA. http://eu.st.com/stonline/products/literature/ds/13495.pdf