OpenOCD
arm946e.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2005 by Dominic Rath *
5  * Dominic.Rath@gmx.de *
6  * *
7  * Copyright (C) 2008 by Spencer Oliver *
8  * spen@spen-soft.co.uk *
9  * *
10  * Copyright (C) 2010 by Drasko DRASKOVIC *
11  * drasko.draskovic@gmail.com *
12  ***************************************************************************/
13 
14 #ifdef HAVE_CONFIG_H
15 #include "config.h"
16 #endif
17 
18 #include "arm946e.h"
19 #include "target_type.h"
20 #include "arm_opcodes.h"
21 
22 #include "breakpoints.h"
23 
24 #if 0
25 #define _DEBUG_INSTRUCTION_EXECUTION_
26 #endif
27 
28 #define NB_CACHE_WAYS 4
29 
30 #define CP15_CTL 0x02
31 #define CP15_CTL_DCACHE (1<<2)
32 #define CP15_CTL_ICACHE (1<<12)
33 
41 static uint8_t arm946e_preserve_cache;
42 
43 static int arm946e_post_debug_entry(struct target *target);
44 static void arm946e_pre_restore_context(struct target *target);
45 static int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *value);
46 
48  struct arm946e_common *arm946e,
49  struct jtag_tap *tap)
50 {
51  struct arm7_9_common *arm7_9 = &arm946e->arm7_9_common;
52 
53  /* initialize arm7/arm9 specific info (including armv4_5) */
54  arm9tdmi_init_arch_info(target, arm7_9, tap);
55 
57 
62  arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
63  arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
64 
65 
68 
75 
76  /* override hw single-step capability from ARM9TDMI */
77  /* arm7_9->has_single_step = 1; */
78 
79  return ERROR_OK;
80 }
81 
82 static int arm946e_target_create(struct target *target, Jim_Interp *interp)
83 {
84  struct arm946e_common *arm946e = calloc(1, sizeof(struct arm946e_common));
85 
87 
88  return ERROR_OK;
89 }
90 
91 static void arm946e_deinit_target(struct target *target)
92 {
93  struct arm *arm = target_to_arm(target);
94  struct arm946e_common *arm946e = target_to_arm946(target);
95 
98  free(arm946e);
99 }
100 
102  struct arm946e_common *arm946e)
103 {
104  if (arm946e->common_magic != ARM946E_COMMON_MAGIC) {
105  command_print(cmd, "target is not an ARM946");
106  return ERROR_TARGET_INVALID;
107  }
108  return ERROR_OK;
109 }
110 
111 /*
112  * Update cp15_control_reg, saved on debug_entry.
113  */
114 static void arm946e_update_cp15_caches(struct target *target, uint32_t value)
115 {
116  struct arm946e_common *arm946e = target_to_arm946(target);
118  | (value & (CP15_CTL_DCACHE|CP15_CTL_ICACHE));
119 }
120 
121 /*
122  * REVISIT: The "read_cp15" and "write_cp15" commands could hook up
123  * to eventual mrc() and mcr() routines ... the reg_addr values being
124  * constructed (for CP15 only) from Opcode_1, Opcode_2, and CRn values.
125  * See section 7.3 of the ARM946E-S TRM.
126  */
127 static int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *value)
128 {
129  int retval = ERROR_OK;
130  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
131  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
132  struct scan_field fields[3];
133  uint8_t reg_addr_buf = reg_addr & 0x3f;
134  uint8_t nr_w_buf = 0;
135 
136  retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
137  if (retval != ERROR_OK)
138  return retval;
139  retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);
140  if (retval != ERROR_OK)
141  return retval;
142 
143  fields[0].num_bits = 32;
144  /* REVISIT: table 7-2 shows that bits 31-31 need to be
145  * specified for accessing BIST registers ...
146  */
147  fields[0].out_value = NULL;
148  fields[0].in_value = NULL;
149 
150  fields[1].num_bits = 6;
151  fields[1].out_value = &reg_addr_buf;
152  fields[1].in_value = NULL;
153 
154  fields[2].num_bits = 1;
155  fields[2].out_value = &nr_w_buf;
156  fields[2].in_value = NULL;
157 
158  jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
159 
160  fields[0].in_value = (uint8_t *)value;
161  jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
162 
164 
165 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
166  LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
167 #endif
168 
169  retval = jtag_execute_queue();
170  if (retval != ERROR_OK)
171  return retval;
172 
173  return ERROR_OK;
174 }
175 
176 static int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value)
177 {
178  int retval = ERROR_OK;
179  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
180  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
181  struct scan_field fields[3];
182  uint8_t reg_addr_buf = reg_addr & 0x3f;
183  uint8_t nr_w_buf = 1;
184  uint8_t value_buf[4];
185 
186  buf_set_u32(value_buf, 0, 32, value);
187 
188  retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
189  if (retval != ERROR_OK)
190  return retval;
191  retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);
192  if (retval != ERROR_OK)
193  return retval;
194 
195  fields[0].num_bits = 32;
196  fields[0].out_value = value_buf;
197  fields[0].in_value = NULL;
198 
199  fields[1].num_bits = 6;
200  fields[1].out_value = &reg_addr_buf;
201  fields[1].in_value = NULL;
202 
203  fields[2].num_bits = 1;
204  fields[2].out_value = &nr_w_buf;
205  fields[2].in_value = NULL;
206 
207  jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
208 
209 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
210  LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
211 #endif
212 
213  retval = jtag_execute_queue();
214  if (retval != ERROR_OK)
215  return retval;
216 
217  return ERROR_OK;
218 }
219 
220 #define GET_ICACHE_SIZE 6
221 #define GET_DCACHE_SIZE 18
222 
223 /*
224  * \param target struct target pointer
225  * \param idsel select GET_ICACHE_SIZE or GET_DCACHE_SIZE
226  * \returns cache size, given in bytes
227  */
228 static uint32_t arm946e_cp15_get_csize(struct target *target, int idsel)
229 {
230  struct arm946e_common *arm946e = target_to_arm946(target);
231  uint32_t csize = arm946e->cp15_cache_info;
232  if (csize == 0) {
233  if (arm946e_read_cp15(target, 0x01, &csize) == ERROR_OK)
234  arm946e->cp15_cache_info = csize;
235  }
236  if (csize & (1<<(idsel-4))) /* cache absent */
237  return 0;
238  csize = (csize >> idsel) & 0x0F;
239  return csize ? 1 << (12 + (csize-3)) : 0;
240 }
241 
243 {
244  uint32_t csize = arm946e_cp15_get_csize(target, GET_DCACHE_SIZE);
245  if (csize == 0)
247 
248  /* One line (index) is 32 bytes (8 words) long, 4-way assoc
249  * ARM DDI 0201D, Section 3.3.5
250  */
251  int nb_idx = (csize / (4*8*NB_CACHE_WAYS)); /* gives nb of lines (indexes) in the cache */
252 
253  /* Loop for all segments (i.e. ways) */
254  uint32_t seg;
255  for (seg = 0; seg < NB_CACHE_WAYS; seg++) {
256  /* Loop for all indexes */
257  int idx;
258  for (idx = 0; idx < nb_idx; idx++) {
259  /* Form and write cp15 index (segment + line idx) */
260  uint32_t cp15_idx = seg << 30 | idx << 5;
261  int retval = arm946e_write_cp15(target, 0x3a, cp15_idx);
262  if (retval != ERROR_OK) {
263  LOG_DEBUG("ERROR writing index");
264  return retval;
265  }
266 
267  /* Read dtag */
268  uint32_t dtag;
269  retval = arm946e_read_cp15(target, 0x16, &dtag);
270  if (retval != ERROR_OK) {
271  LOG_DEBUG("ERROR reading dtag");
272  return retval;
273  }
274 
275  /* Check cache line VALID bit */
276  if (!(dtag >> 4 & 0x1))
277  continue;
278 
279  /* Clean data cache line */
280  retval = arm946e_write_cp15(target, 0x35, 0x1);
281  if (retval != ERROR_OK) {
282  LOG_DEBUG("ERROR cleaning cache line");
283  return retval;
284  }
285 
286  /* Flush data cache line */
287  retval = arm946e_write_cp15(target, 0x1a, 0x1);
288  if (retval != ERROR_OK) {
289  LOG_DEBUG("ERROR flushing cache line");
290  return retval;
291  }
292  }
293  }
294 
295  return ERROR_OK;
296 }
297 
299 {
300  /* Check cache presence before flushing - avoid undefined behavior */
301  uint32_t csize = arm946e_cp15_get_csize(target, GET_ICACHE_SIZE);
302  if (csize == 0)
304 
305  LOG_DEBUG("FLUSHING I$");
310  int retval = arm946e_write_cp15(target, 0x0f, 0x1);
311  if (retval != ERROR_OK) {
312  LOG_DEBUG("ERROR flushing I$");
313  return retval;
314  }
315 
316  return ERROR_OK;
317 }
318 
320 {
321  uint32_t ctr_reg = 0x0;
322  uint32_t retval = ERROR_OK;
323  struct arm946e_common *arm946e = target_to_arm946(target);
324 
325  /* See if CACHES are enabled, and save that info
326  * in the context bits, so that arm946e_pre_restore_context() can use them */
327  arm946e_read_cp15(target, CP15_CTL, &ctr_reg);
328 
329  /* Save control reg in the context */
330  arm946e->cp15_control_reg = ctr_reg;
331 
333  if (ctr_reg & CP15_CTL_DCACHE) {
334  /* Clean and flush D$ */
336 
337  /* Disable D$ */
338  ctr_reg &= ~CP15_CTL_DCACHE;
339  }
340 
341  if (ctr_reg & CP15_CTL_ICACHE) {
342  /* Flush I$ */
344 
345  /* Disable I$ */
346  ctr_reg &= ~CP15_CTL_ICACHE;
347  }
348 
349  /* Write the new configuration */
350  retval = arm946e_write_cp15(target, CP15_CTL, ctr_reg);
351  if (retval != ERROR_OK) {
352  LOG_DEBUG("ERROR disabling cache");
353  return retval;
354  }
355  } /* if preserve_cache */
356 
357  return ERROR_OK;
358 }
359 
361 {
362  uint32_t ctr_reg = 0x0;
363  uint32_t retval;
364 
366  struct arm946e_common *arm946e = target_to_arm946(target);
367  /* Get the contents of the CTR reg */
368  arm946e_read_cp15(target, CP15_CTL, &ctr_reg);
369 
376  ctr_reg |= arm946e->cp15_control_reg & (CP15_CTL_DCACHE|CP15_CTL_ICACHE);
377 
378  /* Write the new configuration */
379  retval = arm946e_write_cp15(target, CP15_CTL, ctr_reg);
380  if (retval != ERROR_OK)
381  LOG_DEBUG("ERROR enabling cache");
382  } /* if preserve_cache */
383 }
384 
385 static uint32_t arm946e_invalidate_dcache(struct target *target, uint32_t address,
386  uint32_t size, uint32_t count)
387 {
388  uint32_t cur_addr = 0x0;
389  uint32_t cp15_idx, set, way, dtag;
390  uint32_t i = 0;
391  int retval;
392 
393  for (i = 0; i < count*size; i++) {
394  cur_addr = address + i;
395 
396 
397  set = (cur_addr >> 5) & 0xff; /* set field is 8 bits long */
398 
399  for (way = 0; way < NB_CACHE_WAYS; way++) {
407  /* Form and write cp15 index (segment + line idx) */
408  cp15_idx = way << 30 | set << 5;
409  retval = arm946e_write_cp15(target, 0x3a, cp15_idx);
410  if (retval != ERROR_OK) {
411  LOG_DEBUG("ERROR writing index");
412  return retval;
413  }
414 
415  /* Read dtag */
416  retval = arm946e_read_cp15(target, 0x16, &dtag);
417  if (retval != ERROR_OK) {
418  LOG_DEBUG("ERROR reading dtag");
419  return retval;
420  }
421 
422  /* Check cache line VALID bit */
423  if (!(dtag >> 4 & 0x1))
424  continue;
425 
426  /* If line is valid and corresponds to affected address - invalidate it */
427  if (dtag >> 5 == cur_addr >> 5) {
428  /* Clean data cache line */
429  retval = arm946e_write_cp15(target, 0x35, 0x1);
430  if (retval != ERROR_OK) {
431  LOG_DEBUG("ERROR cleaning cache line");
432  return retval;
433  }
434 
435  /* Flush data cache line */
436  retval = arm946e_write_cp15(target, 0x1c, 0x1);
437  if (retval != ERROR_OK) {
438  LOG_DEBUG("ERROR flushing cache line");
439  return retval;
440  }
441 
442  break;
443  }
444  } /* loop through all 4 ways */
445  } /* loop through all addresses */
446 
447  return ERROR_OK;
448 }
449 
450 static uint32_t arm946e_invalidate_icache(struct target *target, uint32_t address,
451  uint32_t size, uint32_t count)
452 {
453  uint32_t cur_addr = 0x0;
454  uint32_t cp15_idx, set, way, itag;
455  uint32_t i = 0;
456  int retval;
457 
458  for (i = 0; i < count*size; i++) {
459  cur_addr = address + i;
460 
461  set = (cur_addr >> 5) & 0xff; /* set field is 8 bits long */
462 
463  for (way = 0; way < NB_CACHE_WAYS; way++) {
464  /* Form and write cp15 index (segment + line idx) */
465  cp15_idx = way << 30 | set << 5;
466  retval = arm946e_write_cp15(target, 0x3a, cp15_idx);
467  if (retval != ERROR_OK) {
468  LOG_DEBUG("ERROR writing index");
469  return retval;
470  }
471 
472  /* Read itag */
473  retval = arm946e_read_cp15(target, 0x17, &itag);
474  if (retval != ERROR_OK) {
475  LOG_DEBUG("ERROR reading itag");
476  return retval;
477  }
478 
479  /* Check cache line VALID bit */
480  if (!(itag >> 4 & 0x1))
481  continue;
482 
483  /* If line is valid and corresponds to affected address - invalidate it */
484  if (itag >> 5 == cur_addr >> 5) {
485  /* Flush I$ line */
486  retval = arm946e_write_cp15(target, 0x1d, 0x0);
487  if (retval != ERROR_OK) {
488  LOG_DEBUG("ERROR flushing cache line");
489  return retval;
490  }
491 
492  break;
493  }
494  } /* way loop */
495  } /* addr loop */
496 
497  return ERROR_OK;
498 }
499 
501 static int arm946e_write_memory(struct target *target, target_addr_t address,
502  uint32_t size, uint32_t count, const uint8_t *buffer)
503 {
504  int retval;
505 
506  LOG_DEBUG("-");
507 
508  struct arm946e_common *arm946e = target_to_arm946(target);
509  /* Invalidate D$ if it is ON */
512 
516  retval = arm7_9_write_memory_opt(target, address, size, count, buffer);
517  if (retval != ERROR_OK)
518  return retval;
519 
520  /* *
521  * Invalidate I$ if it is ON.
522  *
523  * D$ has been cleaned and flushed before mem write thus forcing it to behave like write-through,
524  * because arm7_9_write_memory() has seen non-valid bit in D$
525  * and wrote data into physical RAM (without touching or allocating the cache line).
526  * From ARM946ES Technical Reference Manual we can see that it uses "allocate on read-miss"
527  * policy for both I$ and D$ (Chapter 3.2 and 3.3)
528  *
529  * Explanation :
530  * "ARM system developer's guide: designing and optimizing system software" by
531  * Andrew N. Sloss, Dominic Symes and Chris Wright,
532  * Chapter 12.3.3 Allocating Policy on a Cache Miss :
533  * A read allocate on cache miss policy allocates a cache line only during a read from main memory.
534  * If the victim cache line contains valid data, then it is written to main memory before the cache line
535  * is filled with new data.
536  * Under this strategy, a write of new data to memory does not update the contents of the cache memory
537  * unless a cache line was allocated on a previous read from main memory.
538  * If the cache line contains valid data, then the write updates the cache and may update the main memory if
539  * the cache write policy is write-through.
540  * If the data is not in the cache, the controller writes to main memory only.
541  */
544 
545  return ERROR_OK;
546 
547 }
548 
549 static int arm946e_read_memory(struct target *target, target_addr_t address,
550  uint32_t size, uint32_t count, uint8_t *buffer)
551 {
552  int retval;
553 
554  LOG_DEBUG("-");
555 
556  retval = arm7_9_read_memory(target, address, size, count, buffer);
557  if (retval != ERROR_OK)
558  return retval;
559 
560  return ERROR_OK;
561 }
562 
563 COMMAND_HANDLER(arm946e_handle_cp15)
564 {
565  /* one or two arguments, access a single register (write if second argument is given) */
566  if (CMD_ARGC < 1 || CMD_ARGC > 2)
568 
570 
571  struct arm946e_common *arm946e = target_to_arm946(target);
572  int retval = arm946e_verify_pointer(CMD, arm946e);
573  if (retval != ERROR_OK)
574  return retval;
575 
576  if (target->state != TARGET_HALTED) {
577  command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
579  }
580 
581  uint32_t address;
582  COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
583 
584  if (CMD_ARGC == 1) {
585  uint32_t value;
586  retval = arm946e_read_cp15(target, address, &value);
587  if (retval != ERROR_OK) {
588  command_print(CMD, "%s cp15 reg %" PRIu32 " access failed", target_name(target), address);
589  return retval;
590  }
591  retval = jtag_execute_queue();
592  if (retval != ERROR_OK)
593  return retval;
594 
595  /* Return value in hex format */
596  command_print(CMD, "0x%08" PRIx32, value);
597  } else if (CMD_ARGC == 2) {
598  uint32_t value;
599  COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
600 
601  retval = arm946e_write_cp15(target, address, value);
602  if (retval != ERROR_OK) {
603  command_print(CMD, "%s cp15 reg %" PRIu32 " access failed", target_name(target), address);
604  return retval;
605  }
606  if (address == CP15_CTL)
608  }
609 
610  return ERROR_OK;
611 }
612 
613 COMMAND_HANDLER(arm946e_handle_idcache)
614 {
615  if (CMD_ARGC > 1)
617 
618  int retval;
620  struct arm946e_common *arm946e = target_to_arm946(target);
621 
622  retval = arm946e_verify_pointer(CMD, arm946e);
623  if (retval != ERROR_OK)
624  return retval;
625 
626  if (target->state != TARGET_HALTED) {
627  command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
629  }
630 
631  bool icache = (strcmp(CMD_NAME, "icache") == 0);
632  uint32_t csize = arm946e_cp15_get_csize(target, icache ? GET_ICACHE_SIZE : GET_DCACHE_SIZE) / 1024;
633  if (CMD_ARGC == 0) {
634  bool bena = ((arm946e->cp15_control_reg & (icache ? CP15_CTL_ICACHE : CP15_CTL_DCACHE)) != 0)
635  && (arm946e->cp15_control_reg & 0x1);
636  if (csize == 0)
637  command_print(CMD, "%s-cache absent", icache ? "I" : "D");
638  else
639  command_print(CMD, "%s-cache size: %" PRIu32 "K, %s",
640  icache ? "I" : "D", csize, bena ? "enabled" : "disabled");
641  return ERROR_OK;
642  }
643 
644  bool flush = false;
645  bool enable = false;
646  retval = command_parse_bool_arg(CMD_ARGV[0], &enable);
647  if (retval == ERROR_COMMAND_SYNTAX_ERROR) {
648  if (strcmp(CMD_ARGV[0], "flush") == 0) {
649  flush = true;
650  retval = ERROR_OK;
651  } else
652  return retval;
653  }
654 
655  /* Do not invalidate or change state, if cache is absent */
656  if (csize == 0) {
657  command_print(CMD, "%s-cache absent, '%s' operation undefined", icache ? "I" : "D", CMD_ARGV[0]);
659  }
660 
661  /* NOTE: flushing entire cache will not preserve lock-down cache regions */
662  if (icache) {
663  if ((arm946e->cp15_control_reg & CP15_CTL_ICACHE) && !enable)
665  } else {
666  if ((arm946e->cp15_control_reg & CP15_CTL_DCACHE) && !enable)
668  }
669 
670  if (retval != ERROR_OK || flush)
671  return retval;
672 
673  uint32_t value;
674  retval = arm946e_read_cp15(target, CP15_CTL, &value);
675  if (retval != ERROR_OK)
676  return retval;
677 
678  uint32_t vnew = value;
679  uint32_t cmask = icache ? CP15_CTL_ICACHE : CP15_CTL_DCACHE;
680  if (enable) {
681  if ((value & 0x1) == 0)
682  LOG_WARNING("arm946e: MPU must be enabled for cache to operate");
683  vnew |= cmask;
684  } else
685  vnew &= ~cmask;
686 
687  if (vnew == value)
688  return ERROR_OK;
689 
690  retval = arm946e_write_cp15(target, CP15_CTL, vnew);
691  if (retval != ERROR_OK)
692  return retval;
693 
695  return ERROR_OK;
696 }
697 
698 static const struct command_registration arm946e_exec_command_handlers[] = {
699  {
700  .name = "cp15",
701  .handler = arm946e_handle_cp15,
702  .mode = COMMAND_EXEC,
703  .usage = "regnum [value]",
704  .help = "read/modify cp15 register",
705  },
706  {
707  .name = "icache",
708  .handler = arm946e_handle_idcache,
709  .mode = COMMAND_EXEC,
710  .usage = "['enable'|'disable'|'flush']",
711  .help = "I-cache info and operations",
712  },
713  {
714  .name = "dcache",
715  .handler = arm946e_handle_idcache,
716  .mode = COMMAND_EXEC,
717  .usage = "['enable'|'disable'|'flush']",
718  .help = "D-cache info and operations",
719  },
721 };
722 
723 static const struct command_registration arm946e_command_handlers[] = {
724  {
726  },
727  {
728  .name = "arm946e",
729  .mode = COMMAND_ANY,
730  .help = "arm946e command group",
731  .usage = "",
733  },
735 };
736 
738 struct target_type arm946e_target = {
739  .name = "arm946e",
740 
741  .poll = arm7_9_poll,
742  .arch_state = arm_arch_state,
743 
744  .target_request_data = arm7_9_target_request_data,
745 
746  .halt = arm7_9_halt,
747  .resume = arm7_9_resume,
748  .step = arm7_9_step,
749 
750  .assert_reset = arm7_9_assert_reset,
751  .deassert_reset = arm7_9_deassert_reset,
752  .soft_reset_halt = arm7_9_soft_reset_halt,
753 
754  .get_gdb_arch = arm_get_gdb_arch,
755  .get_gdb_reg_list = arm_get_gdb_reg_list,
756 
757  /* .read_memory = arm7_9_read_memory, */
758  /* .write_memory = arm7_9_write_memory, */
759  .read_memory = arm946e_read_memory,
760  .write_memory = arm946e_write_memory,
761 
762  .checksum_memory = arm_checksum_memory,
763  .blank_check_memory = arm_blank_check_memory,
764 
765  .run_algorithm = armv4_5_run_algorithm,
766 
767  .add_breakpoint = arm7_9_add_breakpoint,
768  .remove_breakpoint = arm7_9_remove_breakpoint,
769  /* .add_breakpoint = arm946e_add_breakpoint, */
770  /* .remove_breakpoint = arm946e_remove_breakpoint, */
771 
772  .add_watchpoint = arm7_9_add_watchpoint,
773  .remove_watchpoint = arm7_9_remove_watchpoint,
774 
775  .commands = arm946e_command_handlers,
776  .target_create = arm946e_target_create,
777  .init_target = arm9tdmi_init_target,
778  .deinit_target = arm946e_deinit_target,
779  .examine = arm7_9_examine,
780  .check_reset = arm7_9_check_reset,
781 };
int arm7_9_write_memory_opt(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
int arm7_9_examine(struct target *target)
Perform per-target setup that requires JTAG access.
void arm7_9_deinit(struct target *target)
int arm7_9_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
int arm7_9_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
Add a breakpoint to an ARM7/9 target.
int arm7_9_soft_reset_halt(struct target *target)
Issue a software reset and halt to an ARM7/9 target.
int arm7_9_assert_reset(struct target *target)
Asserts the reset (SRST) on an ARM7/9 target.
int arm7_9_poll(struct target *target)
Polls an ARM7/9 target for its current status.
int arm7_9_halt(struct target *target)
Halt an ARM7/9 target.
int arm7_9_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
Removes a breakpoint from an ARM7/9 target.
int arm7_9_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)
Remove a watchpoint from an ARM7/9 target.
int arm7_9_deassert_reset(struct target *target)
Deassert the reset (SRST) signal on an ARM7/9 target.
int arm7_9_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
int arm7_9_target_request_data(struct target *target, uint32_t size, uint8_t *buffer)
Get some data from the ARM7/9 target.
int arm7_9_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
Add a watchpoint to an ARM7/9 target.
int arm7_9_check_reset(struct target *target)
int arm7_9_resume(struct target *target, int current, target_addr_t address, int handle_breakpoints, int debug_execution)
static struct arm7_9_common * target_to_arm7_9(struct target *target)
static void arm946e_update_cp15_caches(struct target *target, uint32_t value)
Definition: arm946e.c:114
static int arm946e_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
Definition: arm946e.c:549
static const struct command_registration arm946e_exec_command_handlers[]
Definition: arm946e.c:698
static int arm946e_target_create(struct target *target, Jim_Interp *interp)
Definition: arm946e.c:82
static uint32_t arm946e_invalidate_whole_icache(struct target *target)
Definition: arm946e.c:298
static int arm946e_init_arch_info(struct target *target, struct arm946e_common *arm946e, struct jtag_tap *tap)
Definition: arm946e.c:47
static void arm946e_deinit_target(struct target *target)
Definition: arm946e.c:91
static int arm946e_post_debug_entry(struct target *target)
Definition: arm946e.c:319
#define CP15_CTL
Definition: arm946e.c:30
static uint8_t arm946e_preserve_cache
flag to give info about cache manipulation during debug : "0" - cache lines are invalidated "on the f...
Definition: arm946e.c:41
#define GET_DCACHE_SIZE
Definition: arm946e.c:221
static const struct command_registration arm946e_command_handlers[]
Definition: arm946e.c:723
COMMAND_HANDLER(arm946e_handle_cp15)
Definition: arm946e.c:563
static int arm946e_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
Writes a buffer, in the specified word size, with current MMU settings.
Definition: arm946e.c:501
#define CP15_CTL_DCACHE
Definition: arm946e.c:31
static int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value)
Definition: arm946e.c:176
#define GET_ICACHE_SIZE
Definition: arm946e.c:220
#define CP15_CTL_ICACHE
Definition: arm946e.c:32
static int arm946e_verify_pointer(struct command_invocation *cmd, struct arm946e_common *arm946e)
Definition: arm946e.c:101
#define NB_CACHE_WAYS
Definition: arm946e.c:28
struct target_type arm946e_target
Holds methods for ARM946 targets.
Definition: arm946e.c:738
static uint32_t arm946e_invalidate_icache(struct target *target, uint32_t address, uint32_t size, uint32_t count)
Definition: arm946e.c:450
static uint32_t arm946e_invalidate_dcache(struct target *target, uint32_t address, uint32_t size, uint32_t count)
Definition: arm946e.c:385
static int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *value)
Definition: arm946e.c:127
static uint32_t arm946e_invalidate_whole_dcache(struct target *target)
Definition: arm946e.c:242
static void arm946e_pre_restore_context(struct target *target)
Definition: arm946e.c:360
static uint32_t arm946e_cp15_get_csize(struct target *target, int idsel)
Definition: arm946e.c:228
#define ARM946E_COMMON_MAGIC
Definition: arm946e.h:19
static struct arm946e_common * target_to_arm946(struct target *target)
Definition: arm946e.h:29
int arm9tdmi_init_arch_info(struct target *target, struct arm7_9_common *arm7_9, struct jtag_tap *tap)
Definition: arm9tdmi.c:711
int arm9tdmi_init_target(struct command_context *cmd_ctx, struct target *target)
Definition: arm9tdmi.c:703
const struct command_registration arm9tdmi_command_handlers[]
Definition: arm9tdmi.c:873
int arm_blank_check_memory(struct target *target, struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)
Runs ARM code in the target to check whether a memory block holds all ones.
Definition: armv4_5.c:1595
int arm_arch_state(struct target *target)
Definition: armv4_5.c:782
int arm_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum)
Runs ARM code in the target to calculate a CRC32 checksum.
Definition: armv4_5.c:1522
int arm_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class)
Definition: armv4_5.c:1194
int armv4_5_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, int timeout_ms, void *arch_info)
Definition: armv4_5.c:1496
void arm_free_reg_cache(struct arm *arm)
Definition: armv4_5.c:761
const char * arm_get_gdb_arch(struct target *target)
Definition: armv4_5.c:1189
static struct arm * target_to_arm(struct target *target)
Convert target handle to generic ARM target state handle.
Definition: arm.h:243
static int arm_jtag_scann(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state)
Definition: arm_jtag.h:43
static int arm_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr, void *no_verify_capture, tap_state_t end_state)
Definition: arm_jtag.h:31
static void arm_le_to_h_u32(jtag_callback_data_t arg)
Definition: arm_jtag.h:63
Macros used to generate various ARM or Thumb opcodes.
#define ARMV5_BKPT(im)
Definition: arm_opcodes.h:205
#define ARMV5_T_BKPT(im)
Definition: arm_opcodes.h:291
static void buf_set_u32(uint8_t *_buffer, unsigned first, unsigned num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:30
int command_parse_bool_arg(const char *in, bool *out)
Definition: command.c:1384
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:473
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:140
#define CMD_NAME
Use this macro to access the name of the command being handled, rather than accessing the variable di...
Definition: command.h:160
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:155
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:385
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:150
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
Definition: command.h:425
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
Definition: command.h:145
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:247
@ COMMAND_ANY
Definition: command.h:42
@ COMMAND_EXEC
Definition: command.h:40
int jtag_execute_queue(void)
For software FIFO implementations, the queued commands can be executed during this call or earlier.
Definition: jtag/core.c:1037
void jtag_add_dr_scan(struct jtag_tap *active, int in_num_fields, const struct scan_field *in_fields, tap_state_t state)
Generate a DR SCAN using the fields passed to the function.
Definition: jtag/core.c:451
void jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t data0)
A simpler version of jtag_add_callback4().
@ TAP_IDLE
Definition: jtag.h:52
intptr_t jtag_callback_data_t
Defines the type of data passed to the jtag_callback_t interface.
Definition: jtag.h:333
#define LOG_WARNING(expr ...)
Definition: log.h:120
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:155
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
Structure for items that are common between both ARM7 and ARM9 targets.
Definition: arm7_9_common.h:28
uint32_t arm_bkpt
ARM breakpoint instruction.
Definition: arm7_9_common.h:36
struct arm_jtag jtag_info
JTAG information for target.
Definition: arm7_9_common.h:33
int(* post_debug_entry)(struct target *target)
Callback function called after entering debug mode.
uint16_t thumb_bkpt
Thumb breakpoint instruction.
Definition: arm7_9_common.h:37
void(* pre_restore_context)(struct target *target)
Callback function called before restoring the processor context.
uint32_t cp15_cache_info
Definition: arm946e.h:26
struct arm7_9_common arm7_9_common
Definition: arm946e.h:24
uint32_t cp15_control_reg
Definition: arm946e.h:25
unsigned int common_magic
Definition: arm946e.h:22
uint32_t intest_instr
Definition: arm_jtag.h:24
struct jtag_tap * tap
Definition: arm_jtag.h:18
Represents a generic ARM core, with standard application registers.
Definition: arm.h:167
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
const char * name
Definition: command.h:229
const struct command_registration * chain
If non-NULL, the commands in chain will be registered in the same context and scope of this registrat...
Definition: command.h:243
Definition: jtag.h:100
This structure defines a single scan field in the scan.
Definition: jtag.h:86
int num_bits
The number of bits this field specifies.
Definition: jtag.h:88
uint8_t * in_value
A pointer to a 32-bit memory location for data scanned out.
Definition: jtag.h:92
const uint8_t * out_value
A pointer to value to be scanned into the device.
Definition: jtag.h:90
This holds methods shared between all instances of a given target type.
Definition: target_type.h:26
const char * name
Name of this type of target.
Definition: target_type.h:31
Definition: target.h:120
struct jtag_tap * tap
Definition: target.h:124
enum target_state state
Definition: target.h:162
struct target * get_current_target(struct command_context *cmd_ctx)
Definition: target.c:536
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:792
#define ERROR_TARGET_INVALID
Definition: target.h:789
@ TARGET_HALTED
Definition: target.h:55
static const char * target_name(struct target *target)
Returns the instance-specific name of the specified target.
Definition: target.h:234
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:796
uint64_t target_addr_t
Definition: types.h:335
#define NULL
Definition: usb.h:16
uint8_t cmd
Definition: vdebug.c:1
uint8_t count[4]
Definition: vdebug.c:22