ARMv7: help/usage updates
[openocd.git] / src / target / arm_adi_v5.c
index 57f6603b84cb7d5d230891f5e75906d49406cec0..e490f2e546b8b3c809da91f2db8937a450707d6f 100644 (file)
@@ -7,7 +7,7 @@
  *                                                                         *
  *   Copyright (C) 2009 by Oyvind Harboe                                   *
  *   oyvind.harboe@zylin.com                                               *
- *                                                                                                                                                *
+ *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
-/***************************************************************************
- *                                                                         *
- * This file implements support for the ARM Debug Interface v5  (ADI_V5)   *
- *                                                                         *
- * ARM(tm) Debug Interface v5 Architecture Specification    ARM IHI 0031A  *
- *                                                                         *
- * CoreSight(tm) DAP-Lite TRM, ARM DDI 0316A                               *
- * Cortex-M3(tm) TRM, ARM DDI 0337C                                        *
- *                                                                         *
-***************************************************************************/
+
+/**
+ * @file
+ * This file implements support for the ARM Debug Interface version 5 (ADIv5)
+ * debugging architecture.  Compared with previous versions, this includes
+ * a low pin-count Serial Wire Debug (SWD) alternative to JTAG for message
+ * transport, and focusses on memory mapped resources as defined by the
+ * CoreSight architecture.
+ *
+ * A key concept in ADIv5 is the Debug Access Port, or DAP.  A DAP has two
+ * basic components:  a Debug Port (DP) transporting messages to and from a
+ * debugger, and an Access Port (AP) accessing resources.  Three types of DP
+ * are defined.  One uses only JTAG for communication, and is called JTAG-DP.
+ * One uses only SWD for communication, and is called SW-DP.  The third can
+ * use either SWD or JTAG, and is called SWJ-DP.  The most common type of AP
+ * is used to access memory mapped resources and is called a MEM-AP.  Also a
+ * JTAG-AP is also defined, bridging to JTAG resources; those are uncommon.
+ */
+
+/*
+ * Relevant specifications from ARM include:
+ *
+ * ARM(tm) Debug Interface v5 Architecture Specification    ARM IHI 0031A
+ * CoreSight(tm) v1.0 Architecture Specification            ARM IHI 0029B
+ *
+ * CoreSight(tm) DAP-Lite TRM, ARM DDI 0316D
+ * Cortex-M3(tm) TRM, ARM DDI 0337G
+ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include "arm_adi_v5.h"
-#include "time_support.h"
+#include <helper/time_support.h>
 
 /*
  * Transaction Mode:
@@ -71,17 +89,26 @@ static uint32_t max_tar_block_size(uint32_t tar_autoincr_block, uint32_t address
 ***************************************************************************/
 
 /* Scan out and in from target ordered uint8_t buffers */
