arm_adi: -Wshadow warning fix
[openocd.git] / src / target / arm_adi_v5.c
1 /***************************************************************************
2 * Copyright (C) 2006 by Magnus Lundin *
3 * lundin@mlu.mine.nu *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * Copyright (C) 2009 by Oyvind Harboe *
9 * oyvind.harboe@zylin.com *
10 * *
11 * Copyright (C) 2009-2010 by David Brownell *
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 * This program is distributed in the hope that it will be useful, *
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21 * GNU General Public License for more details. *
22 * *
23 * You should have received a copy of the GNU General Public License *
24 * along with this program; if not, write to the *
25 * Free Software Foundation, Inc., *
26 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
27 ***************************************************************************/
28
29 /**
30 * @file
31 * This file implements support for the ARM Debug Interface version 5 (ADIv5)
32 * debugging architecture. Compared with previous versions, this includes
33 * a low pin-count Serial Wire Debug (SWD) alternative to JTAG for message
34 * transport, and focusses on memory mapped resources as defined by the
35 * CoreSight architecture.
36 *
37 * A key concept in ADIv5 is the Debug Access Port, or DAP. A DAP has two
38 * basic components: a Debug Port (DP) transporting messages to and from a
39 * debugger, and an Access Port (AP) accessing resources. Three types of DP
40 * are defined. One uses only JTAG for communication, and is called JTAG-DP.
41 * One uses only SWD for communication, and is called SW-DP. The third can
42 * use either SWD or JTAG, and is called SWJ-DP. The most common type of AP
43 * is used to access memory mapped resources and is called a MEM-AP. Also a
44 * JTAG-AP is also defined, bridging to JTAG resources; those are uncommon.
45 *
46 * This programming interface allows DAP pipelined operations through a
47 * transaction queue. This primarily affects AP operations (such as using
48 * a MEM-AP to access memory or registers). If the current transaction has
49 * not finished by the time the next one must begin, and the ORUNDETECT bit
50 * is set in the DP_CTRL_STAT register, the SSTICKYORUN status is set and
51 * further AP operations will fail. There are two basic methods to avoid
52 * such overrun errors. One involves polling for status instead of using
53 * transaction piplining. The other involves adding delays to ensure the
54 * AP has enough time to complete one operation before starting the next
55 * one. (For JTAG these delays are controlled by memaccess_tck.)
56 */
57
58 /*
59 * Relevant specifications from ARM include:
60 *
61 * ARM(tm) Debug Interface v5 Architecture Specification ARM IHI 0031A
62 * CoreSight(tm) v1.0 Architecture Specification ARM IHI 0029B
63 *
64 * CoreSight(tm) DAP-Lite TRM, ARM DDI 0316D
65 * Cortex-M3(tm) TRM, ARM DDI 0337G
66 */
67
68 #ifdef HAVE_CONFIG_H
69 #include "config.h"
70 #endif
71
72 #include "arm.h"
73 #include "arm_adi_v5.h"
74 #include <helper/time_support.h>
75
76
77 /* ARM ADI Specification requires at least 10 bits used for TAR autoincrement */
78
79 /*
80 uint32_t tar_block_size(uint32_t address)
81 Return the largest block starting at address that does not cross a tar block size alignment boundary
82 */
83 static uint32_t max_tar_block_size(uint32_t tar_autoincr_block, uint32_t address)
84 {
85 return (tar_autoincr_block - ((tar_autoincr_block - 1) & address)) >> 2;
86 }
87
88 /***************************************************************************
89 * *
90 * DP and MEM-AP register access through APACC and DPACC *
91 * *
92 ***************************************************************************/
93
94 /**
95 * Select one of the APs connected to the specified DAP. The
96 * selection is implicitly used with future AP transactions.
97 * This is a NOP if the specified AP is already selected.
98 *
99 * @param dap The DAP
100 * @param apsel Number of the AP to (implicitly) use with further
101 * transactions. This normally identifies a MEM-AP.
102 */
103 void dap_ap_select(struct adiv5_dap *dap,uint8_t apsel)
104 {
105 uint32_t select_apsel = (apsel << 24) & 0xFF000000;
106
107 if (select_apsel != dap->apsel)
108 {
109 dap->apsel = select_apsel;
110 /* Switching AP invalidates cached values.
111 * Values MUST BE UPDATED BEFORE AP ACCESS.
112 */
113 dap->ap_bank_value = -1;
114 dap->ap_csw_value = -1;
115 dap->ap_tar_value = -1;
116 }
117 }
118
119 /**
120 * Queue transactions setting up transfer parameters for the
121 * currently selected MEM-AP.
122 *
123 * Subsequent transfers using registers like AP_REG_DRW or AP_REG_BD2
124 * initiate data reads or writes using memory or peripheral addresses.
125 * If the CSW is configured for it, the TAR may be automatically
126 * incremented after each transfer.
127 *
128 * @todo Rename to reflect it being specifically a MEM-AP function.
129 *
130 * @param dap The DAP connected to the MEM-AP.
131 * @param csw MEM-AP Control/Status Word (CSW) register to assign. If this
132 * matches the cached value, the register is not changed.
133 * @param tar MEM-AP Transfer Address Register (TAR) to assign. If this
134 * matches the cached address, the register is not changed.
135 *
136 * @return ERROR_OK if the transaction was properly queued, else a fault code.
137 */
138 int dap_setup_accessport(struct adiv5_dap *dap, uint32_t csw, uint32_t tar)
139 {
140 int retval;
141
142 csw = csw | CSW_DBGSWENABLE | CSW_MASTER_DEBUG | CSW_HPROT;
143 if (csw != dap->ap_csw_value)
144 {
145 /* LOG_DEBUG("DAP: Set CSW %x",csw); */
146 retval = dap_queue_ap_write(dap, AP_REG_CSW, csw);
147 if (retval != ERROR_OK)
148 return retval;
149 dap->ap_csw_value = csw;
150 }
151 if (tar != dap->ap_tar_value)
152 {
153 /* LOG_DEBUG("DAP: Set TAR %x",tar); */
154 retval = dap_queue_ap_write(dap, AP_REG_TAR, tar);
155 if (retval != ERROR_OK)
156 return retval;
157 dap->ap_tar_value = tar;
158 }
159 /* Disable TAR cache when autoincrementing */
160 if (csw & CSW_ADDRINC_MASK)
161 dap->ap_tar_value = -1;
162 return ERROR_OK;
163 }
164
165 /**
166 * Asynchronous (queued) read of a word from memory or a system register.
167 *
168 * @param dap The DAP connected to the MEM-AP performing the read.
169 * @param address Address of the 32-bit word to read; it must be
170 * readable by the currently selected MEM-AP.
171 * @param value points to where the word will be stored when the
172 * transaction queue is flushed (assuming no errors).
173 *
174 * @return ERROR_OK for success. Otherwise a fault code.
175 */
176 int mem_ap_read_u32(struct adiv5_dap *dap, uint32_t address,
177 uint32_t *value)
178 {
179 int retval;
180
181 /* Use banked addressing (REG_BDx) to avoid some link traffic
182 * (updating TAR) when reading several consecutive addresses.
183 */
184 retval = dap_setup_accessport(dap, CSW_32BIT | CSW_ADDRINC_OFF,
185 address & 0xFFFFFFF0);
186 if (retval != ERROR_OK)
187 return retval;
188
189 return dap_queue_ap_read(dap, AP_REG_BD0 | (address & 0xC), value);
190 }
191
192 /**
193 * Synchronous read of a word from memory or a system register.
194 * As a side effect, this flushes any queued transactions.
195 *
196 * @param dap The DAP connected to the MEM-AP performing the read.
197 * @param address Address of the 32-bit word to read; it must be
198 * readable by the currently selected MEM-AP.
199 * @param value points to where the result will be stored.
200 *
201 * @return ERROR_OK for success; *value holds the result.
202 * Otherwise a fault code.
203 */
204 int mem_ap_read_atomic_u32(struct adiv5_dap *dap, uint32_t address,
205 uint32_t *value)
206 {
207 int retval;
208
209 retval = mem_ap_read_u32(dap, address, value);
210 if (retval != ERROR_OK)
211 return retval;
212
213 return dap_run(dap);
214 }
215
216 /**
217 * Asynchronous (queued) write of a word to memory or a system register.
218 *
219 * @param dap The DAP connected to the MEM-AP.
220 * @param address Address to be written; it must be writable by
221 * the currently selected MEM-AP.
222 * @param value Word that will be written to the address when transaction
223 * queue is flushed (assuming no errors).
224 *
225 * @return ERROR_OK for success. Otherwise a fault code.
226 */
227 int mem_ap_write_u32(struct adiv5_dap *dap, uint32_t address,
228 uint32_t value)
229 {
230 int retval;
231
232 /* Use banked addressing (REG_BDx) to avoid some link traffic
233 * (updating TAR) when writing several consecutive addresses.
234 */
235 retval = dap_setup_accessport(dap, CSW_32BIT | CSW_ADDRINC_OFF,
236 address & 0xFFFFFFF0);
237 if (retval != ERROR_OK)
238 return retval;
239
240 return dap_queue_ap_write(dap, AP_REG_BD0 | (address & 0xC),
241 value);
242 }
243
244 /**
245 * Synchronous write of a word to memory or a system register.
246 * As a side effect, this flushes any queued transactions.
247 *
248 * @param dap The DAP connected to the MEM-AP.
249 * @param address Address to be written; it must be writable by
250 * the currently selected MEM-AP.
251 * @param value Word that will be written.
252 *
253 * @return ERROR_OK for success; the data was written. Otherwise a fault code.
254 */
255 int mem_ap_write_atomic_u32(struct adiv5_dap *dap, uint32_t address,
256 uint32_t value)
257 {
258 int retval = mem_ap_write_u32(dap, address, value);
259
260 if (retval != ERROR_OK)
261 return retval;
262
263 return dap_run(dap);
264 }
265
266 /*****************************************************************************
267 * *
268 * mem_ap_write_buf(struct adiv5_dap *dap, uint8_t *buffer, int count, uint32_t address) *
269 * *
270 * Write a buffer in target order (little endian) *
271 * *
272 *****************************************************************************/
273 int mem_ap_write_buf_u32(struct adiv5_dap *dap, uint8_t *buffer, int count, uint32_t address)
274 {
275 int wcount, blocksize, writecount, errorcount = 0, retval = ERROR_OK;
276 uint32_t adr = address;
277 uint8_t* pBuffer = buffer;
278
279 count >>= 2;
280 wcount = count;
281
282 /* if we have an unaligned access - reorder data */
283 if (adr & 0x3u)
284 {
285 for (writecount = 0; writecount < count; writecount++)
286 {
287 int i;
288 uint32_t outvalue;
289 memcpy(&outvalue, pBuffer, sizeof(uint32_t));
290
291 for (i = 0; i < 4; i++)
292 {
293 *((uint8_t*)pBuffer + (adr & 0x3)) = outvalue;
294 outvalue >>= 8;
295 adr++;
296 }
297 pBuffer += sizeof(uint32_t);
298 }
299 }
300
301 while (wcount > 0)
302 {
303 /* Adjust to write blocks within boundaries aligned to the TAR autoincremnent size*/
304 blocksize = max_tar_block_size(dap->tar_autoincr_block, address);
305 if (wcount < blocksize)
306 blocksize = wcount;
307
308 /* handle unaligned data at 4k boundary */
309 if (blocksize == 0)
310 blocksize = 1;
311
312 dap_setup_accessport(dap, CSW_32BIT | CSW_ADDRINC_SINGLE, address);
313
314 for (writecount = 0; writecount < blocksize; writecount++)
315 {
316 retval = dap_queue_ap_write(dap, AP_REG_DRW,
317 *(uint32_t *) (buffer + 4 * writecount));
318 if (retval != ERROR_OK)
319 break;
320 }
321
322 if (dap_run(dap) == ERROR_OK)
323 {
324 wcount = wcount - blocksize;
325 address = address + 4 * blocksize;
326 buffer = buffer + 4 * blocksize;
327 }
328 else
329 {
330 errorcount++;
331 }
332
333 if (errorcount > 1)
334 {
335 LOG_WARNING("Block write error address 0x%" PRIx32 ", wcount 0x%x", address, wcount);
336 /* REVISIT return the *actual* fault code */
337 return ERROR_JTAG_DEVICE_ERROR;
338 }
339 }
340
341 return retval;
342 }
343
344 static int mem_ap_write_buf_packed_u16(struct adiv5_dap *dap,
345 uint8_t *buffer, int count, uint32_t address)
346 {
347 int retval = ERROR_OK;
348 int wcount, blocksize, writecount, i;
349
350 wcount = count >> 1;
351
352 while (wcount > 0)
353 {
354 int nbytes;
355
356 /* Adjust to write blocks within boundaries aligned to the TAR autoincremnent size*/
357 blocksize = max_tar_block_size(dap->tar_autoincr_block, address);
358
359 if (wcount < blocksize)
360 blocksize = wcount;
361
362 /* handle unaligned data at 4k boundary */
363 if (blocksize == 0)
364 blocksize = 1;
365
366 dap_setup_accessport(dap, CSW_16BIT | CSW_ADDRINC_PACKED, address);
367 writecount = blocksize;
368
369 do
370 {
371 nbytes = MIN((writecount << 1), 4);
372
373 if (nbytes < 4)
374 {
375 if (mem_ap_write_buf_u16(dap, buffer,
376 nbytes, address) != ERROR_OK)
377 {
378 LOG_WARNING("Block write error address "
379 "0x%" PRIx32 ", count 0x%x",
380 address, count);
381 return ERROR_JTAG_DEVICE_ERROR;
382 }
383
384 address += nbytes >> 1;
385 }
386 else
387 {
388 uint32_t outvalue;
389 memcpy(&outvalue, buffer, sizeof(uint32_t));
390
391 for (i = 0; i < nbytes; i++)
392 {
393 *((uint8_t*)buffer + (address & 0x3)) = outvalue;
394 outvalue >>= 8;
395 address++;
396 }
397
398 memcpy(&outvalue, buffer, sizeof(uint32_t));
399 retval = dap_queue_ap_write(dap,
400 AP_REG_DRW, outvalue);
401 if (retval != ERROR_OK)
402 break;
403
404 if (dap_run(dap) != ERROR_OK)
405 {
406 LOG_WARNING("Block write error address "
407 "0x%" PRIx32 ", count 0x%x",
408 address, count);
409 /* REVISIT return *actual* fault code */
410 return ERROR_JTAG_DEVICE_ERROR;
411 }
412 }
413
414 buffer += nbytes >> 1;
415 writecount -= nbytes >> 1;
416
417 } while (writecount);
418 wcount -= blocksize;
419 }
420
421 return retval;
422 }
423
424 int mem_ap_write_buf_u16(struct adiv5_dap *dap, uint8_t *buffer, int count, uint32_t address)
425 {
426 int retval = ERROR_OK;
427
428 if (count >= 4)
429 return mem_ap_write_buf_packed_u16(dap, buffer, count, address);
430
431 while (count > 0)
432 {
433 dap_setup_accessport(dap, CSW_16BIT | CSW_ADDRINC_SINGLE, address);
434 uint16_t svalue;
435 memcpy(&svalue, buffer, sizeof(uint16_t));
436 uint32_t outvalue = (uint32_t)svalue << 8 * (address & 0x3);
437 retval = dap_queue_ap_write(dap, AP_REG_DRW, outvalue);
438 if (retval != ERROR_OK)
439 break;
440
441 retval = dap_run(dap);
442 if (retval != ERROR_OK)
443 break;
444
445 count -= 2;
446 address += 2;
447 buffer += 2;
448 }
449
450 return retval;
451 }
452
453 static int mem_ap_write_buf_packed_u8(struct adiv5_dap *dap,
454 uint8_t *buffer, int count, uint32_t address)
455 {
456 int retval = ERROR_OK;
457 int wcount, blocksize, writecount, i;
458
459 wcount = count;
460
461 while (wcount > 0)
462 {
463 int nbytes;
464
465 /* Adjust to write blocks within boundaries aligned to the TAR autoincremnent size*/
466 blocksize = max_tar_block_size(dap->tar_autoincr_block, address);
467
468 if (wcount < blocksize)
469 blocksize = wcount;
470
471 dap_setup_accessport(dap, CSW_8BIT | CSW_ADDRINC_PACKED, address);
472 writecount = blocksize;
473
474 do
475 {
476 nbytes = MIN(writecount, 4);
477
478 if (nbytes < 4)
479 {
480 if (mem_ap_write_buf_u8(dap, buffer, nbytes, address) != ERROR_OK)
481 {
482 LOG_WARNING("Block write error address "
483 "0x%" PRIx32 ", count 0x%x",
484 address, count);
485 return ERROR_JTAG_DEVICE_ERROR;
486 }
487
488 address += nbytes;
489 }
490 else
491 {
492 uint32_t outvalue;
493 memcpy(&outvalue, buffer, sizeof(uint32_t));
494
495 for (i = 0; i < nbytes; i++)
496 {
497 *((uint8_t*)buffer + (address & 0x3)) = outvalue;
498 outvalue >>= 8;
499 address++;
500 }
501
502 memcpy(&outvalue, buffer, sizeof(uint32_t));
503 retval = dap_queue_ap_write(dap,
504 AP_REG_DRW, outvalue);
505 if (retval != ERROR_OK)
506 break;
507
508 if (dap_run(dap) != ERROR_OK)
509 {
510 LOG_WARNING("Block write error address "
511 "0x%" PRIx32 ", count 0x%x",
512 address, count);
513 /* REVISIT return *actual* fault code */
514 return ERROR_JTAG_DEVICE_ERROR;
515 }
516 }
517
518 buffer += nbytes;
519 writecount -= nbytes;
520
521 } while (writecount);
522 wcount -= blocksize;
523 }
524
525 return retval;
526 }
527
528 int mem_ap_write_buf_u8(struct adiv5_dap *dap, uint8_t *buffer, int count, uint32_t address)
529 {
530 int retval = ERROR_OK;
531
532 if (count >= 4)
533 return mem_ap_write_buf_packed_u8(dap, buffer, count, address);
534
535 while (count > 0)
536 {
537 dap_setup_accessport(dap, CSW_8BIT | CSW_ADDRINC_SINGLE, address);
538 uint32_t outvalue = (uint32_t)*buffer << 8 * (address & 0x3);
539 retval = dap_queue_ap_write(dap, AP_REG_DRW, outvalue);
540 if (retval != ERROR_OK)
541 break;
542
543 retval = dap_run(dap);
544 if (retval != ERROR_OK)
545 break;
546
547 count--;
548 address++;
549 buffer++;
550 }
551
552 return retval;
553 }
554
555 /* FIXME don't import ... this is a temporary workaround for the
556 * mem_ap_read_buf_u32() mess, until it's no longer JTAG-specific.
557 */
558 extern int adi_jtag_dp_scan(struct adiv5_dap *dap,
559 uint8_t instr, uint8_t reg_addr, uint8_t RnW,
560 uint8_t *outvalue, uint8_t *invalue, uint8_t *ack);
561
562 /**
563 * Synchronously read a block of 32-bit words into a buffer
564 * @param dap The DAP connected to the MEM-AP.
565 * @param buffer where the words will be stored (in host byte order).
566 * @param count How many words to read.
567 * @param address Memory address from which to read words; all the
568 * words must be readable by the currently selected MEM-AP.
569 */
570 int mem_ap_read_buf_u32(struct adiv5_dap *dap, uint8_t *buffer,
571 int count, uint32_t address)
572 {
573 int wcount, blocksize, readcount, errorcount = 0, retval = ERROR_OK;
574 uint32_t adr = address;
575 uint8_t* pBuffer = buffer;
576
577 count >>= 2;
578 wcount = count;
579
580 while (wcount > 0)
581 {
582 /* Adjust to read blocks within boundaries aligned to the
583 * TAR autoincrement size (at least 2^10). Autoincrement
584 * mode avoids an extra per-word roundtrip to update TAR.
585 */
586 blocksize = max_tar_block_size(dap->tar_autoincr_block,
587 address);
588 if (wcount < blocksize)
589 blocksize = wcount;
590
591 /* handle unaligned data at 4k boundary */
592 if (blocksize == 0)
593 blocksize = 1;
594
595 dap_setup_accessport(dap, CSW_32BIT | CSW_ADDRINC_SINGLE,
596 address);
597
598 /* FIXME remove these three calls to adi_jtag_dp_scan(),
599 * so this routine becomes transport-neutral. Be careful
600 * not to cause performance problems with JTAG; would it
601 * suffice to loop over dap_queue_ap_read(), or would that
602 * be slower when JTAG is the chosen transport?
603 */
604
605 /* Scan out first read */
606 adi_jtag_dp_scan(dap, JTAG_DP_APACC, AP_REG_DRW,
607 DPAP_READ, 0, NULL, NULL);
608 for (readcount = 0; readcount < blocksize - 1; readcount++)
609 {
610 /* Scan out next read; scan in posted value for the
611 * previous one. Assumes read is acked "OK/FAULT",
612 * and CTRL_STAT says that meant "OK".
613 */
614 adi_jtag_dp_scan(dap, JTAG_DP_APACC, AP_REG_DRW,
615 DPAP_READ, 0, buffer + 4 * readcount,
616 &dap->ack);
617 }
618
619 /* Scan in last posted value; RDBUFF has no other effect,
620 * assuming ack is OK/FAULT and CTRL_STAT says "OK".
621 */
622 adi_jtag_dp_scan(dap, JTAG_DP_DPACC, DP_RDBUFF,
623 DPAP_READ, 0, buffer + 4 * readcount,
624 &dap->ack);
625 if (dap_run(dap) == ERROR_OK)
626 {
627 wcount = wcount - blocksize;
628 address += 4 * blocksize;
629 buffer += 4 * blocksize;
630 }
631 else
632 {
633 errorcount++;
634 }
635
636 if (errorcount > 1)
637 {
638 LOG_WARNING("Block read error address 0x%" PRIx32
639 ", count 0x%x", address, count);
640 /* REVISIT return the *actual* fault code */
641 return ERROR_JTAG_DEVICE_ERROR;
642 }
643 }
644
645 /* if we have an unaligned access - reorder data */
646 if (adr & 0x3u)
647 {
648 for (readcount = 0; readcount < count; readcount++)
649 {
650 int i;
651 uint32_t data;
652 memcpy(&data, pBuffer, sizeof(uint32_t));
653
654 for (i = 0; i < 4; i++)
655 {
656 *((uint8_t*)pBuffer) =
657 (data >> 8 * (adr & 0x3));
658 pBuffer++;
659 adr++;
660 }
661 }
662 }
663
664 return retval;
665 }
666
667 static int mem_ap_read_buf_packed_u16(struct adiv5_dap *dap,
668 uint8_t *buffer, int count, uint32_t address)
669 {
670 uint32_t invalue;
671 int retval = ERROR_OK;
672 int wcount, blocksize, readcount, i;
673
674 wcount = count >> 1;
675
676 while (wcount > 0)
677 {
678 int nbytes;
679
680 /* Adjust to read blocks within boundaries aligned to the TAR autoincremnent size*/
681 blocksize = max_tar_block_size(dap->tar_autoincr_block, address);
682 if (wcount < blocksize)
683 blocksize = wcount;
684
685 dap_setup_accessport(dap, CSW_16BIT | CSW_ADDRINC_PACKED, address);
686
687 /* handle unaligned data at 4k boundary */
688 if (blocksize == 0)
689 blocksize = 1;
690 readcount = blocksize;
691
692 do
693 {
694 retval = dap_queue_ap_read(dap, AP_REG_DRW, &invalue);
695 if (dap_run(dap) != ERROR_OK)
696 {
697 LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count);
698 /* REVISIT return the *actual* fault code */
699 return ERROR_JTAG_DEVICE_ERROR;
700 }
701
702 nbytes = MIN((readcount << 1), 4);
703
704 for (i = 0; i < nbytes; i++)
705 {
706 *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
707 buffer++;
708 address++;
709 }
710
711 readcount -= (nbytes >> 1);
712 } while (readcount);
713 wcount -= blocksize;
714 }
715
716 return retval;
717 }
718
719 /**
720 * Synchronously read a block of 16-bit halfwords into a buffer
721 * @param dap The DAP connected to the MEM-AP.
722 * @param buffer where the halfwords will be stored (in host byte order).
723 * @param count How many halfwords to read.
724 * @param address Memory address from which to read words; all the
725 * words must be readable by the currently selected MEM-AP.
726 */
727 int mem_ap_read_buf_u16(struct adiv5_dap *dap, uint8_t *buffer,
728 int count, uint32_t address)
729 {
730 uint32_t invalue, i;
731 int retval = ERROR_OK;
732
733 if (count >= 4)
734 return mem_ap_read_buf_packed_u16(dap, buffer, count, address);
735
736 while (count > 0)
737 {
738 dap_setup_accessport(dap, CSW_16BIT | CSW_ADDRINC_SINGLE, address);
739 retval = dap_queue_ap_read(dap, AP_REG_DRW, &invalue);
740 if (retval != ERROR_OK)
741 break;
742
743 retval = dap_run(dap);
744 if (retval != ERROR_OK)
745 break;
746
747 if (address & 0x1)
748 {
749 for (i = 0; i < 2; i++)
750 {
751 *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
752 buffer++;
753 address++;
754 }
755 }
756 else
757 {
758 uint16_t svalue = (invalue >> 8 * (address & 0x3));
759 memcpy(buffer, &svalue, sizeof(uint16_t));
760 address += 2;
761 buffer += 2;
762 }
763 count -= 2;
764 }
765
766 return retval;
767 }
768
769 /* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many
770 * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s?
771 *
772 * The solution is to arrange for a large out/in scan in this loop and
773 * and convert data afterwards.
774 */
775 static int mem_ap_read_buf_packed_u8(struct adiv5_dap *dap,
776 uint8_t *buffer, int count, uint32_t address)
777 {
778 uint32_t invalue;
779 int retval = ERROR_OK;
780 int wcount, blocksize, readcount, i;
781
782 wcount = count;
783
784 while (wcount > 0)
785 {
786 int nbytes;
787
788 /* Adjust to read blocks within boundaries aligned to the TAR autoincremnent size*/
789 blocksize = max_tar_block_size(dap->tar_autoincr_block, address);
790
791 if (wcount < blocksize)
792 blocksize = wcount;
793
794 dap_setup_accessport(dap, CSW_8BIT | CSW_ADDRINC_PACKED, address);
795 readcount = blocksize;
796
797 do
798 {
799 retval = dap_queue_ap_read(dap, AP_REG_DRW, &invalue);
800 if (dap_run(dap) != ERROR_OK)
801 {
802 LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count);
803 /* REVISIT return the *actual* fault code */
804 return ERROR_JTAG_DEVICE_ERROR;
805 }
806
807 nbytes = MIN(readcount, 4);
808
809 for (i = 0; i < nbytes; i++)
810 {
811 *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
812 buffer++;
813 address++;
814 }
815
816 readcount -= nbytes;
817 } while (readcount);
818 wcount -= blocksize;
819 }
820
821 return retval;
822 }
823
824 /**
825 * Synchronously read a block of bytes into a buffer
826 * @param dap The DAP connected to the MEM-AP.
827 * @param buffer where the bytes will be stored.
828 * @param count How many bytes to read.
829 * @param address Memory address from which to read data; all the
830 * data must be readable by the currently selected MEM-AP.
831 */
832 int mem_ap_read_buf_u8(struct adiv5_dap *dap, uint8_t *buffer,
833 int count, uint32_t address)
834 {
835 uint32_t invalue;
836 int retval = ERROR_OK;
837
838 if (count >= 4)
839 return mem_ap_read_buf_packed_u8(dap, buffer, count, address);
840
841 while (count > 0)
842 {
843 dap_setup_accessport(dap, CSW_8BIT | CSW_ADDRINC_SINGLE, address);
844 retval = dap_queue_ap_read(dap, AP_REG_DRW, &invalue);
845 retval = dap_run(dap);
846 if (retval != ERROR_OK)
847 break;
848
849 *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
850 count--;
851 address++;
852 buffer++;
853 }
854
855 return retval;
856 }
857
858 /*--------------------------------------------------------------------------*/
859
860
861 /* FIXME don't import ... just initialize as
862 * part of DAP transport setup
863 */
864 extern const struct dap_ops jtag_dp_ops;
865
866 /*--------------------------------------------------------------------------*/
867
868 /**
869 * Initialize a DAP. This sets up the power domains, prepares the DP
870 * for further use, and arranges to use AP #0 for all AP operations
871 * until dap_ap-select() changes that policy.
872 *
873 * @param dap The DAP being initialized.
874 *
875 * @todo Rename this. We also need an initialization scheme which account
876 * for SWD transports not just JTAG; that will need to address differences
877 * in layering. (JTAG is useful without any debug target; but not SWD.)
878 * And this may not even use an AHB-AP ... e.g. DAP-Lite uses an APB-AP.
879 */
880 int ahbap_debugport_init(struct adiv5_dap *dap)
881 {
882 uint32_t idreg, romaddr, dummy;
883 uint32_t ctrlstat;
884 int cnt = 0;
885 int retval;
886
887 LOG_DEBUG(" ");
888
889 /* JTAG-DP or SWJ-DP, in JTAG mode */
890 dap->ops = &jtag_dp_ops;
891
892 /* Default MEM-AP setup.
893 *
894 * REVISIT AP #0 may be an inappropriate default for this.
895 * Should we probe, or take a hint from the caller?
896 * Presumably we can ignore the possibility of multiple APs.
897 */
898 dap->apsel = !0;
899 dap_ap_select(dap, 0);
900
901 /* DP initialization */
902
903 retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &dummy);
904 if (retval != ERROR_OK)
905 return retval;
906
907 retval = dap_queue_dp_write(dap, DP_CTRL_STAT, SSTICKYERR);
908 if (retval != ERROR_OK)
909 return retval;
910
911 retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &dummy);
912 if (retval != ERROR_OK)
913 return retval;
914
915 dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ;
916 retval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat);
917 if (retval != ERROR_OK)
918 return retval;
919
920 retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat);
921 if (retval != ERROR_OK)
922 return retval;
923 if ((retval = dap_run(dap)) != ERROR_OK)
924 return retval;
925
926 /* Check that we have debug power domains activated */
927 while (!(ctrlstat & CDBGPWRUPACK) && (cnt++ < 10))
928 {
929 LOG_DEBUG("DAP: wait CDBGPWRUPACK");
930 retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat);
931 if (retval != ERROR_OK)
932 return retval;
933 if ((retval = dap_run(dap)) != ERROR_OK)
934 return retval;
935 alive_sleep(10);
936 }
937
938 while (!(ctrlstat & CSYSPWRUPACK) && (cnt++ < 10))
939 {
940 LOG_DEBUG("DAP: wait CSYSPWRUPACK");
941 retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat);
942 if (retval != ERROR_OK)
943 return retval;
944 if ((retval = dap_run(dap)) != ERROR_OK)
945 return retval;
946 alive_sleep(10);
947 }
948
949 retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &dummy);
950 if (retval != ERROR_OK)
951 return retval;
952 /* With debug power on we can activate OVERRUN checking */
953 dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ | CORUNDETECT;
954 retval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat);
955 if (retval != ERROR_OK)
956 return retval;
957 retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &dummy);
958 if (retval != ERROR_OK)
959 return retval;
960
961 /*
962 * REVISIT this isn't actually *initializing* anything in an AP,
963 * and doesn't care if it's a MEM-AP at all (much less AHB-AP).
964 * Should it? If the ROM address is valid, is this the right
965 * place to scan the table and do any topology detection?
966 */
967 retval = dap_queue_ap_read(dap, AP_REG_IDR, &idreg);
968 retval = dap_queue_ap_read(dap, AP_REG_BASE, &romaddr);
969
970 if ((retval = dap_run(dap)) != ERROR_OK)
971 return retval;
972
973 LOG_DEBUG("MEM-AP #%" PRId32 " ID Register 0x%" PRIx32
974 ", Debug ROM Address 0x%" PRIx32,
975 dap->apsel, idreg, romaddr);
976
977 return ERROR_OK;
978 }
979
980 /* CID interpretation -- see ARM IHI 0029B section 3
981 * and ARM IHI 0031A table 13-3.
982 */
983 static const char *class_description[16] ={
984 "Reserved", "ROM table", "Reserved", "Reserved",
985 "Reserved", "Reserved", "Reserved", "Reserved",
986 "Reserved", "CoreSight component", "Reserved", "Peripheral Test Block",
987 "Reserved", "OptimoDE DESS",
988 "Generic IP component", "PrimeCell or System component"
989 };
990
991 static bool
992 is_dap_cid_ok(uint32_t cid3, uint32_t cid2, uint32_t cid1, uint32_t cid0)
993 {
994 return cid3 == 0xb1 && cid2 == 0x05
995 && ((cid1 & 0x0f) == 0) && cid0 == 0x0d;
996 }
997
998 static int dap_info_command(struct command_context *cmd_ctx,
999 struct adiv5_dap *dap, int apsel)
1000 {
1001 int retval;
1002 uint32_t dbgbase, apid;
1003 int romtable_present = 0;
1004 uint8_t mem_ap;
1005 uint32_t apselold;
1006
1007 /* AP address is in bits 31:24 of DP_SELECT */
1008 if (apsel >= 256)
1009 return ERROR_INVALID_ARGUMENTS;
1010
1011 apselold = dap->apsel;
1012 dap_ap_select(dap, apsel);
1013 retval = dap_queue_ap_read(dap, AP_REG_BASE, &dbgbase);
1014 retval = dap_queue_ap_read(dap, AP_REG_IDR, &apid);
1015 retval = dap_run(dap);
1016 if (retval != ERROR_OK)
1017 return retval;
1018
1019 /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */
1020 mem_ap = ((apid&0x10000) && ((apid&0x0F) != 0));
1021 command_print(cmd_ctx, "AP ID register 0x%8.8" PRIx32, apid);
1022 if (apid)
1023 {
1024 switch (apid&0x0F)
1025 {
1026 case 0:
1027 command_print(cmd_ctx, "\tType is JTAG-AP");
1028 break;
1029 case 1:
1030 command_print(cmd_ctx, "\tType is MEM-AP AHB");
1031 break;
1032 case 2:
1033 command_print(cmd_ctx, "\tType is MEM-AP APB");
1034 break;
1035 default:
1036 command_print(cmd_ctx, "\tUnknown AP type");
1037 break;
1038 }
1039
1040 /* NOTE: a MEM-AP may have a single CoreSight component that's
1041 * not a ROM table ... or have no such components at all.
1042 */
1043 if (mem_ap)
1044 command_print(cmd_ctx, "AP BASE 0x%8.8" PRIx32,
1045 dbgbase);
1046 }
1047 else
1048 {
1049 command_print(cmd_ctx, "No AP found at this apsel 0x%x", apsel);
1050 }
1051
1052 romtable_present = ((mem_ap) && (dbgbase != 0xFFFFFFFF));
1053 if (romtable_present)
1054 {
1055 uint32_t cid0,cid1,cid2,cid3,memtype,romentry;
1056 uint16_t entry_offset;
1057
1058 /* bit 16 of apid indicates a memory access port */
1059 if (dbgbase & 0x02)
1060 command_print(cmd_ctx, "\tValid ROM table present");
1061 else
1062 command_print(cmd_ctx, "\tROM table in legacy format");
1063
1064 /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */
1065 mem_ap_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFF0, &cid0);
1066 mem_ap_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFF4, &cid1);
1067 mem_ap_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFF8, &cid2);
1068 mem_ap_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFFC, &cid3);
1069 mem_ap_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFCC, &memtype);
1070 retval = dap_run(dap);
1071 if (retval != ERROR_OK)
1072 return retval;
1073
1074 if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
1075 command_print(cmd_ctx, "\tCID3 0x%2.2" PRIx32
1076 ", CID2 0x%2.2" PRIx32
1077 ", CID1 0x%2.2" PRIx32
1078 ", CID0 0x%2.2" PRIx32,
1079 cid3, cid2, cid1, cid0);
1080 if (memtype & 0x01)
1081 command_print(cmd_ctx, "\tMEMTYPE system memory present on bus");
1082 else
1083 command_print(cmd_ctx, "\tMEMTYPE System memory not present. "
1084 "Dedicated debug bus.");
1085
1086 /* Now we read ROM table entries from dbgbase&0xFFFFF000) | 0x000 until we get 0x00000000 */
1087 entry_offset = 0;
1088 do
1089 {
1090 mem_ap_read_atomic_u32(dap, (dbgbase&0xFFFFF000) | entry_offset, &romentry);
1091 command_print(cmd_ctx, "\tROMTABLE[0x%x] = 0x%" PRIx32 "",entry_offset,romentry);
1092 if (romentry&0x01)
1093 {
1094 uint32_t c_cid0, c_cid1, c_cid2, c_cid3;
1095 uint32_t c_pid0, c_pid1, c_pid2, c_pid3, c_pid4;
1096 uint32_t component_start, component_base;
1097 unsigned part_num;
1098 char *type, *full;
1099
1100 component_base = (uint32_t)((dbgbase & 0xFFFFF000)
1101 + (int)(romentry & 0xFFFFF000));
1102 mem_ap_read_atomic_u32(dap,
1103 (component_base & 0xFFFFF000) | 0xFE0, &c_pid0);
1104 mem_ap_read_atomic_u32(dap,
1105 (component_base & 0xFFFFF000) | 0xFE4, &c_pid1);
1106 mem_ap_read_atomic_u32(dap,
1107 (component_base & 0xFFFFF000) | 0xFE8, &c_pid2);
1108 mem_ap_read_atomic_u32(dap,
1109 (component_base & 0xFFFFF000) | 0xFEC, &c_pid3);
1110 mem_ap_read_atomic_u32(dap,
1111 (component_base & 0xFFFFF000) | 0xFD0, &c_pid4);
1112 mem_ap_read_atomic_u32(dap,
1113 (component_base & 0xFFFFF000) | 0xFF0, &c_cid0);
1114 mem_ap_read_atomic_u32(dap,
1115 (component_base & 0xFFFFF000) | 0xFF4, &c_cid1);
1116 mem_ap_read_atomic_u32(dap,
1117 (component_base & 0xFFFFF000) | 0xFF8, &c_cid2);
1118 mem_ap_read_atomic_u32(dap,
1119 (component_base & 0xFFFFF000) | 0xFFC, &c_cid3);
1120 component_start = component_base - 0x1000*(c_pid4 >> 4);
1121
1122 command_print(cmd_ctx, "\t\tComponent base address 0x%" PRIx32
1123 ", start address 0x%" PRIx32,
1124 component_base, component_start);
1125 command_print(cmd_ctx, "\t\tComponent class is 0x%x, %s",
1126 (int) (c_cid1 >> 4) & 0xf,
1127 /* See ARM IHI 0029B Table 3-3 */
1128 class_description[(c_cid1 >> 4) & 0xf]);
1129
1130 /* CoreSight component? */
1131 if (((c_cid1 >> 4) & 0x0f) == 9) {
1132 uint32_t devtype;
1133 unsigned minor;
1134 char *major = "Reserved", *subtype = "Reserved";
1135
1136 mem_ap_read_atomic_u32(dap,
1137 (component_base & 0xfffff000) | 0xfcc,
1138 &devtype);
1139 minor = (devtype >> 4) & 0x0f;
1140 switch (devtype & 0x0f) {
1141 case 0:
1142 major = "Miscellaneous";
1143 switch (minor) {
1144 case 0:
1145 subtype = "other";
1146 break;
1147 case 4:
1148 subtype = "Validation component";
1149 break;
1150 }
1151 break;
1152 case 1:
1153 major = "Trace Sink";
1154 switch (minor) {
1155 case 0:
1156 subtype = "other";
1157 break;
1158 case 1:
1159 subtype = "Port";
1160 break;
1161 case 2:
1162 subtype = "Buffer";
1163 break;
1164 }
1165 break;
1166 case 2:
1167 major = "Trace Link";
1168 switch (minor) {
1169 case 0:
1170 subtype = "other";
1171 break;
1172 case 1:
1173 subtype = "Funnel, router";
1174 break;
1175 case 2:
1176 subtype = "Filter";
1177 break;
1178 case 3:
1179 subtype = "FIFO, buffer";
1180 break;
1181 }
1182 break;
1183 case 3:
1184 major = "Trace Source";
1185 switch (minor) {
1186 case 0:
1187 subtype = "other";
1188 break;
1189 case 1:
1190 subtype = "Processor";
1191 break;
1192 case 2:
1193 subtype = "DSP";
1194 break;
1195 case 3:
1196 subtype = "Engine/Coprocessor";
1197 break;
1198 case 4:
1199 subtype = "Bus";
1200 break;
1201 }
1202 break;
1203 case 4:
1204 major = "Debug Control";
1205 switch (minor) {
1206 case 0:
1207 subtype = "other";
1208 break;
1209 case 1:
1210 subtype = "Trigger Matrix";
1211 break;
1212 case 2:
1213 subtype = "Debug Auth";
1214 break;
1215 }
1216 break;
1217 case 5:
1218 major = "Debug Logic";
1219 switch (minor) {
1220 case 0:
1221 subtype = "other";
1222 break;
1223 case 1:
1224 subtype = "Processor";
1225 break;
1226 case 2:
1227 subtype = "DSP";
1228 break;
1229 case 3:
1230 subtype = "Engine/Coprocessor";
1231 break;
1232 }
1233 break;
1234 }
1235 command_print(cmd_ctx, "\t\tType is 0x%2.2x, %s, %s",
1236 (unsigned) (devtype & 0xff),
1237 major, subtype);
1238 /* REVISIT also show 0xfc8 DevId */
1239 }
1240
1241 if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
1242 command_print(cmd_ctx, "\t\tCID3 0x%2.2" PRIx32
1243 ", CID2 0x%2.2" PRIx32
1244 ", CID1 0x%2.2" PRIx32
1245 ", CID0 0x%2.2" PRIx32,
1246 c_cid3, c_cid2, c_cid1, c_cid0);
1247 command_print(cmd_ctx, "\t\tPeripheral ID[4..0] = hex "
1248 "%2.2x %2.2x %2.2x %2.2x %2.2x",
1249 (int) c_pid4,
1250 (int) c_pid3, (int) c_pid2,
1251 (int) c_pid1, (int) c_pid0);
1252
1253 /* Part number interpretations are from Cortex
1254 * core specs, the CoreSight components TRM
1255 * (ARM DDI 0314H), and ETM specs; also from
1256 * chip observation (e.g. TI SDTI).
1257 */
1258 part_num = c_pid0 & 0xff;
1259 part_num |= (c_pid1 & 0x0f) << 8;
1260 switch (part_num) {
1261 case 0x000:
1262 type = "Cortex-M3 NVIC";
1263 full = "(Interrupt Controller)";
1264 break;
1265 case 0x001:
1266 type = "Cortex-M3 ITM";
1267 full = "(Instrumentation Trace Module)";
1268 break;
1269 case 0x002:
1270 type = "Cortex-M3 DWT";
1271 full = "(Data Watchpoint and Trace)";
1272 break;
1273 case 0x003:
1274 type = "Cortex-M3 FBP";
1275 full = "(Flash Patch and Breakpoint)";
1276 break;
1277 case 0x00d:
1278 type = "CoreSight ETM11";
1279 full = "(Embedded Trace)";
1280 break;
1281 // case 0x113: what?
1282 case 0x120: /* from OMAP3 memmap */
1283 type = "TI SDTI";
1284 full = "(System Debug Trace Interface)";
1285 break;
1286 case 0x343: /* from OMAP3 memmap */
1287 type = "TI DAPCTL";
1288 full = "";
1289 break;
1290 case 0x906:
1291 type = "Coresight CTI";
1292 full = "(Cross Trigger)";
1293 break;
1294 case 0x907:
1295 type = "Coresight ETB";
1296 full = "(Trace Buffer)";
1297 break;
1298 case 0x908:
1299 type = "Coresight CSTF";
1300 full = "(Trace Funnel)";
1301 break;
1302 case 0x910:
1303 type = "CoreSight ETM9";
1304 full = "(Embedded Trace)";
1305 break;
1306 case 0x912:
1307 type = "Coresight TPIU";
1308 full = "(Trace Port Interface Unit)";
1309 break;
1310 case 0x921:
1311 type = "Cortex-A8 ETM";
1312 full = "(Embedded Trace)";
1313 break;
1314 case 0x922:
1315 type = "Cortex-A8 CTI";
1316 full = "(Cross Trigger)";
1317 break;
1318 case 0x923:
1319 type = "Cortex-M3 TPIU";
1320 full = "(Trace Port Interface Unit)";
1321 break;
1322 case 0x924:
1323 type = "Cortex-M3 ETM";
1324 full = "(Embedded Trace)";
1325 break;
1326 case 0xc08:
1327 type = "Cortex-A8 Debug";
1328 full = "(Debug Unit)";
1329 break;
1330 default:
1331 type = "-*- unrecognized -*-";
1332 full = "";
1333 break;
1334 }
1335 command_print(cmd_ctx, "\t\tPart is %s %s",
1336 type, full);
1337 }
1338 else
1339 {
1340 if (romentry)
1341 command_print(cmd_ctx, "\t\tComponent not present");
1342 else
1343 command_print(cmd_ctx, "\t\tEnd of ROM table");
1344 }
1345 entry_offset += 4;
1346 } while (romentry > 0);
1347 }
1348 else
1349 {
1350 command_print(cmd_ctx, "\tNo ROM table present");
1351 }
1352 dap_ap_select(dap, apselold);
1353
1354 return ERROR_OK;
1355 }
1356
1357 COMMAND_HANDLER(handle_dap_info_command)
1358 {
1359 struct target *target = get_current_target(CMD_CTX);
1360 struct arm *arm = target_to_arm(target);
1361 struct adiv5_dap *dap = arm->dap;
1362 uint32_t apsel;
1363
1364 switch (CMD_ARGC) {
1365 case 0:
1366 apsel = dap->apsel;
1367 break;
1368 case 1:
1369 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
1370 break;
1371 default:
1372 return ERROR_COMMAND_SYNTAX_ERROR;
1373 }
1374
1375 return dap_info_command(CMD_CTX, dap, apsel);
1376 }
1377
1378 COMMAND_HANDLER(dap_baseaddr_command)
1379 {
1380 struct target *target = get_current_target(CMD_CTX);
1381 struct arm *arm = target_to_arm(target);
1382 struct adiv5_dap *dap = arm->dap;
1383
1384 uint32_t apsel, apselsave, baseaddr;
1385 int retval;
1386
1387 apselsave = dap->apsel;
1388 switch (CMD_ARGC) {
1389 case 0:
1390 apsel = dap->apsel;
1391 break;
1392 case 1:
1393 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
1394 /* AP address is in bits 31:24 of DP_SELECT */
1395 if (apsel >= 256)
1396 return ERROR_INVALID_ARGUMENTS;
1397 break;
1398 default:
1399 return ERROR_COMMAND_SYNTAX_ERROR;
1400 }
1401
1402 if (apselsave != apsel)
1403 dap_ap_select(dap, apsel);
1404
1405 /* NOTE: assumes we're talking to a MEM-AP, which
1406 * has a base address. There are other kinds of AP,
1407 * though they're not common for now. This should
1408 * use the ID register to verify it's a MEM-AP.
1409 */
1410 retval = dap_queue_ap_read(dap, AP_REG_BASE, &baseaddr);
1411 retval = dap_run(dap);
1412 if (retval != ERROR_OK)
1413 return retval;
1414
1415 command_print(CMD_CTX, "0x%8.8" PRIx32, baseaddr);
1416
1417 if (apselsave != apsel)
1418 dap_ap_select(dap, apselsave);
1419
1420 return retval;
1421 }
1422
1423 COMMAND_HANDLER(dap_memaccess_command)
1424 {
1425 struct target *target = get_current_target(CMD_CTX);
1426 struct arm *arm = target_to_arm(target);
1427 struct adiv5_dap *dap = arm->dap;
1428
1429 uint32_t memaccess_tck;
1430
1431 switch (CMD_ARGC) {
1432 case 0:
1433 memaccess_tck = dap->memaccess_tck;
1434 break;
1435 case 1:
1436 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], memaccess_tck);
1437 break;
1438 default:
1439 return ERROR_COMMAND_SYNTAX_ERROR;
1440 }
1441 dap->memaccess_tck = memaccess_tck;
1442
1443 command_print(CMD_CTX, "memory bus access delay set to %" PRIi32 " tck",
1444 dap->memaccess_tck);
1445
1446 return ERROR_OK;
1447 }
1448
1449 COMMAND_HANDLER(dap_apsel_command)
1450 {
1451 struct target *target = get_current_target(CMD_CTX);
1452 struct arm *arm = target_to_arm(target);
1453 struct adiv5_dap *dap = arm->dap;
1454
1455 uint32_t apsel, apid;
1456 int retval;
1457
1458 switch (CMD_ARGC) {
1459 case 0:
1460 apsel = 0;
1461 break;
1462 case 1:
1463 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
1464 /* AP address is in bits 31:24 of DP_SELECT */
1465 if (apsel >= 256)
1466 return ERROR_INVALID_ARGUMENTS;
1467 break;
1468 default:
1469 return ERROR_COMMAND_SYNTAX_ERROR;
1470 }
1471
1472 dap_ap_select(dap, apsel);
1473 retval = dap_queue_ap_read(dap, AP_REG_IDR, &apid);
1474 retval = dap_run(dap);
1475 if (retval != ERROR_OK)
1476 return retval;
1477
1478 command_print(CMD_CTX, "ap %" PRIi32 " selected, identification register 0x%8.8" PRIx32,
1479 apsel, apid);
1480
1481 return retval;
1482 }
1483
1484 COMMAND_HANDLER(dap_apid_command)
1485 {
1486 struct target *target = get_current_target(CMD_CTX);
1487 struct arm *arm = target_to_arm(target);
1488 struct adiv5_dap *dap = arm->dap;
1489
1490 uint32_t apsel, apselsave, apid;
1491 int retval;
1492
1493 apselsave = dap->apsel;
1494 switch (CMD_ARGC) {
1495 case 0:
1496 apsel = dap->apsel;
1497 break;
1498 case 1:
1499 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
1500 /* AP address is in bits 31:24 of DP_SELECT */
1501 if (apsel >= 256)
1502 return ERROR_INVALID_ARGUMENTS;
1503 break;
1504 default:
1505 return ERROR_COMMAND_SYNTAX_ERROR;
1506 }
1507
1508 if (apselsave != apsel)
1509 dap_ap_select(dap, apsel);
1510
1511 retval = dap_queue_ap_read(dap, AP_REG_IDR, &apid);
1512 retval = dap_run(dap);
1513 if (retval != ERROR_OK)
1514 return retval;
1515
1516 command_print(CMD_CTX, "0x%8.8" PRIx32, apid);
1517 if (apselsave != apsel)
1518 dap_ap_select(dap, apselsave);
1519
1520 return retval;
1521 }
1522
1523 static const struct command_registration dap_commands[] = {
1524 {
1525 .name = "info",
1526 .handler = handle_dap_info_command,
1527 .mode = COMMAND_EXEC,
1528 .help = "display ROM table for MEM-AP "
1529 "(default currently selected AP)",
1530 .usage = "[ap_num]",
1531 },
1532 {
1533 .name = "apsel",
1534 .handler = dap_apsel_command,
1535 .mode = COMMAND_EXEC,
1536 .help = "Set the currently selected AP (default 0) "
1537 "and display the result",
1538 .usage = "[ap_num]",
1539 },
1540 {
1541 .name = "apid",
1542 .handler = dap_apid_command,
1543 .mode = COMMAND_EXEC,
1544 .help = "return ID register from AP "
1545 "(default currently selected AP)",
1546 .usage = "[ap_num]",
1547 },
1548 {
1549 .name = "baseaddr",
1550 .handler = dap_baseaddr_command,
1551 .mode = COMMAND_EXEC,
1552 .help = "return debug base address from MEM-AP "
1553 "(default currently selected AP)",
1554 .usage = "[ap_num]",
1555 },
1556 {
1557 .name = "memaccess",
1558 .handler = dap_memaccess_command,
1559 .mode = COMMAND_EXEC,
1560 .help = "set/get number of extra tck for MEM-AP memory "
1561 "bus access [0-255]",
1562 .usage = "[cycles]",
1563 },
1564 COMMAND_REGISTRATION_DONE
1565 };
1566
1567 const struct command_registration dap_command_handlers[] = {
1568 {
1569 .name = "dap",
1570 .mode = COMMAND_EXEC,
1571 .help = "DAP command group",
1572 .chain = dap_commands,
1573 },
1574 COMMAND_REGISTRATION_DONE
1575 };
1576
1577

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)