cortex_m: Discover the AP to use, just like Cortex-A
[fw/openocd] / src / target / arm_adi_v5.c
index 4a1e42c026b9e5afe4cca3b9a0ad976c2b5da6db..3a81784e301548e72ce1e6bcf53de335b1155f13 100644 (file)
@@ -113,34 +113,33 @@ void dap_ap_select(struct adiv5_dap *dap, uint8_t ap)
                 * Values MUST BE UPDATED BEFORE AP ACCESS.
                 */
                dap->ap_bank_value = -1;
-               dap->ap_csw_value = -1;
-               dap->ap_tar_value = -1;
        }
 }
 
 static int dap_setup_accessport_csw(struct adiv5_dap *dap, uint32_t csw)
 {
        csw = csw | CSW_DBGSWENABLE | CSW_MASTER_DEBUG | CSW_HPROT |
-               dap->apcsw[dap->ap_current >> 24];
+               dap->ap[dap_ap_get_select(dap)].csw_default;
 
-       if (csw != dap->ap_csw_value) {
+       if (csw != dap->ap[dap_ap_get_select(dap)].csw_value) {
                /* LOG_DEBUG("DAP: Set CSW %x",csw); */
-               int retval = dap_queue_ap_write(dap, AP_REG_CSW, csw);
+               int retval = dap_queue_ap_write(dap, MEM_AP_REG_CSW, csw);
                if (retval != ERROR_OK)
                        return retval;
-               dap->ap_csw_value = csw;
+               dap->ap[dap_ap_get_select(dap)].csw_value = csw;
        }
        return ERROR_OK;
 }
 
 static int dap_setup_accessport_tar(struct adiv5_dap *dap, uint32_t tar)
 {
-       if (tar != dap->ap_tar_value || dap->ap_csw_value & CSW_ADDRINC_MASK) {
+       if (tar != dap->ap[dap_ap_get_select(dap)].tar_value ||
+                       (dap->ap[dap_ap_get_select(dap)].csw_value & CSW_ADDRINC_MASK)) {
                /* LOG_DEBUG("DAP: Set TAR %x",tar); */
-               int retval = dap_queue_ap_write(dap, AP_REG_TAR, tar);
+               int retval = dap_queue_ap_write(dap, MEM_AP_REG_TAR, tar);
                if (retval != ERROR_OK)
                        return retval;
-               dap->ap_tar_value = tar;
+               dap->ap[dap_ap_get_select(dap)].tar_value = tar;
        }
        return ERROR_OK;
 }
@@ -149,7 +148,7 @@ static int dap_setup_accessport_tar(struct adiv5_dap *dap, uint32_t tar)
  * Queue transactions setting up transfer parameters for the
  * currently selected MEM-AP.
  *
- * Subsequent transfers using registers like AP_REG_DRW or AP_REG_BD2
+ * Subsequent transfers using registers like MEM_AP_REG_DRW or MEM_AP_REG_BD2
  * initiate data reads or writes using memory or peripheral addresses.
  * If the CSW is configured for it, the TAR may be automatically
  * incremented after each transfer.
@@ -187,7 +186,7 @@ int dap_setup_accessport(struct adiv5_dap *dap, uint32_t csw, uint32_t tar)
  *
  * @return ERROR_OK for success.  Otherwise a fault code.
  */
-int mem_ap_read_u32(struct adiv5_dap *dap, uint32_t address,
+static int mem_ap_read_u32(struct adiv5_dap *dap, uint32_t address,
                uint32_t *value)
 {
        int retval;
@@ -200,7 +199,7 @@ int mem_ap_read_u32(struct adiv5_dap *dap, uint32_t address,
        if (retval != ERROR_OK)
                return retval;
 
-       return dap_queue_ap_read(dap, AP_REG_BD0 | (address & 0xC), value);
+       return dap_queue_ap_read(dap, MEM_AP_REG_BD0 | (address & 0xC), value);
 }
 
 /**
@@ -215,7 +214,7 @@ int mem_ap_read_u32(struct adiv5_dap *dap, uint32_t address,
  * @return ERROR_OK for success; *value holds the result.
  * Otherwise a fault code.
  */
-int mem_ap_read_atomic_u32(struct adiv5_dap *dap, uint32_t address,
+static int mem_ap_read_atomic_u32(struct adiv5_dap *dap, uint32_t address,
                uint32_t *value)
 {
        int retval;
@@ -238,7 +237,7 @@ int mem_ap_read_atomic_u32(struct adiv5_dap *dap, uint32_t address,
  *
  * @return ERROR_OK for success.  Otherwise a fault code.
  */
-int mem_ap_write_u32(struct adiv5_dap *dap, uint32_t address,
+static int mem_ap_write_u32(struct adiv5_dap *dap, uint32_t address,
                uint32_t value)
 {
        int retval;
@@ -251,7 +250,7 @@ int mem_ap_write_u32(struct adiv5_dap *dap, uint32_t address,
        if (retval != ERROR_OK)
                return retval;
 
-       return dap_queue_ap_write(dap, AP_REG_BD0 | (address & 0xC),
+       return dap_queue_ap_write(dap, MEM_AP_REG_BD0 | (address & 0xC),
                        value);
 }
 
@@ -266,7 +265,7 @@ int mem_ap_write_u32(struct adiv5_dap *dap, uint32_t address,
  *
  * @return ERROR_OK for success; the data was written.  Otherwise a fault code.
  */
-int mem_ap_write_atomic_u32(struct adiv5_dap *dap, uint32_t address,
+static int mem_ap_write_atomic_u32(struct adiv5_dap *dap, uint32_t address,
                uint32_t value)
 {
        int retval = mem_ap_write_u32(dap, address, value);
@@ -289,24 +288,46 @@ int mem_ap_write_atomic_u32(struct adiv5_dap *dap, uint32_t address,
  *  should normally be true, except when writing to e.g. a FIFO.
  * @return ERROR_OK on success, otherwise an error code.
  */
-int mem_ap_write(struct adiv5_dap *dap, const uint8_t *buffer, uint32_t size, uint32_t count,
+static int mem_ap_write(struct adiv5_dap *dap, const uint8_t *buffer, uint32_t size, uint32_t count,
                uint32_t address, bool addrinc)
 {
+       struct adiv5_ap *ap = &dap->ap[dap_ap_get_select(dap)];
        size_t nbytes = size * count;
        const uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF;
        uint32_t csw_size;
+       uint32_t addr_xor;
        int retval;
 
-       if (size == 4)
+       /* TI BE-32 Quirks mode:
+        * Writes on big-endian TMS570 behave very strangely. Observed behavior:
+        *   size   write address   bytes written in order
+        *   4      TAR ^ 0         (val >> 24), (val >> 16), (val >> 8), (val)
+        *   2      TAR ^ 2         (val >> 8), (val)
+        *   1      TAR ^ 3         (val)
+        * For example, if you attempt to write a single byte to address 0, the processor
+        * will actually write a byte to address 3.
+        *
+        * To make writes of size < 4 work as expected, we xor a value with the address before
+        * setting the TAP, and we set the TAP after every transfer rather then relying on
+        * address increment. */
+
+       if (size == 4) {
                csw_size = CSW_32BIT;
-       else if (size == 2)
+               addr_xor = 0;
+       } else if (size == 2) {
                csw_size = CSW_16BIT;
-       else if (size == 1)
+               addr_xor = dap->ti_be_32_quirks ? 2 : 0;
+       } else if (size == 1) {
                csw_size = CSW_8BIT;
-       else
+               addr_xor = dap->ti_be_32_quirks ? 3 : 0;
+       } else {
                return ERROR_TARGET_UNALIGNED_ACCESS;
+       }
 
-       retval = dap_setup_accessport_tar(dap, address);
+       if (ap->unaligned_access_bad && (address % size != 0))
+               return ERROR_TARGET_UNALIGNED_ACCESS;
+
+       retval = dap_setup_accessport_tar(dap, address ^ addr_xor);
        if (retval != ERROR_OK)
                return retval;
 
@@ -314,8 +335,8 @@ int mem_ap_write(struct adiv5_dap *dap, const uint8_t *buffer, uint32_t size, ui
                uint32_t this_size = size;
 
                /* Select packed transfer if possible */
-               if (addrinc && dap->packed_transfers && nbytes >= 4
-                               && max_tar_block_size(dap->tar_autoincr_block, address) >= 4) {
+               if (addrinc && ap->packed_transfers && nbytes >= 4
+                               && max_tar_block_size(ap->tar_autoincr_block, address) >= 4) {
                        this_size = 4;
                        retval = dap_setup_accessport_csw(dap, csw_size | CSW_ADDRINC_PACKED);
                } else {
@@ -328,25 +349,43 @@ int mem_ap_write(struct adiv5_dap *dap, const uint8_t *buffer, uint32_t size, ui
                /* How many source bytes each transfer will consume, and their location in the DRW,
                 * depends on the type of transfer and alignment. See ARM document IHI0031C. */
                uint32_t outvalue = 0;
-               switch (this_size) {
-               case 4:
-                       outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
-                       outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
-               case 2:
-                       outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
-               case 1:
-                       outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
+               if (dap->ti_be_32_quirks) {
+                       switch (this_size) {
+                       case 4:
+                               outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
+                               outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
+                               outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
+                               outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
+                               break;
+                       case 2:
+                               outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (address++ & 3) ^ addr_xor);
+                               outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (address++ & 3) ^ addr_xor);
+                               break;
+                       case 1:
+                               outvalue |= (uint32_t)*buffer++ << 8 * (0 ^ (address++ & 3) ^ addr_xor);
+                               break;
+                       }
+               } else {
+                       switch (this_size) {
+                       case 4:
+                               outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
+                               outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
+                       case 2:
+                               outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
+                       case 1:
+                               outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
+                       }
                }
 
                nbytes -= this_size;
 
-               retval = dap_queue_ap_write(dap, AP_REG_DRW, outvalue);
+               retval = dap_queue_ap_write(dap, MEM_AP_REG_DRW, outvalue);
                if (retval != ERROR_OK)
                        break;
 
-               /* Rewrite TAR if it wrapped */
-               if (addrinc && address % dap->tar_autoincr_block < size && nbytes > 0) {
-                       retval = dap_setup_accessport_tar(dap, address);
+               /* Rewrite TAR if it wrapped or we're xoring addresses */
+               if (addrinc && (addr_xor || (address % ap->tar_autoincr_block < size && nbytes > 0))) {
+                       retval = dap_setup_accessport_tar(dap, address ^ addr_xor);
                        if (retval != ERROR_OK)
                                break;
                }
@@ -358,7 +397,7 @@ int mem_ap_write(struct adiv5_dap *dap, const uint8_t *buffer, uint32_t size, ui
 
        if (retval != ERROR_OK) {
                uint32_t tar;
-               if (dap_queue_ap_read(dap, AP_REG_TAR, &tar) == ERROR_OK
+               if (dap_queue_ap_read(dap, MEM_AP_REG_TAR, &tar) == ERROR_OK
                                && dap_run(dap) == ERROR_OK)
                        LOG_ERROR("Failed to write memory at 0x%08"PRIx32, tar);
                else
@@ -380,15 +419,23 @@ int mem_ap_write(struct adiv5_dap *dap, const uint8_t *buffer, uint32_t size, ui
  *  should normally be true, except when reading from e.g. a FIFO.
  * @return ERROR_OK on success, otherwise an error code.
  */
-int mem_ap_read(struct adiv5_dap *dap, uint8_t *buffer, uint32_t size, uint32_t count,
+static int mem_ap_read(struct adiv5_dap *dap, uint8_t *buffer, uint32_t size, uint32_t count,
                uint32_t adr, bool addrinc)
 {
+       struct adiv5_ap *ap = &dap->ap[dap_ap_get_select(dap)];
        size_t nbytes = size * count;
        const uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF;
        uint32_t csw_size;
        uint32_t address = adr;
        int retval;
 
+       /* TI BE-32 Quirks mode:
+        * Reads on big-endian TMS570 behave strangely differently than writes.
+        * They read from the physical address requested, but with DRW byte-reversed.
+        * For example, a byte read from address 0 will place the result in the high bytes of DRW.
+        * Also, packed 8-bit and 16-bit transfers seem to sometimes return garbage in some bytes,
+        * so avoid them. */
+
        if (size == 4)
                csw_size = CSW_32BIT;
        else if (size == 2)
@@ -398,6 +445,9 @@ int mem_ap_read(struct adiv5_dap *dap, uint8_t *buffer, uint32_t size, uint32_t
        else
                return ERROR_TARGET_UNALIGNED_ACCESS;
 
+       if (ap->unaligned_access_bad && (adr % size != 0))
+               return ERROR_TARGET_UNALIGNED_ACCESS;
+
        /* Allocate buffer to hold the sequence of DRW reads that will be made. This is a significant
         * over-allocation if packed transfers are going to be used, but determining the real need at
         * this point would be messy. */
@@ -409,8 +459,10 @@ int mem_ap_read(struct adiv5_dap *dap, uint8_t *buffer, uint32_t size, uint32_t
        }
 
        retval = dap_setup_accessport_tar(dap, address);
-       if (retval != ERROR_OK)
+       if (retval != ERROR_OK) {
+               free(read_buf);
                return retval;
+       }
 
        /* Queue up all reads. Each read will store the entire DRW word in the read buffer. How many
         * useful bytes it contains, and their location in the word, depends on the type of transfer
@@ -419,8 +471,8 @@ int mem_ap_read(struct adiv5_dap *dap, uint8_t *buffer, uint32_t size, uint32_t
                uint32_t this_size = size;
 
                /* Select packed transfer if possible */
-               if (addrinc && dap->packed_transfers && nbytes >= 4
-                               && max_tar_block_size(dap->tar_autoincr_block, address) >= 4) {
+               if (addrinc && ap->packed_transfers && nbytes >= 4
+                               && max_tar_block_size(ap->tar_autoincr_block, address) >= 4) {
                        this_size = 4;
                        retval = dap_setup_accessport_csw(dap, csw_size | CSW_ADDRINC_PACKED);
                } else {
@@ -429,7 +481,7 @@ int mem_ap_read(struct adiv5_dap *dap, uint8_t *buffer, uint32_t size, uint32_t
                if (retval != ERROR_OK)
                        break;
 
-               retval = dap_queue_ap_read(dap, AP_REG_DRW, read_ptr++);
+               retval = dap_queue_ap_read(dap, MEM_AP_REG_DRW, read_ptr++);
                if (retval != ERROR_OK)
                        break;
 
@@ -437,7 +489,7 @@ int mem_ap_read(struct adiv5_dap *dap, uint8_t *buffer, uint32_t size, uint32_t
                address += this_size;
 
                /* Rewrite TAR if it wrapped */
-               if (addrinc && address % dap->tar_autoincr_block < size && nbytes > 0) {
+               if (addrinc && address % ap->tar_autoincr_block < size && nbytes > 0) {
                        retval = dap_setup_accessport_tar(dap, address);
                        if (retval != ERROR_OK)
                                break;
@@ -456,7 +508,7 @@ int mem_ap_read(struct adiv5_dap *dap, uint8_t *buffer, uint32_t size, uint32_t
         * at least give the caller what we have. */
        if (retval != ERROR_OK) {
                uint32_t tar;
-               if (dap_queue_ap_read(dap, AP_REG_TAR, &tar) == ERROR_OK
+               if (dap_queue_ap_read(dap, MEM_AP_REG_TAR, &tar) == ERROR_OK
                                && dap_run(dap) == ERROR_OK) {
                        LOG_ERROR("Failed to read memory at 0x%08"PRIx32, tar);
                        if (nbytes > tar - address)
@@ -471,19 +523,31 @@ int mem_ap_read(struct adiv5_dap *dap, uint8_t *buffer, uint32_t size, uint32_t
        while (nbytes > 0) {
                uint32_t this_size = size;
 
-               if (addrinc && dap->packed_transfers && nbytes >= 4
-                               && max_tar_block_size(dap->tar_autoincr_block, address) >= 4) {
+               if (addrinc && ap->packed_transfers && nbytes >= 4
+                               && max_tar_block_size(ap->tar_autoincr_block, address) >= 4) {
                        this_size = 4;
                }
 
-               switch (this_size) {
-               case 4:
-                       *buffer++ = *read_ptr >> 8 * (address++ & 3);
-                       *buffer++ = *read_ptr >> 8 * (address++ & 3);
-               case 2:
-                       *buffer++ = *read_ptr >> 8 * (address++ & 3);
-               case 1:
-                       *buffer++ = *read_ptr >> 8 * (address++ & 3);
+               if (dap->ti_be_32_quirks) {
+                       switch (this_size) {
+                       case 4:
+                               *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
+                               *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
+                       case 2:
+                               *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
+                       case 1:
+                               *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
+                       }
+               } else {
+                       switch (this_size) {
+                       case 4:
+                               *buffer++ = *read_ptr >> 8 * (address++ & 3);
+                               *buffer++ = *read_ptr >> 8 * (address++ & 3);
+                       case 2:
+                               *buffer++ = *read_ptr >> 8 * (address++ & 3);
+                       case 1:
+                               *buffer++ = *read_ptr >> 8 * (address++ & 3);
+                       }
                }
 
                read_ptr++;
@@ -553,196 +617,37 @@ int mem_ap_sel_write_buf_noincr(struct adiv5_dap *swjdp, uint8_t ap,
        return mem_ap_write(swjdp, buffer, size, count, address, false);
 }
 
-#define MDM_REG_STAT           0x00
-#define MDM_REG_CTRL           0x04
-#define MDM_REG_ID             0xfc
-
-#define MDM_STAT_FMEACK                (1<<0)
-#define MDM_STAT_FREADY                (1<<1)
-#define MDM_STAT_SYSSEC                (1<<2)
-#define MDM_STAT_SYSRES                (1<<3)
-#define MDM_STAT_FMEEN         (1<<5)
-#define MDM_STAT_BACKDOOREN    (1<<6)
-#define MDM_STAT_LPEN          (1<<7)
-#define MDM_STAT_VLPEN         (1<<8)
-#define MDM_STAT_LLSMODEXIT    (1<<9)
-#define MDM_STAT_VLLSXMODEXIT  (1<<10)
-#define MDM_STAT_CORE_HALTED   (1<<16)
-#define MDM_STAT_CORE_SLEEPDEEP        (1<<17)
-#define MDM_STAT_CORESLEEPING  (1<<18)
-
-#define MEM_CTRL_FMEIP         (1<<0)
-#define MEM_CTRL_DBG_DIS       (1<<1)
-#define MEM_CTRL_DBG_REQ       (1<<2)
-#define MEM_CTRL_SYS_RES_REQ   (1<<3)
-#define MEM_CTRL_CORE_HOLD_RES (1<<4)
-#define MEM_CTRL_VLLSX_DBG_REQ (1<<5)
-#define MEM_CTRL_VLLSX_DBG_ACK (1<<6)
-#define MEM_CTRL_VLLSX_STAT_ACK        (1<<7)
-
-#define MDM_ACCESS_TIMEOUT     3000 /* ms */
-
-/**
- *
- */
-int dap_syssec_kinetis_mdmap(struct adiv5_dap *dap)
-{
-       uint32_t val;
-       int retval;
-       int timeout = 0;
-       enum reset_types jtag_reset_config = jtag_get_reset_config();
-
-       dap_ap_select(dap, 1);
-
-       /* first check mdm-ap id register */
-       retval = dap_queue_ap_read(dap, MDM_REG_ID, &val);
-       if (retval != ERROR_OK)
-               return retval;
-       dap_run(dap);
-
-       if (val != 0x001C0000) {
-               LOG_DEBUG("id doesn't match %08" PRIX32 " != 0x001C0000", val);
-               dap_ap_select(dap, 0);
-               return ERROR_FAIL;
-       }
-
-       /* read and parse status register
-        * it's important that the device is out of
-        * reset here
-        */
-       while (1) {
-               if (timeout++ > MDM_ACCESS_TIMEOUT) {
-                       LOG_DEBUG("MDMAP : flash ready timeout");
-                       return ERROR_FAIL;
-               }
-               retval = dap_queue_ap_read(dap, MDM_REG_STAT, &val);
-               if (retval != ERROR_OK)
-                       return retval;
-               dap_run(dap);
-
-               LOG_DEBUG("MDM_REG_STAT %08" PRIX32, val);
-               if (val & MDM_STAT_FREADY)
-                       break;
-               alive_sleep(1);
-       }
-
-       if ((val & MDM_STAT_SYSSEC)) {
-               LOG_DEBUG("MDMAP: system is secured, masserase needed");
-
-               if (!(val & MDM_STAT_FMEEN))
-                       LOG_DEBUG("MDMAP: masserase is disabled");
-               else {
-                       /* we need to assert reset */
-                       if (jtag_reset_config & RESET_HAS_SRST) {
-                               /* default to asserting srst */
-                               adapter_assert_reset();
-                       } else {
-                               LOG_DEBUG("SRST not configured");
-                               dap_ap_select(dap, 0);
-                               return ERROR_FAIL;
-                       }
-                       timeout = 0;
-                       while (1) {
-                               if (timeout++ > MDM_ACCESS_TIMEOUT) {
-                                       LOG_DEBUG("MDMAP : flash ready timeout");
-                                       return ERROR_FAIL;
-                               }
-                               retval = dap_queue_ap_write(dap, MDM_REG_CTRL, MEM_CTRL_FMEIP);
-                               if (retval != ERROR_OK)
-                                       return retval;
-                               dap_run(dap);
-                               /* read status register and wait for ready */
-                               retval = dap_queue_ap_read(dap, MDM_REG_STAT, &val);
-                               if (retval != ERROR_OK)
-                                       return retval;
-                               dap_run(dap);
-                               LOG_DEBUG("MDM_REG_STAT %08" PRIX32, val);
-
-                               if ((val & 1))
-                                       break;
-                               alive_sleep(1);
-                       }
-                       timeout = 0;
-                       while (1) {
-                               if (timeout++ > MDM_ACCESS_TIMEOUT) {
-                                       LOG_DEBUG("MDMAP : flash ready timeout");
-                                       return ERROR_FAIL;
-                               }
-                               retval = dap_queue_ap_write(dap, MDM_REG_CTRL, 0);
-                               if (retval != ERROR_OK)
-                                       return retval;
-                               dap_run(dap);
-                               /* read status register */
-                               retval = dap_queue_ap_read(dap, MDM_REG_STAT, &val);
-                               if (retval != ERROR_OK)
-                                       return retval;
-                               dap_run(dap);
-                               LOG_DEBUG("MDM_REG_STAT %08" PRIX32, val);
-                               /* read control register and wait for ready */
-                               retval = dap_queue_ap_read(dap, MDM_REG_CTRL, &val);
-                               if (retval != ERROR_OK)
-                                       return retval;
-                               dap_run(dap);
-                               LOG_DEBUG("MDM_REG_CTRL %08" PRIX32, val);
-
-                               if (val == 0x00)
-                                       break;
-                               alive_sleep(1);
-                       }
-               }
-       }
+/*--------------------------------------------------------------------------*/
 
-       dap_ap_select(dap, 0);
 
-       return ERROR_OK;
-}
+#define DAP_POWER_DOMAIN_TIMEOUT (10)
 
-/** */
-struct dap_syssec_filter {
-       /** */
-       uint32_t idcode;
-       /** */
-       int (*dap_init)(struct adiv5_dap *dap);
-};
+/* FIXME don't import ... just initialize as
+ * part of DAP transport setup
+*/
+extern const struct dap_ops jtag_dp_ops;
 
-/** */
-static struct dap_syssec_filter dap_syssec_filter_data[] = {
-       { 0x4BA00477, dap_syssec_kinetis_mdmap }
-};
+/*--------------------------------------------------------------------------*/
 
 /**
- *
+ * Create a new DAP
  */
-int dap_syssec(struct adiv5_dap *dap)
+struct adiv5_dap *dap_init(void)
 {
-       unsigned int i;
-       struct jtag_tap *tap;
-
-       for (i = 0; i < sizeof(dap_syssec_filter_data); i++) {
-               tap = dap->jtag_info->tap;
-
-               while (tap != NULL) {
-                       if (tap->hasidcode && (dap_syssec_filter_data[i].idcode == tap->idcode)) {
-                               LOG_DEBUG("DAP: mdmap_init for idcode: %08" PRIx32, tap->idcode);
-                               dap_syssec_filter_data[i].dap_init(dap);
-                       }
-                       tap = tap->next_tap;
-               }
+       struct adiv5_dap *dap = calloc(1, sizeof(struct adiv5_dap));
+       int i;
+       /* Set up with safe defaults */
+       for (i = 0; i <= 255; i++) {
+               dap->ap[i].dap = dap;
+               dap->ap[i].ap_num = i;
+               /* memaccess_tck max is 255 */
+               dap->ap[i].memaccess_tck = 255;
+               /* Number of bits for tar autoincrement, impl. dep. at least 10 */
+               dap->ap[i].tar_autoincr_block = (1<<10);
        }
-
-       return ERROR_OK;
+       return dap;
 }
 
-/*--------------------------------------------------------------------------*/
-
-
-/* FIXME don't import ... just initialize as
- * part of DAP transport setup
-*/
-extern const struct dap_ops jtag_dp_ops;
-
-/*--------------------------------------------------------------------------*/
-
 /**
  * Initialize a DAP.  This sets up the power domains, prepares the DP
  * for further use, and arranges to use AP #0 for all AP operations
@@ -755,11 +660,12 @@ extern const struct dap_ops jtag_dp_ops;
  * in layering.  (JTAG is useful without any debug target; but not SWD.)
  * And this may not even use an AHB-AP ... e.g. DAP-Lite uses an APB-AP.
  */
-int ahbap_debugport_init(struct adiv5_dap *dap)
+int ahbap_debugport_init(struct adiv5_dap *dap, uint8_t apsel)
 {
-       uint32_t ctrlstat;
-       int cnt = 0;
+       /* check that we support packed transfers */
+       uint32_t csw, cfg;
        int retval;
+       struct adiv5_ap *ap = &dap->ap[apsel];
 
        LOG_DEBUG(" ");
 
@@ -776,94 +682,104 @@ int ahbap_debugport_init(struct adiv5_dap *dap)
         * Should we probe, or take a hint from the caller?
         * Presumably we can ignore the possibility of multiple APs.
         */
-       dap->ap_current = !0;
-       dap_ap_select(dap, 0);
+       dap->ap_current = -1;
+       dap_ap_select(dap, apsel);
+       dap->last_read = NULL;
 
-       /* DP initialization */
+       for (size_t i = 0; i < 10; i++) {
+               /* DP initialization */
 
-       retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
-       if (retval != ERROR_OK)
-               return retval;
+               dap->dp_bank_value = 0;
 
-       retval = dap_queue_dp_write(dap, DP_CTRL_STAT, SSTICKYERR);
-       if (retval != ERROR_OK)
-               return retval;
+               retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
+               if (retval != ERROR_OK)
+                       continue;
 
-       retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
-       if (retval != ERROR_OK)
-               return retval;
+               retval = dap_queue_dp_write(dap, DP_CTRL_STAT, SSTICKYERR);
+               if (retval != ERROR_OK)
+                       continue;
 
-       dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ;
-       retval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat);
-       if (retval != ERROR_OK)
-               return retval;
+               retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
+               if (retval != ERROR_OK)
+                       continue;
 
-       retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat);
-       if (retval != ERROR_OK)
-               return retval;
-       retval = dap_run(dap);
-       if (retval != ERROR_OK)
-               return retval;
+               dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ;
+               retval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat);
+               if (retval != ERROR_OK)
+                       continue;
 
-       /* Check that we have debug power domains activated */
-       while (!(ctrlstat & CDBGPWRUPACK) && (cnt++ < 10)) {
+               /* Check that we have debug power domains activated */
                LOG_DEBUG("DAP: wait CDBGPWRUPACK");
-               retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat);
+               retval = dap_dp_poll_register(dap, DP_CTRL_STAT,
+                                             CDBGPWRUPACK, CDBGPWRUPACK,
+                                             DAP_POWER_DOMAIN_TIMEOUT);
                if (retval != ERROR_OK)
-                       return retval;
-               retval = dap_run(dap);
-               if (retval != ERROR_OK)
-                       return retval;
-               alive_sleep(10);
-       }
+                       continue;
 
-       while (!(ctrlstat & CSYSPWRUPACK) && (cnt++ < 10)) {
                LOG_DEBUG("DAP: wait CSYSPWRUPACK");
-               retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat);
+               retval = dap_dp_poll_register(dap, DP_CTRL_STAT,
+                                             CSYSPWRUPACK, CSYSPWRUPACK,
+                                             DAP_POWER_DOMAIN_TIMEOUT);
                if (retval != ERROR_OK)
-                       return retval;
-               retval = dap_run(dap);
+                       continue;
+
+               retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
                if (retval != ERROR_OK)
-                       return retval;
-               alive_sleep(10);
-       }
+                       continue;
+               /* With debug power on we can activate OVERRUN checking */
+               dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ | CORUNDETECT;
+               retval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat);
+               if (retval != ERROR_OK)
+                       continue;
+               retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
+               if (retval != ERROR_OK)
+                       continue;
 
-       retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
-       if (retval != ERROR_OK)
-               return retval;
-       /* With debug power on we can activate OVERRUN checking */
-       dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ | CORUNDETECT;
-       retval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat);
-       if (retval != ERROR_OK)
-               return retval;
-       retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
-       if (retval != ERROR_OK)
-               return retval;
+               retval = dap_setup_accessport(dap, CSW_8BIT | CSW_ADDRINC_PACKED, 0);
+               if (retval != ERROR_OK)
+                       continue;
 
-       dap_syssec(dap);
+               retval = dap_queue_ap_read(dap, MEM_AP_REG_CSW, &csw);
+               if (retval != ERROR_OK)
+                       continue;
 
-       /* check that we support packed transfers */
-       uint32_t csw;
+               retval = dap_queue_ap_read(dap, MEM_AP_REG_CFG, &cfg);
+               if (retval != ERROR_OK)
+                       continue;
 
-       retval = dap_setup_accessport(dap, CSW_8BIT | CSW_ADDRINC_PACKED, 0);
-       if (retval != ERROR_OK)
-               return retval;
+               retval = dap_run(dap);
+               if (retval != ERROR_OK)
+                       continue;
 
-       retval = dap_queue_ap_read(dap, AP_REG_CSW, &csw);
-       if (retval != ERROR_OK)
-               return retval;
+               break;
+       }
 
-       retval = dap_run(dap);
        if (retval != ERROR_OK)
                return retval;
 
        if (csw & CSW_ADDRINC_PACKED)
-               dap->packed_transfers = true;
+               ap->packed_transfers = true;
        else
-               dap->packed_transfers = false;
+               ap->packed_transfers = false;
+
+       /* Packed transfers on TI BE-32 processors do not work correctly in
+        * many cases. */
+       if (dap->ti_be_32_quirks)
+               ap->packed_transfers = false;
 
        LOG_DEBUG("MEM_AP Packed Transfers: %s",
-                       dap->packed_transfers ? "enabled" : "disabled");
+                       ap->packed_transfers ? "enabled" : "disabled");
+
+       /* The ARM ADI spec leaves implementation-defined whether unaligned
+        * memory accesses work, only work partially, or cause a sticky error.
+        * On TI BE-32 processors, reads seem to return garbage in some bytes
+        * and unaligned writes seem to cause a sticky error.
+        * TODO: it would be nice to have a way to detect whether unaligned
+        * operations are supported on other processors. */
+       ap->unaligned_access_bad = dap->ti_be_32_quirks;
+
+       LOG_DEBUG("MEM_AP CFG: large data %d, long address %d, big-endian %d",
+                       !!(cfg & 0x04), !!(cfg & 0x02), !!(cfg & 0x01));
 
        return ERROR_OK;
 }
@@ -909,9 +825,10 @@ int dap_find_ap(struct adiv5_dap *dap, enum ap_type type_to_find, uint8_t *ap_nu
                 * 31-28 : Revision
                 * 27-24 : JEDEC bank (0x4 for ARM)
                 * 23-17 : JEDEC code (0x3B for ARM)
-                * 16    : Mem-AP
-                * 15-8  : Reserved
-                *  7-0  : AP Identity (1=AHB-AP 2=APB-AP 0x10=JTAG-AP)
+                * 16-13 : Class (0b1000=Mem-AP)
+                * 12-8  : Reserved
+                *  7-4  : AP Variant (non-zero for JTAG-AP)
+                *  3-0  : AP Type (0=JTAG-AP 1=AHB-AP 2=APB-AP 4=AXI-AP)
                 */
 
                /* Reading register for a non-existant AP should not cause an error,
@@ -919,11 +836,12 @@ int dap_find_ap(struct adiv5_dap *dap, enum ap_type type_to_find, uint8_t *ap_nu
                 */
                if ((retval == ERROR_OK) &&                  /* Register read success */
                        ((id_val & 0x0FFF0000) == 0x04770000) && /* Jedec codes match */
-                       ((id_val & 0xFF) == type_to_find)) {     /* type matches*/
+                       ((id_val & 0xF) == type_to_find)) {      /* type matches*/
 
                        LOG_DEBUG("Found %s at AP index: %d (IDR=0x%08" PRIX32 ")",
                                                (type_to_find == AP_TYPE_AHB_AP)  ? "AHB-AP"  :
                                                (type_to_find == AP_TYPE_APB_AP)  ? "APB-AP"  :
+                                               (type_to_find == AP_TYPE_AXI_AP)  ? "AXI-AP"  :
                                                (type_to_find == AP_TYPE_JTAG_AP) ? "JTAG-AP" : "Unknown",
                                                ap, id_val);
 
@@ -935,65 +853,51 @@ int dap_find_ap(struct adiv5_dap *dap, enum ap_type type_to_find, uint8_t *ap_nu
        LOG_DEBUG("No %s found",
                                (type_to_find == AP_TYPE_AHB_AP)  ? "AHB-AP"  :
                                (type_to_find == AP_TYPE_APB_AP)  ? "APB-AP"  :
+                               (type_to_find == AP_TYPE_AXI_AP)  ? "AXI-AP"  :
                                (type_to_find == AP_TYPE_JTAG_AP) ? "JTAG-AP" : "Unknown");
        return ERROR_FAIL;
 }
 
 int dap_get_debugbase(struct adiv5_dap *dap, int ap,
-                       uint32_t *out_dbgbase, uint32_t *out_apid)
+                       uint32_t *dbgbase, uint32_t *apid)
 {
        uint32_t ap_old;
        int retval;
-       uint32_t dbgbase, apid;
 
        /* AP address is in bits 31:24 of DP_SELECT */
        if (ap >= 256)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       ap_old = dap->ap_current;
+       ap_old = dap_ap_get_select(dap);
        dap_ap_select(dap, ap);
 
-       retval = dap_queue_ap_read(dap, AP_REG_BASE, &dbgbase);
+       retval = dap_queue_ap_read(dap, MEM_AP_REG_BASE, dbgbase);
        if (retval != ERROR_OK)
                return retval;
-       retval = dap_queue_ap_read(dap, AP_REG_IDR, &apid);
+       retval = dap_queue_ap_read(dap, AP_REG_IDR, apid);
        if (retval != ERROR_OK)
                return retval;
        retval = dap_run(dap);
        if (retval != ERROR_OK)
                return retval;
 
-       /* Excavate the device ID code */
-       struct jtag_tap *tap = dap->jtag_info->tap;
-       while (tap != NULL) {
-               if (tap->hasidcode)
-                       break;
-               tap = tap->next_tap;
-       }
-       if (tap == NULL || !tap->hasidcode)
-               return ERROR_OK;
-
        dap_ap_select(dap, ap_old);
 
-       /* The asignment happens only here to prevent modification of these
-        * values before they are certain. */
-       *out_dbgbase = dbgbase;
-       *out_apid = apid;
-
        return ERROR_OK;
 }
 
 int dap_lookup_cs_component(struct adiv5_dap *dap, int ap,
-                       uint32_t dbgbase, uint8_t type, uint32_t *addr)
+                       uint32_t dbgbase, uint8_t type, uint32_t *addr, int32_t *idx)
 {
        uint32_t ap_old;
        uint32_t romentry, entry_offset = 0, component_base, devtype;
-       int retval = ERROR_FAIL;
+       int retval;
 
        if (ap >= 256)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       ap_old = dap->ap_current;
+       *addr = 0;
+       ap_old = dap_ap_get_select(dap);
        dap_ap_select(dap, ap);
 
        do {
@@ -1006,15 +910,33 @@ int dap_lookup_cs_component(struct adiv5_dap *dap, int ap,
                        + (romentry & 0xFFFFF000);
 
                if (romentry & 0x1) {
+                       uint32_t c_cid1;
+                       retval = mem_ap_read_atomic_u32(dap, component_base | 0xff4, &c_cid1);
+                       if (retval != ERROR_OK) {
+                               LOG_ERROR("Can't read component with base address 0x%" PRIx32
+                                         ", the corresponding core might be turned off", component_base);
+                               return retval;
+                       }
+                       if (((c_cid1 >> 4) & 0x0f) == 1) {
+                               retval = dap_lookup_cs_component(dap, ap, component_base,
+                                                       type, addr, idx);
+                               if (retval == ERROR_OK)
+                                       break;
+                               if (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
+                                       return retval;
+                       }
+
                        retval = mem_ap_read_atomic_u32(dap,
                                        (component_base & 0xfffff000) | 0xfcc,
                                        &devtype);
                        if (retval != ERROR_OK)
                                return retval;
                        if ((devtype & 0xff) == type) {
-                               *addr = component_base;
-                               retval = ERROR_OK;
-                               break;
+                               if (!*idx) {
+                                       *addr = component_base;
+                                       break;
+                               } else
+                                       (*idx)--;
                        }
                }
                entry_offset += 4;
@@ -1022,7 +944,10 @@ int dap_lookup_cs_component(struct adiv5_dap *dap, int ap,
 
        dap_ap_select(dap, ap_old);
 
-       return retval;
+       if (!*addr)
+               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+
+       return ERROR_OK;
 }
 
 static int dap_rom_display(struct command_context *cmd_ctx,
@@ -1091,8 +1016,8 @@ static int dap_rom_display(struct command_context *cmd_ctx,
                        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_base;
-                       unsigned part_num;
-                       char *type, *full;
+                       uint32_t part_num;
+                       const char *type, *full;
 
                        component_base = (dbgbase & 0xFFFFF000) + (romentry & 0xFFFFF000);
 
@@ -1142,8 +1067,8 @@ static int dap_rom_display(struct command_context *cmd_ctx,
                                      "start address 0x%" PRIx32, component_base,
                                      /* component may take multiple 4K pages */
                                      (uint32_t)(component_base - 0x1000*(c_pid4 >> 4)));
-                       command_print(cmd_ctx, "\t\tComponent class is 0x%x, %s",
-                                       (c_cid1 >> 4) & 0xf,
+                       command_print(cmd_ctx, "\t\tComponent class is 0x%" PRIx8 ", %s",
+                                       (uint8_t)((c_cid1 >> 4) & 0xf),
                                        /* See ARM IHI 0029B Table 3-3 */
                                        class_description[(c_cid1 >> 4) & 0xf]);
 
@@ -1151,7 +1076,7 @@ static int dap_rom_display(struct command_context *cmd_ctx,
                        if (((c_cid1 >> 4) & 0x0f) == 9) {
                                uint32_t devtype;
                                unsigned minor;
-                               char *major = "Reserved", *subtype = "Reserved";
+                               const char *major = "Reserved", *subtype = "Reserved";
 
                                retval = mem_ap_read_atomic_u32(dap,
                                                (component_base & 0xfffff000) | 0xfcc,
@@ -1183,6 +1108,9 @@ static int dap_rom_display(struct command_context *cmd_ctx,
                                        case 2:
                                                subtype = "Buffer";
                                                break;
+                                       case 3:
+                                               subtype = "Router";
+                                               break;
                                        }
                                        break;
                                case 2:
@@ -1220,6 +1148,9 @@ static int dap_rom_display(struct command_context *cmd_ctx,
                                        case 4:
                                                subtype = "Bus";
                                                break;
+                                       case 6:
+                                               subtype = "Software";
+                                               break;
                                        }
                                        break;
                                case 4:
@@ -1234,6 +1165,9 @@ static int dap_rom_display(struct command_context *cmd_ctx,
                                        case 2:
                                                subtype = "Debug Auth";
                                                break;
+                                       case 3:
+                                               subtype = "Power Requestor";
+                                               break;
                                        }
                                        break;
                                case 5:
@@ -1251,11 +1185,40 @@ static int dap_rom_display(struct command_context *cmd_ctx,
                                        case 3:
                                                subtype = "Engine/Coprocessor";
                                                break;
+                                       case 4:
+                                               subtype = "Bus";
+                                               break;
+                                       case 5:
+                                               subtype = "Memory";
+                                               break;
+                                       }
+                                       break;
+                               case 6:
+                                       major = "Perfomance Monitor";
+                                       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;
+                                       case 5:
+                                               subtype = "Memory";
+                                               break;
                                        }
                                        break;
                                }
-                               command_print(cmd_ctx, "\t\tType is 0x%02x, %s, %s",
-                                               devtype & 0xff,
+                               command_print(cmd_ctx, "\t\tType is 0x%02" PRIx8 ", %s, %s",
+                                               (uint8_t)(devtype & 0xff),
                                                major, subtype);
                                /* REVISIT also show 0xfc8 DevId */
                        }
@@ -1301,6 +1264,18 @@ static int dap_rom_display(struct command_context *cmd_ctx,
                                type = "Cortex-M3 FBP";
                                full = "(Flash Patch and Breakpoint)";
                                break;
+                       case 0x008:
+                               type = "Cortex-M0 SCS";
+                               full = "(System Control Space)";
+                               break;
+                       case 0x00a:
+                               type = "Cortex-M0 DWT";
+                               full = "(Data Watchpoint and Trace)";
+                               break;
+                       case 0x00b:
+                               type = "Cortex-M0 BPU";
+                               full = "(Breakpoint Unit)";
+                               break;
                        case 0x00c:
                                type = "Cortex-M4 SCS";
                                full = "(System Control Space)";
@@ -1342,6 +1317,18 @@ static int dap_rom_display(struct command_context *cmd_ctx,
                                type = "Coresight ITM";
                                full = "(Instrumentation Trace Macrocell)";
                                break;
+                       case 0x914:
+                               type = "Coresight SWO";
+                               full = "(Single Wire Output)";
+                               break;
+                       case 0x917:
+                               type = "Coresight HTM";
+                               full = "(AHB Trace Macrocell)";
+                               break;
+                       case 0x920:
+                               type = "CoreSight ETM11";
+                               full = "(Embedded Trace)";
+                               break;
                        case 0x921:
                                type = "Cortex-A8 ETM";
                                full = "(Embedded Trace)";
@@ -1370,6 +1357,14 @@ static int dap_rom_display(struct command_context *cmd_ctx,
                                type = "CoreSight Component";
                                full = "(unidentified Cortex-A9 component)";
                                break;
+                       case 0x961:
+                               type = "CoreSight TMC";
+                               full = "(Trace Memory Controller)";
+                               break;
+                       case 0x962:
+                               type = "CoreSight STM";
+                               full = "(System Trace Macrocell)";
+                               break;
                        case 0x9a0:
                                type = "CoreSight PMU";
                                full = "(Performance Monitoring Unit)";
@@ -1378,6 +1373,14 @@ static int dap_rom_display(struct command_context *cmd_ctx,
                                type = "Cortex-M4 TPUI";
                                full = "(Trace Port Interface Unit)";
                                break;
+                       case 0x9a5:
+                               type = "Cortex-A5 ETM";
+                               full = "(Embedded Trace)";
+                               break;
+                       case 0xc05:
+                               type = "Cortex-A5 Debug";
+                               full = "(Debug Unit)";
+                               break;
                        case 0xc08:
                                type = "Cortex-A8 Debug";
                                full = "(Debug Unit)";
@@ -1386,7 +1389,12 @@ static int dap_rom_display(struct command_context *cmd_ctx,
                                type = "Cortex-A9 Debug";
                                full = "(Debug Unit)";
                                break;
+                       case 0x4af:
+                               type = "Cortex-A15 Debug";
+                               full = "(Debug Unit)";
+                               break;
                        default:
+                               LOG_DEBUG("Unrecognized Part number 0x%" PRIx32, part_num);
                                type = "-*- unrecognized -*-";
                                full = "";
                                break;
@@ -1415,7 +1423,7 @@ static int dap_info_command(struct command_context *cmd_ctx,
                struct adiv5_dap *dap, int ap)
 {
        int retval;
-       uint32_t dbgbase = 0, apid = 0; /* Silence gcc by initializing */
+       uint32_t dbgbase, apid;
        int romtable_present = 0;
        uint8_t mem_ap;
        uint32_t ap_old;
@@ -1424,7 +1432,7 @@ static int dap_info_command(struct command_context *cmd_ctx,
        if (retval != ERROR_OK)
                return retval;
 
-       ap_old = dap->ap_current;
+       ap_old = dap_ap_get_select(dap);
        dap_ap_select(dap, ap);
 
        /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec  */
@@ -1455,9 +1463,9 @@ static int dap_info_command(struct command_context *cmd_ctx,
                command_print(cmd_ctx, "No AP found at this ap 0x%x", ap);
 
        romtable_present = ((mem_ap) && (dbgbase != 0xFFFFFFFF));
-       if (romtable_present) {
+       if (romtable_present)
                dap_rom_display(cmd_ctx, dap, ap, dbgbase, 0);
-       else
+       else
                command_print(cmd_ctx, "\tNo ROM table present");
        dap_ap_select(dap, ap_old);
 
@@ -1515,7 +1523,7 @@ COMMAND_HANDLER(dap_baseaddr_command)
         * though they're not common for now.  This should
         * use the ID register to verify it's a MEM-AP.
         */
-       retval = dap_queue_ap_read(dap, AP_REG_BASE, &baseaddr);
+       retval = dap_queue_ap_read(dap, MEM_AP_REG_BASE, &baseaddr);
        if (retval != ERROR_OK)
                return retval;
        retval = dap_run(dap);
@@ -1537,7 +1545,7 @@ COMMAND_HANDLER(dap_memaccess_command)
 
        switch (CMD_ARGC) {
        case 0:
-               memaccess_tck = dap->memaccess_tck;
+               memaccess_tck = dap->ap[dap->apsel].memaccess_tck;
                break;
        case 1:
                COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], memaccess_tck);
@@ -1545,10 +1553,10 @@ COMMAND_HANDLER(dap_memaccess_command)
        default:
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
-       dap->memaccess_tck = memaccess_tck;
+       dap->ap[dap->apsel].memaccess_tck = memaccess_tck;
 
        command_print(CMD_CTX, "memory bus access delay set to %" PRIi32 " tck",
-                       dap->memaccess_tck);
+                       dap->ap[dap->apsel].memaccess_tck);
 
        return ERROR_OK;
 }
@@ -1598,7 +1606,7 @@ COMMAND_HANDLER(dap_apcsw_command)
        struct arm *arm = target_to_arm(target);
        struct adiv5_dap *dap = arm->dap;
 
-       uint32_t apcsw = dap->apcsw[dap->apsel], sprot = 0;
+       uint32_t apcsw = dap->ap[dap->apsel].csw_default, sprot = 0;
 
        switch (CMD_ARGC) {
        case 0:
@@ -1618,7 +1626,7 @@ COMMAND_HANDLER(dap_apcsw_command)
        default:
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
-       dap->apcsw[dap->apsel] = apcsw;
+       dap->ap[dap->apsel].csw_default = apcsw;
 
        return 0;
 }
@@ -1662,6 +1670,32 @@ COMMAND_HANDLER(dap_apid_command)
        return retval;
 }
 
+COMMAND_HANDLER(dap_ti_be_32_quirks_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct arm *arm = target_to_arm(target);
+       struct adiv5_dap *dap = arm->dap;
+
+       uint32_t enable = dap->ti_be_32_quirks;
+
+       switch (CMD_ARGC) {
+       case 0:
+               break;
+       case 1:
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], enable);
+               if (enable > 1)
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               break;
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+       dap->ti_be_32_quirks = enable;
+       command_print(CMD_CTX, "TI BE-32 quirks mode %s",
+               enable ? "enabled" : "disabled");
+
+       return 0;
+}
+
 static const struct command_registration dap_commands[] = {
        {
                .name = "info",
@@ -1711,6 +1745,13 @@ static const struct command_registration dap_commands[] = {
                        "bus access [0-255]",
                .usage = "[cycles]",
        },
+       {
+               .name = "ti_be_32_quirks",
+               .handler = dap_ti_be_32_quirks_command,
+               .mode = COMMAND_CONFIG,
+               .help = "set/get quirks mode for TI TMS450/TMS570 processors",
+               .usage = "[enable]",
+       },
        COMMAND_REGISTRATION_DONE
 };