-int adi_jtag_dp_scan(swjdp_common_t *swjdp, uint8_t instr, uint8_t reg_addr, uint8_t RnW, uint8_t *outvalue, uint8_t *invalue, uint8_t *ack)
+static int adi_jtag_dp_scan(struct swjdp_common *swjdp,
+               uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+               uint8_t *outvalue, uint8_t *invalue, uint8_t *ack)
 {
-       arm_jtag_t *jtag_info = swjdp->jtag_info;
-       scan_field_t fields[2];
+       struct arm_jtag *jtag_info = swjdp->jtag_info;
+       struct scan_field fields[2];
        uint8_t out_addr_buf;
 
        jtag_set_end_state(TAP_IDLE);
        arm_jtag_set_instr(jtag_info, instr, NULL);
 
        /* Add specified number of tck clocks before accessing memory bus */
-       if ((instr == DAP_IR_APACC) && ((reg_addr == AP_REG_DRW)||((reg_addr&0xF0) == AP_REG_BD0) )&& (swjdp->memaccess_tck != 0))
+
+       /* REVISIT these TCK cycles should be *AFTER*  updating APACC, since
+        * they provide more time for the (MEM) AP to complete the read ...
+        */
+       if ((instr == JTAG_DP_APACC)
+                       && ((reg_addr == AP_REG_DRW)
+                               || ((reg_addr & 0xF0) == AP_REG_BD0))
+                       && (swjdp->memaccess_tck != 0))
                jtag_add_runtest(swjdp->memaccess_tck, jtag_set_end_state(TAP_IDLE));
 
        fields[0].tap = jtag_info->tap;
@@ -101,10 +128,12 @@ int adi_jtag_dp_scan(swjdp_common_t *swjdp, uint8_t instr, uint8_t reg_addr, uin
 }
 
 /* Scan out and in from host ordered uint32_t variables */
-int adi_jtag_dp_scan_u32(swjdp_common_t *swjdp, uint8_t instr, uint8_t reg_addr, uint8_t RnW, uint32_t outvalue, uint32_t *invalue, uint8_t *ack)
+static int adi_jtag_dp_scan_u32(struct swjdp_common *swjdp,
+               uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+               uint32_t outvalue, uint32_t *invalue, uint8_t *ack)
 {
-       arm_jtag_t *jtag_info = swjdp->jtag_info;
-       scan_field_t fields[2];
+       struct arm_jtag *jtag_info = swjdp->jtag_info;
+       struct scan_field fields[2];
        uint8_t out_value_buf[4];
        uint8_t out_addr_buf;
 
@@ -112,7 +141,14 @@ int adi_jtag_dp_scan_u32(swjdp_common_t *swjdp, uint8_t instr, uint8_t reg_addr,
        arm_jtag_set_instr(jtag_info, instr, NULL);
 
        /* Add specified number of tck clocks before accessing memory bus */
-       if ((instr == DAP_IR_APACC) && ((reg_addr == AP_REG_DRW)||((reg_addr&0xF0) == AP_REG_BD0) )&& (swjdp->memaccess_tck != 0))
+
+       /* REVISIT these TCK cycles should be *AFTER*  updating APACC, since
+        * they provide more time for the (MEM) AP to complete the read ...
+        */
+       if ((instr == JTAG_DP_APACC)
+                       && ((reg_addr == AP_REG_DRW)
+                               || ((reg_addr & 0xF0) == AP_REG_BD0))
+                       && (swjdp->memaccess_tck != 0))
                jtag_add_runtest(swjdp->memaccess_tck, jtag_set_end_state(TAP_IDLE));
 
        fields[0].tap = jtag_info->tap;
@@ -143,43 +179,51 @@ int adi_jtag_dp_scan_u32(swjdp_common_t *swjdp, uint8_t instr, uint8_t reg_addr,
 }
 
 /* scan_inout_check adds one extra inscan for DPAP_READ commands to read variables */
-int scan_inout_check(swjdp_common_t *swjdp, uint8_t instr, uint8_t reg_addr, uint8_t RnW, uint8_t *outvalue, uint8_t *invalue)
+static int scan_inout_check(struct swjdp_common *swjdp,
+               uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+               uint8_t *outvalue, uint8_t *invalue)
 {
        adi_jtag_dp_scan(swjdp, instr, reg_addr, RnW, outvalue, NULL, NULL);
 
        if ((RnW == DPAP_READ) && (invalue != NULL))
-       {
-               adi_jtag_dp_scan(swjdp, DAP_IR_DPACC, DP_RDBUFF, DPAP_READ, 0, invalue, &swjdp->ack);
-       }
-
-       /* In TRANS_MODE_ATOMIC all DAP_IR_APACC transactions wait for ack = OK/FAULT and the check CTRL_STAT */
-       if ((instr == DAP_IR_APACC) && (swjdp->trans_mode == TRANS_MODE_ATOMIC))
-       {
+               adi_jtag_dp_scan(swjdp, JTAG_DP_DPACC,
+                               DP_RDBUFF, DPAP_READ, 0, invalue, &swjdp->ack);
+
+       /* In TRANS_MODE_ATOMIC all JTAG_DP_APACC transactions wait for
+        * ack = OK/FAULT and the check CTRL_STAT
+        */
+       if ((instr == JTAG_DP_APACC)
+                       && (swjdp->trans_mode == TRANS_MODE_ATOMIC))
                return swjdp_transaction_endcheck(swjdp);
-       }
 
        return ERROR_OK;
 }
 
-int scan_inout_check_u32(swjdp_common_t *swjdp, uint8_t instr, uint8_t reg_addr, uint8_t RnW, uint32_t outvalue, uint32_t *invalue)
+static int scan_inout_check_u32(struct swjdp_common *swjdp,
+               uint8_t instr, uint8_t reg_addr, uint8_t RnW,
+               uint32_t outvalue, uint32_t *invalue)
 {
+       /* Issue the read or write */
        adi_jtag_dp_scan_u32(swjdp, instr, reg_addr, RnW, outvalue, NULL, NULL);
 
+       /* For reads,  collect posted value; RDBUFF has no other effect.
+        * Assumes read gets acked with OK/FAULT, and CTRL_STAT says "OK".
+        */
        if ((RnW == DPAP_READ) && (invalue != NULL))
-       {
-               adi_jtag_dp_scan_u32(swjdp, DAP_IR_DPACC, DP_RDBUFF, DPAP_READ, 0, invalue, &swjdp->ack);
-       }
-
-       /* In TRANS_MODE_ATOMIC all DAP_IR_APACC transactions wait for ack = OK/FAULT and then check CTRL_STAT */
-       if ((instr == DAP_IR_APACC) && (swjdp->trans_mode == TRANS_MODE_ATOMIC))
-       {
+               adi_jtag_dp_scan_u32(swjdp, JTAG_DP_DPACC,
+                               DP_RDBUFF, DPAP_READ, 0, invalue, &swjdp->ack);
+
+       /* In TRANS_MODE_ATOMIC all JTAG_DP_APACC transactions wait for
+        * ack = OK/FAULT and then check CTRL_STAT
+        */
+       if ((instr == JTAG_DP_APACC)
+                       && (swjdp->trans_mode == TRANS_MODE_ATOMIC))
                return swjdp_transaction_endcheck(swjdp);
-       }
 
        return ERROR_OK;
 }
 
-int swjdp_transaction_endcheck(swjdp_common_t *swjdp)
+int swjdp_transaction_endcheck(struct swjdp_common *swjdp)
 {
        int retval;
        uint32_t ctrlstat;
@@ -188,7 +232,8 @@ int swjdp_transaction_endcheck(swjdp_common_t *swjdp)
 
 #if 0
        /* Danger!!!! BROKEN!!!! */
-       scan_inout_check_u32(swjdp, DAP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+       scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                       DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
        /* Danger!!!! BROKEN!!!! Why will jtag_execute_queue() fail here????
        R956 introduced the check on return value here and now Michael Schwingen reports
        that this code no longer works....
@@ -202,39 +247,49 @@ int swjdp_transaction_endcheck(swjdp_common_t *swjdp)
        /* Why??? second time it works??? */
 #endif
 
-       scan_inout_check_u32(swjdp, DAP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+       /* Post CTRL/STAT read; discard any previous posted read value
+        * but collect its ACK status.
+        */
+       scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                       DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
        if ((retval = jtag_execute_queue()) != ERROR_OK)
                return retval;
 
        swjdp->ack = swjdp->ack & 0x7;
 
-       if (swjdp->ack != 2)
+       /* common code path avoids calling timeval_ms() */
+       if (swjdp->ack != JTAG_ACK_OK_FAULT)
        {
                long long then = timeval_ms();
-               while (swjdp->ack != 2)
+
+               while (swjdp->ack != JTAG_ACK_OK_FAULT)
                {
-                       if (swjdp->ack == 1)
+                       if (swjdp->ack == JTAG_ACK_WAIT)
                        {
                                if ((timeval_ms()-then) > 1000)
                                {
-                                       LOG_WARNING("Timeout (1000ms) waiting for ACK = OK/FAULT in SWJDP transaction");
+                                       /* NOTE:  this would be a good spot
+                                        * to use JTAG_DP_ABORT.
+                                        */
+                                       LOG_WARNING("Timeout (1000ms) waiting "
+                                               "for ACK=OK/FAULT "
+                                               "in JTAG-DP transaction");
                                        return ERROR_JTAG_DEVICE_ERROR;
                                }
                        }
                        else
                        {
-                               LOG_WARNING("Invalid ACK in SWJDP transaction");
+                               LOG_WARNING("Invalid ACK "
+                                               "in JTAG-DP transaction");
                                return ERROR_JTAG_DEVICE_ERROR;
                        }
 
-                       scan_inout_check_u32(swjdp, DAP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+                       scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                                       DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
                        if ((retval = jtag_execute_queue()) != ERROR_OK)
                                return retval;
                        swjdp->ack = swjdp->ack & 0x7;
                }
-       } else
-       {
-               /* common code path avoids fn to timeval_ms() */
        }
 
        /* Check for STICKYERR and STICKYORUN */
@@ -253,14 +308,19 @@ int swjdp_transaction_endcheck(swjdp_common_t *swjdp)
                        /* Print information about last AHBAP access */
                        LOG_ERROR("AHBAP Cached values: dp_select 0x%" PRIx32 ", ap_csw 0x%" PRIx32 ", ap_tar 0x%" PRIx32 "", swjdp->dp_select_value, swjdp->ap_csw_value, swjdp->ap_tar_value);
                        if (ctrlstat & SSTICKYORUN)
-                               LOG_ERROR("SWJ-DP OVERRUN - check clock or reduce jtag speed");
+                               LOG_ERROR("JTAG-DP OVERRUN - "
+                                       "check clock or reduce jtag speed");
 
                        if (ctrlstat & SSTICKYERR)
-                               LOG_ERROR("SWJ-DP STICKY ERROR");
+                               LOG_ERROR("JTAG-DP STICKY ERROR");
 
                        /* Clear Sticky Error Bits */
-                       scan_inout_check_u32(swjdp, DAP_IR_DPACC, DP_CTRL_STAT, DPAP_WRITE, swjdp->dp_ctrl_stat | SSTICKYORUN | SSTICKYERR, NULL);
-                       scan_inout_check_u32(swjdp, DAP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
+                       scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                                       DP_CTRL_STAT, DPAP_WRITE,
+                                       swjdp->dp_ctrl_stat | SSTICKYORUN
+                                               | SSTICKYERR, NULL);
+                       scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                                       DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
                        if ((retval = jtag_execute_queue()) != ERROR_OK)
                                return retval;
 
@@ -287,17 +347,21 @@ int swjdp_transaction_endcheck(swjdp_common_t *swjdp)
  *                                                                         *
 ***************************************************************************/
 
-int dap_dp_write_reg(swjdp_common_t *swjdp, uint32_t value, uint8_t reg_addr)
+static int dap_dp_write_reg(struct swjdp_common *swjdp,
+               uint32_t value, uint8_t reg_addr)
 {
-       return scan_inout_check_u32(swjdp, DAP_IR_DPACC, reg_addr, DPAP_WRITE, value, NULL);
+       return scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                       reg_addr, DPAP_WRITE, value, NULL);
 }
 
-int dap_dp_read_reg(swjdp_common_t *swjdp, uint32_t *value, uint8_t reg_addr)
+static int dap_dp_read_reg(struct swjdp_common *swjdp,
+               uint32_t *value, uint8_t reg_addr)
 {
-       return scan_inout_check_u32(swjdp, DAP_IR_DPACC, reg_addr, DPAP_READ, 0, value);
+       return scan_inout_check_u32(swjdp, JTAG_DP_DPACC,
+                       reg_addr, DPAP_READ, 0, value);
 }
 
-int dap_ap_select(swjdp_common_t *swjdp,uint8_t apsel)
+int dap_ap_select(struct swjdp_common *swjdp,uint8_t apsel)
 {
        uint32_t select;
        select = (apsel << 24) & 0xFF000000;
@@ -314,7 +378,7 @@ int dap_ap_select(swjdp_common_t *swjdp,uint8_t apsel)
        return ERROR_OK;
 }
 
-int dap_dp_bankselect(swjdp_common_t *swjdp,uint32_t ap_reg)
+static int dap_dp_bankselect(struct swjdp_common *swjdp, uint32_t ap_reg)
 {
        uint32_t select;
        select = (ap_reg & 0x000000F0);
@@ -328,36 +392,33 @@ int dap_dp_bankselect(swjdp_common_t *swjdp,uint32_t ap_reg)
        return ERROR_OK;
 }
 
-int dap_ap_write_reg(swjdp_common_t *swjdp, uint32_t reg_addr, uint8_t* out_value_buf)
+static int dap_ap_write_reg(struct swjdp_common *swjdp,
+               uint32_t reg_addr, uint8_t *out_value_buf)
 {
        dap_dp_bankselect(swjdp, reg_addr);
-       scan_inout_check(swjdp, DAP_IR_APACC, reg_addr, DPAP_WRITE, out_value_buf, NULL);
+       scan_inout_check(swjdp, JTAG_DP_APACC, reg_addr,
+                       DPAP_WRITE, out_value_buf, NULL);
 
        return ERROR_OK;
 }
 
-int dap_ap_read_reg(swjdp_common_t *swjdp, uint32_t reg_addr, uint8_t *in_value_buf)
-{
-       dap_dp_bankselect(swjdp, reg_addr);
-       scan_inout_check(swjdp, DAP_IR_APACC, reg_addr, DPAP_READ, 0, in_value_buf);
-
-       return ERROR_OK;
-}
-int dap_ap_write_reg_u32(swjdp_common_t *swjdp, uint32_t reg_addr, uint32_t value)
+int dap_ap_write_reg_u32(struct swjdp_common *swjdp, uint32_t reg_addr, uint32_t value)
 {
        uint8_t out_value_buf[4];
 
        buf_set_u32(out_value_buf, 0, 32, value);
        dap_dp_bankselect(swjdp, reg_addr);
-       scan_inout_check(swjdp, DAP_IR_APACC, reg_addr, DPAP_WRITE, out_value_buf, NULL);
+       scan_inout_check(swjdp, JTAG_DP_APACC, reg_addr,
+                       DPAP_WRITE, out_value_buf, NULL);
 
        return ERROR_OK;
 }
 
-int dap_ap_read_reg_u32(swjdp_common_t *swjdp, uint32_t reg_addr, uint32_t *value)
+int dap_ap_read_reg_u32(struct swjdp_common *swjdp, uint32_t reg_addr, uint32_t *value)
 {
        dap_dp_bankselect(swjdp, reg_addr);
-       scan_inout_check_u32(swjdp, DAP_IR_APACC, reg_addr, DPAP_READ, 0, value);
+       scan_inout_check_u32(swjdp, JTAG_DP_APACC, reg_addr,
+                       DPAP_READ, 0, value);
 
        return ERROR_OK;
 }
@@ -368,19 +429,19 @@ int dap_ap_read_reg_u32(swjdp_common_t *swjdp, uint32_t reg_addr, uint32_t *valu
  *                                                                         *
 ***************************************************************************/
 
-int dap_setup_accessport(swjdp_common_t *swjdp, uint32_t csw, uint32_t tar)
+int dap_setup_accessport(struct swjdp_common *swjdp, uint32_t csw, uint32_t tar)
 {
        csw = csw | CSW_DBGSWENABLE | CSW_MASTER_DEBUG | CSW_HPROT;
        if (csw != swjdp->ap_csw_value)
        {
                /* LOG_DEBUG("swjdp : Set CSW %x",csw); */
-               dap_ap_write_reg_u32(swjdp, AP_REG_CSW, csw );
+               dap_ap_write_reg_u32(swjdp, AP_REG_CSW, csw);
                swjdp->ap_csw_value = csw;
        }
        if (tar != swjdp->ap_tar_value)
        {
                /* LOG_DEBUG("swjdp : Set TAR %x",tar); */
-               dap_ap_write_reg_u32(swjdp, AP_REG_TAR, tar );
+               dap_ap_write_reg_u32(swjdp, AP_REG_TAR, tar);
                swjdp->ap_tar_value = tar;
        }
        if (csw & CSW_ADDRINC_MASK)
@@ -393,23 +454,23 @@ int dap_setup_accessport(swjdp_common_t *swjdp, uint32_t csw, uint32_t tar)
 
 /*****************************************************************************
 *                                                                            *
-* mem_ap_read_u32(swjdp_common_t *swjdp, uint32_t address, uint32_t *value)      *
+* mem_ap_read_u32(struct swjdp_common *swjdp, uint32_t address, uint32_t *value)      *
 *                                                                            *
 * Read a uint32_t value from memory or system register                            *
 * Functionally equivalent to target_read_u32(target, address, uint32_t *value),   *
 * but with less overhead                                                     *
 *****************************************************************************/
-int mem_ap_read_u32(swjdp_common_t *swjdp, uint32_t address, uint32_t *value)
+int mem_ap_read_u32(struct swjdp_common *swjdp, uint32_t address, uint32_t *value)
 {
        swjdp->trans_mode = TRANS_MODE_COMPOSITE;
 
        dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, address & 0xFFFFFFF0);
-       dap_ap_read_reg_u32(swjdp, AP_REG_BD0 | (address & 0xC), value );
+       dap_ap_read_reg_u32(swjdp, AP_REG_BD0 | (address & 0xC), value);
 
        return ERROR_OK;
 }
 
-int mem_ap_read_atomic_u32(swjdp_common_t *swjdp, uint32_t address, uint32_t *value)
+int mem_ap_read_atomic_u32(struct swjdp_common *swjdp, uint32_t address, uint32_t *value)
 {
        mem_ap_read_u32(swjdp, address, value);
 
@@ -418,22 +479,22 @@ int mem_ap_read_atomic_u32(swjdp_common_t *swjdp, uint32_t address, uint32_t *va
 
 /*****************************************************************************
 *                                                                            *
-* mem_ap_write_u32(swjdp_common_t *swjdp, uint32_t address, uint32_t value)      *
+* mem_ap_write_u32(struct swjdp_common *swjdp, uint32_t address, uint32_t value)      *
 *                                                                            *
 * Write a uint32_t value to memory or memory mapped register                              *
 *                                                                            *
 *****************************************************************************/
-int mem_ap_write_u32(swjdp_common_t *swjdp, uint32_t address, uint32_t value)
+int mem_ap_write_u32(struct swjdp_common *swjdp, uint32_t address, uint32_t value)
 {
        swjdp->trans_mode = TRANS_MODE_COMPOSITE;
 
        dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, address & 0xFFFFFFF0);
-       dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (address & 0xC), value );
+       dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (address & 0xC), value);
 
        return ERROR_OK;
 }
 
-int mem_ap_write_atomic_u32(swjdp_common_t *swjdp, uint32_t address, uint32_t value)
+int mem_ap_write_atomic_u32(struct swjdp_common *swjdp, uint32_t address, uint32_t value)
 {
        mem_ap_write_u32(swjdp, address, value);
 
@@ -442,12 +503,12 @@ int mem_ap_write_atomic_u32(swjdp_common_t *swjdp, uint32_t address, uint32_t va
 
 /*****************************************************************************
 *                                                                            *
-* mem_ap_write_buf(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint32_t address) *
+* mem_ap_write_buf(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address) *
 *                                                                            *
 * Write a buffer in target order (little endian)                             *
 *                                                                            *
 *****************************************************************************/
-int mem_ap_write_buf_u32(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint32_t address)
+int mem_ap_write_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address)
 {
        int wcount, blocksize, writecount, errorcount = 0, retval = ERROR_OK;
        uint32_t adr = address;
@@ -467,7 +528,7 @@ int mem_ap_write_buf_u32(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint
                        uint32_t outvalue;
                        memcpy(&outvalue, pBuffer, sizeof(uint32_t));
 
-                       for (i = 0; i < 4; i++ )
+                       for (i = 0; i < 4; i++)
                        {
                                *((uint8_t*)pBuffer + (adr & 0x3)) = outvalue;
                                outvalue >>= 8;
@@ -492,7 +553,7 @@ int mem_ap_write_buf_u32(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint
 
                for (writecount = 0; writecount < blocksize; writecount++)
                {
-                       dap_ap_write_reg(swjdp, AP_REG_DRW, buffer + 4 * writecount );
+                       dap_ap_write_reg(swjdp, AP_REG_DRW, buffer + 4 * writecount);
                }
 
                if (swjdp_transaction_endcheck(swjdp) == ERROR_OK)
@@ -516,7 +577,8 @@ int mem_ap_write_buf_u32(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint
        return retval;
 }
 
-int mem_ap_write_buf_packed_u16(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint32_t address)
+static int mem_ap_write_buf_packed_u16(struct swjdp_common *swjdp,
+               uint8_t *buffer, int count, uint32_t address)
 {
        int retval = ERROR_OK;
        int wcount, blocksize, writecount, i;
@@ -546,7 +608,7 @@ int mem_ap_write_buf_packed_u16(swjdp_common_t *swjdp, uint8_t *buffer, int coun
                {
                        nbytes = MIN((writecount << 1), 4);
 
-                       if (nbytes < 4 )
+                       if (nbytes < 4)
                        {
                                if (mem_ap_write_buf_u16(swjdp, buffer, nbytes, address) != ERROR_OK)
                                {
@@ -561,7 +623,7 @@ int mem_ap_write_buf_packed_u16(swjdp_common_t *swjdp, uint8_t *buffer, int coun
                                uint32_t outvalue;
                                memcpy(&outvalue, buffer, sizeof(uint32_t));
 
-                               for (i = 0; i < nbytes; i++ )
+                               for (i = 0; i < nbytes; i++)
                                {
                                        *((uint8_t*)buffer + (address & 0x3)) = outvalue;
                                        outvalue >>= 8;
@@ -587,7 +649,7 @@ int mem_ap_write_buf_packed_u16(swjdp_common_t *swjdp, uint8_t *buffer, int coun
        return retval;
 }
 
-int mem_ap_write_buf_u16(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint32_t address)
+int mem_ap_write_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address)
 {
        int retval = ERROR_OK;
 
@@ -602,7 +664,7 @@ int mem_ap_write_buf_u16(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint
                uint16_t svalue;
                memcpy(&svalue, buffer, sizeof(uint16_t));
                uint32_t outvalue = (uint32_t)svalue << 8 * (address & 0x3);
-               dap_ap_write_reg_u32(swjdp, AP_REG_DRW, outvalue );
+               dap_ap_write_reg_u32(swjdp, AP_REG_DRW, outvalue);
                retval = swjdp_transaction_endcheck(swjdp);
                count -= 2;
                address += 2;
@@ -612,7 +674,8 @@ int mem_ap_write_buf_u16(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint
        return retval;
 }
 
-int mem_ap_write_buf_packed_u8(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint32_t address)
+static int mem_ap_write_buf_packed_u8(struct swjdp_common *swjdp,
+               uint8_t *buffer, int count, uint32_t address)
 {
        int retval = ERROR_OK;
        int wcount, blocksize, writecount, i;
@@ -638,7 +701,7 @@ int mem_ap_write_buf_packed_u8(swjdp_common_t *swjdp, uint8_t *buffer, int count
                {
                        nbytes = MIN(writecount, 4);
 
-                       if (nbytes < 4 )
+                       if (nbytes < 4)
                        {
                                if (mem_ap_write_buf_u8(swjdp, buffer, nbytes, address) != ERROR_OK)
                                {
@@ -653,7 +716,7 @@ int mem_ap_write_buf_packed_u8(swjdp_common_t *swjdp, uint8_t *buffer, int count
                                uint32_t outvalue;
                                memcpy(&outvalue, buffer, sizeof(uint32_t));
 
-                               for (i = 0; i < nbytes; i++ )
+                               for (i = 0; i < nbytes; i++)
                                {
                                        *((uint8_t*)buffer + (address & 0x3)) = outvalue;
                                        outvalue >>= 8;
@@ -679,7 +742,7 @@ int mem_ap_write_buf_packed_u8(swjdp_common_t *swjdp, uint8_t *buffer, int count
        return retval;
 }
 
-int mem_ap_write_buf_u8(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint32_t address)
+int mem_ap_write_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address)
 {
        int retval = ERROR_OK;
 
@@ -692,7 +755,7 @@ int mem_ap_write_buf_u8(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint3
        {
                dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address);
                uint32_t outvalue = (uint32_t)*buffer << 8 * (address & 0x3);
-               dap_ap_write_reg_u32(swjdp, AP_REG_DRW, outvalue );
+               dap_ap_write_reg_u32(swjdp, AP_REG_DRW, outvalue);
                retval = swjdp_transaction_endcheck(swjdp);
                count--;
                address++;
@@ -704,12 +767,12 @@ int mem_ap_write_buf_u8(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint3
 
 /*********************************************************************************
 *                                                                                *
-* mem_ap_read_buf_u32(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint32_t address)  *
+* mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address)  *
 *                                                                                *
 * Read block fast in target order (little endian) into a buffer                  *
 *                                                                                *
 **********************************************************************************/
-int mem_ap_read_buf_u32(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint32_t address)
+int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address)
 {
        int wcount, blocksize, readcount, errorcount = 0, retval = ERROR_OK;
        uint32_t adr = address;
@@ -734,15 +797,25 @@ int mem_ap_read_buf_u32(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint3
                dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_SINGLE, address);
 
                /* Scan out first read */
-               adi_jtag_dp_scan(swjdp, DAP_IR_APACC, AP_REG_DRW, DPAP_READ, 0, NULL, NULL);
+               adi_jtag_dp_scan(swjdp, JTAG_DP_APACC, AP_REG_DRW,
+                               DPAP_READ, 0, NULL, NULL);
                for (readcount = 0; readcount < blocksize - 1; readcount++)
                {
-                       /* Scan out read instruction and scan in previous value */
-                       adi_jtag_dp_scan(swjdp, DAP_IR_APACC, AP_REG_DRW, DPAP_READ, 0, buffer + 4 * readcount, &swjdp->ack);
+                       /* Scan out next read; scan in posted value for the
+                        * previous one.  Assumes read is acked "OK/FAULT",
+                        * and CTRL_STAT says that meant "OK".
+                        */
+                       adi_jtag_dp_scan(swjdp, JTAG_DP_APACC, AP_REG_DRW,
+                                       DPAP_READ, 0, buffer + 4 * readcount,
+                                       &swjdp->ack);
                }
 
-               /* Scan in last value */
-               adi_jtag_dp_scan(swjdp, DAP_IR_DPACC, DP_RDBUFF, DPAP_READ, 0, buffer + 4 * readcount, &swjdp->ack);
+               /* Scan in last posted value; RDBUFF has no other effect,
+                * assuming ack is OK/FAULT and CTRL_STAT says "OK".
+                */
+               adi_jtag_dp_scan(swjdp, JTAG_DP_DPACC, DP_RDBUFF,
+                               DPAP_READ, 0, buffer + 4 * readcount,
+                               &swjdp->ack);
                if (swjdp_transaction_endcheck(swjdp) == ERROR_OK)
                {
                        wcount = wcount - blocksize;
@@ -770,7 +843,7 @@ int mem_ap_read_buf_u32(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint3
                        uint32_t data;
                        memcpy(&data, pBuffer, sizeof(uint32_t));
 
-                       for (i = 0; i < 4; i++ )
+                       for (i = 0; i < 4; i++)
                        {
                                *((uint8_t*)pBuffer) = (data >> 8 * (adr & 0x3));
                                pBuffer++;
@@ -782,7 +855,8 @@ int mem_ap_read_buf_u32(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint3
        return retval;
 }
 
-int mem_ap_read_buf_packed_u16(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint32_t address)
+static int mem_ap_read_buf_packed_u16(struct swjdp_common *swjdp,
+               uint8_t *buffer, int count, uint32_t address)
 {
        uint32_t invalue;
        int retval = ERROR_OK;
@@ -810,7 +884,7 @@ int mem_ap_read_buf_packed_u16(swjdp_common_t *swjdp, uint8_t *buffer, int count
 
                do
                {
-                       dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue );
+                       dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue);
                        if (swjdp_transaction_endcheck(swjdp) != ERROR_OK)
                        {
                                LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count);
@@ -819,7 +893,7 @@ int mem_ap_read_buf_packed_u16(swjdp_common_t *swjdp, uint8_t *buffer, int count
 
                        nbytes = MIN((readcount << 1), 4);
 
-                       for (i = 0; i < nbytes; i++ )
+                       for (i = 0; i < nbytes; i++)
                        {
                                *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
                                buffer++;
@@ -834,7 +908,7 @@ int mem_ap_read_buf_packed_u16(swjdp_common_t *swjdp, uint8_t *buffer, int count
        return retval;
 }
 
-int mem_ap_read_buf_u16(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint32_t address)
+int mem_ap_read_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address)
 {
        uint32_t invalue, i;
        int retval = ERROR_OK;
@@ -847,11 +921,11 @@ int mem_ap_read_buf_u16(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint3
        while (count > 0)
        {
                dap_setup_accessport(swjdp, CSW_16BIT | CSW_ADDRINC_SINGLE, address);
-               dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue );
+               dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue);
                retval = swjdp_transaction_endcheck(swjdp);
                if (address & 0x1)
                {
-                       for (i = 0; i < 2; i++ )
+                       for (i = 0; i < 2; i++)
                        {
                                *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
                                buffer++;
@@ -877,7 +951,8 @@ int mem_ap_read_buf_u16(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint3
  * The solution is to arrange for a large out/in scan in this loop and
  * and convert data afterwards.
  */
-int mem_ap_read_buf_packed_u8(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint32_t address)
+static int mem_ap_read_buf_packed_u8(struct swjdp_common *swjdp,
+               uint8_t *buffer, int count, uint32_t address)
 {
        uint32_t invalue;
        int retval = ERROR_OK;
@@ -902,7 +977,7 @@ int mem_ap_read_buf_packed_u8(swjdp_common_t *swjdp, uint8_t *buffer, int count,
 
                do
                {
-                       dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue );
+                       dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue);
                        if (swjdp_transaction_endcheck(swjdp) != ERROR_OK)
                        {
                                LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count);
@@ -911,7 +986,7 @@ int mem_ap_read_buf_packed_u8(swjdp_common_t *swjdp, uint8_t *buffer, int count,
 
                        nbytes = MIN(readcount, 4);
 
-                       for (i = 0; i < nbytes; i++ )
+                       for (i = 0; i < nbytes; i++)
                        {
                                *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
                                buffer++;
@@ -926,7 +1001,7 @@ int mem_ap_read_buf_packed_u8(swjdp_common_t *swjdp, uint8_t *buffer, int count,
        return retval;
 }
 
-int mem_ap_read_buf_u8(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint32_t address)
+int mem_ap_read_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address)
 {
        uint32_t invalue;
        int retval = ERROR_OK;
@@ -939,7 +1014,7 @@ int mem_ap_read_buf_u8(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint32
        while (count > 0)
        {
                dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address);
-               dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue );
+               dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue);
                retval = swjdp_transaction_endcheck(swjdp);
                *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
                count--;
@@ -950,7 +1025,14 @@ int mem_ap_read_buf_u8(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint32
        return retval;
 }
 
-int ahbap_debugport_init(swjdp_common_t *swjdp)
+/**
+ * Initialize a DAP.
+ *
+ * @todo Rename this.  We also need an initialization scheme which account
+ * for SWD transports not just JTAG; that will need to address differences
+ * in layering.  (JTAG is useful without any debug target; but not SWD.)
+ */
+int ahbap_debugport_init(struct swjdp_common *swjdp)
 {
        uint32_t idreg, romaddr, dummy;
        uint32_t ctrlstat;
@@ -959,9 +1041,17 @@ int ahbap_debugport_init(swjdp_common_t *swjdp)
 
        LOG_DEBUG(" ");
 
+       /* Default MEM-AP setup.
+        *
+        * REVISIT AP #0 may be an inappropriate default for this.
+        * Should we probe, or receve a hint from the caller?
+        * Presumably we can ignore the possibility of multiple APs.
+        */
        swjdp->apsel = 0;
        swjdp->ap_csw_value = -1;
        swjdp->ap_tar_value = -1;
+
+       /* DP initialization */
        swjdp->trans_mode = TRANS_MODE_ATOMIC;
        dap_dp_read_reg(swjdp, &dummy, DP_CTRL_STAT);
        dap_dp_write_reg(swjdp, SSTICKYERR, DP_CTRL_STAT);
@@ -999,54 +1089,78 @@ int ahbap_debugport_init(swjdp_common_t *swjdp)
        dap_dp_write_reg(swjdp, swjdp->dp_ctrl_stat, DP_CTRL_STAT);
        dap_dp_read_reg(swjdp, &dummy, DP_CTRL_STAT);
 
-       dap_ap_read_reg_u32(swjdp, 0xFC, &idreg);
-       dap_ap_read_reg_u32(swjdp, 0xF8, &romaddr);
+       /*
+        * REVISIT this isn't actually *initializing* anything in an AP,
+        * and doesn't care if it's a MEM-AP at all (much less AHB-AP).
+        * Should it?  If the ROM address is valid, is this the right
+        * place to scan the table and do any topology detection?
+        */
+       dap_ap_read_reg_u32(swjdp, AP_REG_IDR, &idreg);
+       dap_ap_read_reg_u32(swjdp, AP_REG_BASE, &romaddr);
 
        LOG_DEBUG("AHB-AP ID Register 0x%" PRIx32 ", Debug ROM Address 0x%" PRIx32 "", idreg, romaddr);
 
        return ERROR_OK;
 }
 
+/* CID interpretation -- see ARM IHI 0029B section 3
+ * and ARM IHI 0031A table 13-3.
+ */
+static const char *class_description[16] ={
+       "Reserved", "ROM table", "Reserved", "Reserved",
+       "Reserved", "Reserved", "Reserved", "Reserved",
+       "Reserved", "CoreSight component", "Reserved", "Peripheral Test Block",
+       "Reserved", "OptimoDE DESS",
+               "Generic IP component", "PrimeCell or System component"
+};
+
+static bool
+is_dap_cid_ok(uint32_t cid3, uint32_t cid2, uint32_t cid1, uint32_t cid0)
+{
+       return cid3 == 0xb1 && cid2 == 0x05
+                       && ((cid1 & 0x0f) == 0) && cid0 == 0x0d;
+}
 
-char * class_description[16] ={
-       "Reserved",
-       "ROM table","Reserved","Reserved","Reserved","Reserved","Reserved","Reserved","Reserved",
-       "CoreSight component","Reserved","Peripheral Test Block","Reserved","DESS","Generic IP component","Non standard layout"};
-
-int dap_info_command(struct command_context_s *cmd_ctx, swjdp_common_t *swjdp, int apsel)
+int dap_info_command(struct command_context *cmd_ctx, struct swjdp_common *swjdp, int apsel)
 {
 
-       uint32_t dbgbase,apid;
+       uint32_t dbgbase, apid;
        int romtable_present = 0;
        uint8_t mem_ap;
        uint32_t apselold;
 
        apselold = swjdp->apsel;
        dap_ap_select(swjdp, apsel);
-       dap_ap_read_reg_u32(swjdp, 0xF8, &dbgbase);
-       dap_ap_read_reg_u32(swjdp, 0xFC, &apid);
+       dap_ap_read_reg_u32(swjdp, AP_REG_BASE, &dbgbase);
+       dap_ap_read_reg_u32(swjdp, AP_REG_IDR, &apid);
        swjdp_transaction_endcheck(swjdp);
        /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec  */
        mem_ap = ((apid&0x10000) && ((apid&0x0F) != 0));
-       command_print(cmd_ctx, "ap identification register 0x%8.8" PRIx32 "", apid);
+       command_print(cmd_ctx, "AP ID register 0x%8.8" PRIx32, apid);
        if (apid)
        {
                switch (apid&0x0F)
                {
                        case 0:
-                               command_print(cmd_ctx, "\tType is jtag-ap");
+                               command_print(cmd_ctx, "\tType is JTAG-AP");
                                break;
                        case 1:
-                               command_print(cmd_ctx, "\tType is mem-ap AHB");
+                               command_print(cmd_ctx, "\tType is MEM-AP AHB");
                                break;
                        case 2:
-                               command_print(cmd_ctx, "\tType is mem-ap APB");
+                               command_print(cmd_ctx, "\tType is MEM-AP APB");
                                break;
                        default:
-                               command_print(cmd_ctx, "\tUnknown AP-type");
-                       break;
+                               command_print(cmd_ctx, "\tUnknown AP type");
+                               break;
                }
-               command_print(cmd_ctx, "ap debugbase 0x%8.8" PRIx32 "", dbgbase);
+
+               /* NOTE: a MEM-AP may have a single CoreSight component that's
+                * not a ROM table ... or have no such components at all.
+                */
+               if (mem_ap)
+                       command_print(cmd_ctx, "AP BASE 0x%8.8" PRIx32,
+                                       dbgbase);
        }
        else
        {
@@ -1058,57 +1172,283 @@ int dap_info_command(struct command_context_s *cmd_ctx, swjdp_common_t *swjdp, i
        {
                uint32_t cid0,cid1,cid2,cid3,memtype,romentry;
                uint16_t entry_offset;
+
                /* bit 16 of apid indicates a memory access port */
-               if (dbgbase&0x02)
-               {
+               if (dbgbase & 0x02)
                        command_print(cmd_ctx, "\tValid ROM table present");
-               }
                else
-               {
-                       command_print(cmd_ctx, "\tROM table in legacy format" );
-               }
+                       command_print(cmd_ctx, "\tROM table in legacy format");
+
                /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec  */
-               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000)|0xFF0, &cid0);
-               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000)|0xFF4, &cid1);
-               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000)|0xFF8, &cid2);
-               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000)|0xFFC, &cid3);
-               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000)|0xFCC, &memtype);
+               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFF0, &cid0);
+               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFF4, &cid1);
+               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFF8, &cid2);
+               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFFC, &cid3);
+               mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFCC, &memtype);
                swjdp_transaction_endcheck(swjdp);
-               command_print(cmd_ctx, "\tCID3 0x%" PRIx32 ", CID2 0x%" PRIx32 ", CID1 0x%" PRIx32 " CID0, 0x%" PRIx32,cid3,cid2,cid1,cid0);
-               if (memtype&0x01)
-               {
+               if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
+                       command_print(cmd_ctx, "\tCID3 0x%2.2" PRIx32
+                                       ", CID2 0x%2.2" PRIx32
+                                       ", CID1 0x%2.2" PRIx32
+                                       ", CID0 0x%2.2" PRIx32,
+                                       cid3, cid2, cid1, cid0);
+               if (memtype & 0x01)
                        command_print(cmd_ctx, "\tMEMTYPE system memory present on bus");
-               }
                else
-               {
-                       command_print(cmd_ctx, "\tMEMTYPE system memory not present. Dedicated debug bus" );
-               }
+                       command_print(cmd_ctx, "\tMEMTYPE System memory not present. "
+                                       "Dedicated debug bus.");
 
-               /* Now we read ROM table entries from dbgbase&0xFFFFF000)|0x000 until we get 0x00000000 */
+               /* Now we read ROM table entries from dbgbase&0xFFFFF000) | 0x000 until we get 0x00000000 */
                entry_offset = 0;
                do
                {
-                       mem_ap_read_atomic_u32(swjdp, (dbgbase&0xFFFFF000)|entry_offset, &romentry);
+                       mem_ap_read_atomic_u32(swjdp, (dbgbase&0xFFFFF000) | entry_offset, &romentry);
                        command_print(cmd_ctx, "\tROMTABLE[0x%x] = 0x%" PRIx32 "",entry_offset,romentry);
                        if (romentry&0x01)
                        {
-                               uint32_t c_cid0,c_cid1,c_cid2,c_cid3,c_pid0,c_pid1,c_pid2,c_pid3,c_pid4,component_start;
-                               uint32_t component_base = (uint32_t)((dbgbase&0xFFFFF000)+(int)(romentry&0xFFFFF000));
-                               mem_ap_read_atomic_u32(swjdp, (component_base&0xFFFFF000)|0xFE0, &c_pid0);
-                               mem_ap_read_atomic_u32(swjdp, (component_base&0xFFFFF000)|0xFE4, &c_pid1);
-                               mem_ap_read_atomic_u32(swjdp, (component_base&0xFFFFF000)|0xFE8, &c_pid2);
-                               mem_ap_read_atomic_u32(swjdp, (component_base&0xFFFFF000)|0xFEC, &c_pid3);
-                               mem_ap_read_atomic_u32(swjdp, (component_base&0xFFFFF000)|0xFD0, &c_pid4);
-                               mem_ap_read_atomic_u32(swjdp, (component_base&0xFFFFF000)|0xFF0, &c_cid0);
-                               mem_ap_read_atomic_u32(swjdp, (component_base&0xFFFFF000)|0xFF4, &c_cid1);
-                               mem_ap_read_atomic_u32(swjdp, (component_base&0xFFFFF000)|0xFF8, &c_cid2);
-                               mem_ap_read_atomic_u32(swjdp, (component_base&0xFFFFF000)|0xFFC, &c_cid3);
+                               uint32_t c_cid0, c_cid1, c_cid2, c_cid3;
+                               uint32_t c_pid0, c_pid1, c_pid2, c_pid3, c_pid4;
+                               uint32_t component_start, component_base;
+                               unsigned part_num;
+                               char *type, *full;
+
+                               component_base = (uint32_t)((dbgbase & 0xFFFFF000)
+                                               + (int)(romentry & 0xFFFFF000));
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFE0, &c_pid0);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFE4, &c_pid1);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFE8, &c_pid2);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFEC, &c_pid3);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFD0, &c_pid4);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFF0, &c_cid0);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFF4, &c_cid1);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFF8, &c_cid2);
+                               mem_ap_read_atomic_u32(swjdp,
+                                               (component_base & 0xFFFFF000) | 0xFFC, &c_cid3);
                                component_start = component_base - 0x1000*(c_pid4 >> 4);
-                               command_print(cmd_ctx, "\t\tComponent base address 0x%" PRIx32 ", pid4 0x%" PRIx32 ", start address 0x%" PRIx32 "",component_base,c_pid4,component_start);
-                               command_print(cmd_ctx, "\t\tComponent cid1 0x%" PRIx32 ", class is %s",c_cid1,class_description[(c_cid1 >> 4)&0xF]); /* Se ARM DDI 0314 C Table 2.2 */
-                               command_print(cmd_ctx, "\t\tCID3 0x%" PRIx32 ", CID2 0x%" PRIx32 ", CID1 0x%" PRIx32 ", CID0, 0x%" PRIx32 "",c_cid3,c_cid2,c_cid1,c_cid0);
-                               command_print(cmd_ctx, "\t\tPID3 0x%" PRIx32 ", PID2 0x%" PRIx32 ", PID1 0x%" PRIx32 ", PID0, 0x%" PRIx32 "",c_pid3,c_pid2,c_pid1,c_pid0);
-                               /* For CoreSight components,  (c_cid1 >> 4)&0xF == 9 , we also read 0xFC8 DevId and 0xFCC DevType */
+
+                               command_print(cmd_ctx, "\t\tComponent base address 0x%" PRIx32
+                                               ", start address 0x%" PRIx32,
+                                               component_base, component_start);
+                               command_print(cmd_ctx, "\t\tComponent class is 0x%x, %s",
+                                               (int) (c_cid1 >> 4) & 0xf,
+                                               /* See ARM IHI 0029B Table 3-3 */
+                                               class_description[(c_cid1 >> 4) & 0xf]);
+
+                               /* CoreSight component? */
+                               if (((c_cid1 >> 4) & 0x0f) == 9) {
+                                       uint32_t devtype;
+                                       unsigned minor;
+                                       char *major = "Reserved", *subtype = "Reserved";
+
+                                       mem_ap_read_atomic_u32(swjdp,
+                                                       (component_base & 0xfffff000) | 0xfcc,
+                                                       &devtype);
+                                       minor = (devtype >> 4) & 0x0f;
+                                       switch (devtype & 0x0f) {
+                                       case 0:
+                                               major = "Miscellaneous";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 4:
+                                                       subtype = "Validation component";
+                                                       break;
+                                               }
+                                               break;
+                                       case 1:
+                                               major = "Trace Sink";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 1:
+                                                       subtype = "Port";
+                                                       break;
+                                               case 2:
+                                                       subtype = "Buffer";
+                                                       break;
+                                               }
+                                               break;
+                                       case 2:
+                                               major = "Trace Link";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 1:
+                                                       subtype = "Funnel, router";
+                                                       break;
+                                               case 2:
+                                                       subtype = "Filter";
+                                                       break;
+                                               case 3:
+                                                       subtype = "FIFO, buffer";
+                                                       break;
+                                               }
+                                               break;
+                                       case 3:
+                                               major = "Trace Source";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 1:
+                                                       subtype = "Processor";
+                                                       break;
+                                               case 2:
+                                                       subtype = "DSP";
+                                                       break;
+                                               case 3:
+                                                       subtype = "Engine/Coprocessor";
+                                                       break;
+                                               case 4:
+                                                       subtype = "Bus";
+                                                       break;
+                                               }
+                                               break;
+                                       case 4:
+                                               major = "Debug Control";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 1:
+                                                       subtype = "Trigger Matrix";
+                                                       break;
+                                               case 2:
+                                                       subtype = "Debug Auth";
+                                                       break;
+                                               }
+                                               break;
+                                       case 5:
+                                               major = "Debug Logic";
+                                               switch (minor) {
+                                               case 0:
+                                                       subtype = "other";
+                                                       break;
+                                               case 1:
+                                                       subtype = "Processor";
+                                                       break;
+                                               case 2:
+                                                       subtype = "DSP";
+                                                       break;
+                                               case 3:
+                                                       subtype = "Engine/Coprocessor";
+                                                       break;
+                                               }
+                                               break;
+                                       }
+                                       command_print(cmd_ctx, "\t\tType is 0x%2.2x, %s, %s",
+                                                       (unsigned) (devtype & 0xff),
+                                                       major, subtype);
+                                       /* REVISIT also show 0xfc8 DevId */
+                               }
+
+                               if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
+                                       command_print(cmd_ctx, "\t\tCID3 0x%2.2" PRIx32
+                                                       ", CID2 0x%2.2" PRIx32
+                                                       ", CID1 0x%2.2" PRIx32
+                                                       ", CID0 0x%2.2" PRIx32,
+                                                       c_cid3, c_cid2, c_cid1, c_cid0);
+                               command_print(cmd_ctx, "\t\tPeripheral ID[4..0] = hex "
+                                               "%2.2x %2.2x %2.2x %2.2x %2.2x",
+                                               (int) c_pid4,
+                                               (int) c_pid3, (int) c_pid2,
+                                               (int) c_pid1, (int) c_pid0);
+
+                               /* Part number interpretations are from Cortex
+                                * core specs, the CoreSight components TRM
+                                * (ARM DDI 0314H), and ETM specs; also from
+                                * chip observation (e.g. TI SDTI).
+                                */
+                               part_num = c_pid0 & 0xff;
+                               part_num |= (c_pid1 & 0x0f) << 8;
+                               switch (part_num) {
+                               case 0x000:
+                                       type = "Cortex-M3 NVIC";
+                                       full = "(Interrupt Controller)";
+                                       break;
+                               case 0x001:
+                                       type = "Cortex-M3 ITM";
+                                       full = "(Instrumentation Trace Module)";
+                                       break;
+                               case 0x002:
+                                       type = "Cortex-M3 DWT";
+                                       full = "(Data Watchpoint and Trace)";
+                                       break;
+                               case 0x003:
+                                       type = "Cortex-M3 FBP";
+                                       full = "(Flash Patch and Breakpoint)";
+                                       break;
+                               case 0x00d:
+                                       type = "CoreSight ETM11";
+                                       full = "(Embedded Trace)";
+                                       break;
+                               // case 0x113: what?
+                               case 0x120:             /* from OMAP3 memmap */
+                                       type = "TI SDTI";
+                                       full = "(System Debug Trace Interface)";
+                                       break;
+                               case 0x343:             /* from OMAP3 memmap */
+                                       type = "TI DAPCTL";
+                                       full = "";
+                                       break;
+                               case 0x4e0:
+                                       type = "Cortex-M3 ETM";
+                                       full = "(Embedded Trace)";
+                                       break;
+                               case 0x906:
+                                       type = "Coresight CTI";
+                                       full = "(Cross Trigger)";
+                                       break;
+                               case 0x907:
+                                       type = "Coresight ETB";
+                                       full = "(Trace Buffer)";
+                                       break;
+                               case 0x908:
+                                       type = "Coresight CSTF";
+                                       full = "(Trace Funnel)";
+                                       break;
+                               case 0x910:
+                                       type = "CoreSight ETM9";
+                                       full = "(Embedded Trace)";
+                                       break;
+                               case 0x912:
+                                       type = "Coresight TPIU";
+                                       full = "(Trace Port Interface Unit)";
+                                       break;
+                               case 0x921:
+                                       type = "Cortex-A8 ETM";
+                                       full = "(Embedded Trace)";
+                                       break;
+                               case 0x922:
+                                       type = "Cortex-A8 CTI";
+                                       full = "(Cross Trigger)";
+                                       break;
+                               case 0x923:
+                                       type = "Cortex-M3 TPIU";
+                                       full = "(Trace Port Interface Unit)";
+                                       break;
+                               case 0xc08:
+                                       type = "Cortex-A8 Debug";
+                                       full = "(Debug Unit)";
+                                       break;
+                               default:
+                                       type = "-*- unrecognized -*-";
+                                       full = "";
+                                       break;
+                               }
+                               command_print(cmd_ctx, "\t\tPart is %s %s",
+                                               type, full);
                        }
                        else
                        {
@@ -1118,7 +1458,7 @@ int dap_info_command(struct command_context_s *cmd_ctx, swjdp_common_t *swjdp, i
                                        command_print(cmd_ctx, "\t\tEnd of ROM table");
                        }
                        entry_offset += 4;
-               } while (romentry>0);
+               } while (romentry > 0);
        }
        else
        {
@@ -1129,3 +1469,108 @@ int dap_info_command(struct command_context_s *cmd_ctx, swjdp_common_t *swjdp, i
        return ERROR_OK;
 }
 
+DAP_COMMAND_HANDLER(dap_baseaddr_command)
+{
+       uint32_t apsel, apselsave, baseaddr;
+       int retval;
+
+       apselsave = swjdp->apsel;
+       switch (CMD_ARGC) {
+       case 0:
+               apsel = swjdp->apsel;
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       if (apselsave != apsel)
+               dap_ap_select(swjdp, apsel);
+
+       dap_ap_read_reg_u32(swjdp, AP_REG_BASE, &baseaddr);
+       retval = swjdp_transaction_endcheck(swjdp);
+       command_print(CMD_CTX, "0x%8.8" PRIx32, baseaddr);
+
+       if (apselsave != apsel)
+               dap_ap_select(swjdp, apselsave);
+
+       return retval;
+}
+
+DAP_COMMAND_HANDLER(dap_memaccess_command)
+{
+       uint32_t memaccess_tck;
+
+       switch (CMD_ARGC) {
+       case 0:
+               memaccess_tck = swjdp->memaccess_tck;
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], memaccess_tck);
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+       swjdp->memaccess_tck = memaccess_tck;
+
+       command_print(CMD_CTX, "memory bus access delay set to %" PRIi32 " tck",
+                       swjdp->memaccess_tck);
+
+       return ERROR_OK;
+}
+
+DAP_COMMAND_HANDLER(dap_apsel_command)
+{
+       uint32_t apsel, apid;
+       int retval;
+
+       switch (CMD_ARGC) {
+       case 0:
+               apsel = 0;
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       dap_ap_select(swjdp, apsel);
+       dap_ap_read_reg_u32(swjdp, AP_REG_IDR, &apid);
+       retval = swjdp_transaction_endcheck(swjdp);
+       command_print(CMD_CTX, "ap %" PRIi32 " selected, identification register 0x%8.8" PRIx32,
+                       apsel, apid);
+
+       return retval;
+}
+
+DAP_COMMAND_HANDLER(dap_apid_command)
+{
+       uint32_t apsel, apselsave, apid;
+       int retval;
+
+       apselsave = swjdp->apsel;
+       switch (CMD_ARGC) {
+       case 0:
+               apsel = swjdp->apsel;
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       if (apselsave != apsel)
+               dap_ap_select(swjdp, apsel);
+
+       dap_ap_read_reg_u32(swjdp, AP_REG_IDR, &apid);
+       retval = swjdp_transaction_endcheck(swjdp);
+       command_print(CMD_CTX, "0x%8.8" PRIx32, apid);
+       if (apselsave != apsel)
+               dap_ap_select(swjdp, apselsave);
+
+       return retval;
+}

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)