Edgar Grimberg, fix arm926ejs_examine_debug_reason return value.
[openocd.git] / src / target / arm926ejs.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "arm926ejs.h"
25 #include "jtag.h"
26 #include "log.h"
27
28 #include <stdlib.h>
29 #include <string.h>
30
31 #if 1
32 #define _DEBUG_INSTRUCTION_EXECUTION_
33 #endif
34
35 /* cli handling */
36 int arm926ejs_register_commands(struct command_context_s *cmd_ctx);
37
38 int arm926ejs_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
39 int arm926ejs_handle_cp15i_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
40 int arm926ejs_handle_virt2phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
41 int arm926ejs_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
42 int arm926ejs_handle_md_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
43 int arm926ejs_handle_mw_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
44
45 int arm926ejs_handle_read_cache_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
46 int arm926ejs_handle_read_mmu_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
47
48 /* forward declarations */
49 int arm926ejs_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
50 int arm926ejs_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
51 int arm926ejs_quit();
52 int arm926ejs_arch_state(struct target_s *target);
53 int arm926ejs_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
54 int arm926ejs_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
55 int arm926ejs_soft_reset_halt(struct target_s *target);
56 static int arm926ejs_virt2phys(struct target_s *target, u32 virtual, u32 *physical);
57 static int arm926ejs_mmu(struct target_s *target, int *enabled);
58
59 target_type_t arm926ejs_target =
60 {
61 .name = "arm926ejs",
62
63 .poll = arm7_9_poll,
64 .arch_state = arm926ejs_arch_state,
65
66 .target_request_data = arm7_9_target_request_data,
67
68 .halt = arm7_9_halt,
69 .resume = arm7_9_resume,
70 .step = arm7_9_step,
71
72 .assert_reset = arm7_9_assert_reset,
73 .deassert_reset = arm7_9_deassert_reset,
74 .soft_reset_halt = arm926ejs_soft_reset_halt,
75 .prepare_reset_halt = arm7_9_prepare_reset_halt,
76
77 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
78
79 .read_memory = arm7_9_read_memory,
80 .write_memory = arm926ejs_write_memory,
81 .bulk_write_memory = arm7_9_bulk_write_memory,
82 .checksum_memory = arm7_9_checksum_memory,
83
84 .run_algorithm = armv4_5_run_algorithm,
85
86 .add_breakpoint = arm7_9_add_breakpoint,
87 .remove_breakpoint = arm7_9_remove_breakpoint,
88 .add_watchpoint = arm7_9_add_watchpoint,
89 .remove_watchpoint = arm7_9_remove_watchpoint,
90
91 .register_commands = arm926ejs_register_commands,
92 .target_command = arm926ejs_target_command,
93 .init_target = arm926ejs_init_target,
94 .quit = arm926ejs_quit,
95 .virt2phys = arm926ejs_virt2phys,
96 .mmu = arm926ejs_mmu
97 };
98
99
100 int arm926ejs_catch_broken_irscan(u8 *captured, void *priv, scan_field_t *field)
101 {
102 /* The ARM926EJ-S' instruction register is 4 bits wide */
103 u8 t = *captured & 0xf;
104 u8 t2 = *field->in_check_value & 0xf;
105 if (t == t2)
106 {
107 return ERROR_OK;
108 }
109 else if ((t == 0x0f) || (t == 0x00))
110 {
111 DEBUG("caught ARM926EJ-S invalid Capture-IR result after CP15 access");
112 return ERROR_OK;
113 }
114 return ERROR_JTAG_QUEUE_FAILED;;
115 }
116
117 #define ARM926EJS_CP15_ADDR(opcode_1, opcode_2, CRn, CRm) ((opcode_1 << 11) | (opcode_2 << 8) | (CRn << 4) | (CRm << 0))
118
119 int arm926ejs_cp15_read(target_t *target, u32 op1, u32 op2, u32 CRn, u32 CRm, u32 *value)
120 {
121 armv4_5_common_t *armv4_5 = target->arch_info;
122 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
123 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
124 u32 address = ARM926EJS_CP15_ADDR(op1, op2, CRn, CRm);
125 scan_field_t fields[4];
126 u8 address_buf[2];
127 u8 nr_w_buf = 0;
128 u8 access = 1;
129
130 buf_set_u32(address_buf, 0, 14, address);
131
132 jtag_add_end_state(TAP_RTI);
133 arm_jtag_scann(jtag_info, 0xf);
134 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
135
136 fields[0].device = jtag_info->chain_pos;
137 fields[0].num_bits = 32;
138 fields[0].out_value = NULL;
139 fields[0].out_mask = NULL;
140 fields[0].in_value = NULL;
141 fields[0].in_check_value = NULL;
142 fields[0].in_check_mask = NULL;
143 fields[0].in_handler = NULL;
144 fields[0].in_handler_priv = NULL;
145
146 fields[1].device = jtag_info->chain_pos;
147 fields[1].num_bits = 1;
148 fields[1].out_value = &access;
149 fields[1].out_mask = NULL;
150 fields[1].in_value = &access;
151 fields[1].in_check_value = NULL;
152 fields[1].in_check_mask = NULL;
153 fields[1].in_handler = NULL;
154 fields[1].in_handler_priv = NULL;
155
156 fields[2].device = jtag_info->chain_pos;
157 fields[2].num_bits = 14;
158 fields[2].out_value = address_buf;
159 fields[2].out_mask = NULL;
160 fields[2].in_value = NULL;
161 fields[2].in_check_value = NULL;
162 fields[2].in_check_mask = NULL;
163 fields[2].in_handler = NULL;
164 fields[2].in_handler_priv = NULL;
165
166 fields[3].device = jtag_info->chain_pos;
167 fields[3].num_bits = 1;
168 fields[3].out_value = &nr_w_buf;
169 fields[3].out_mask = NULL;
170 fields[3].in_value = NULL;
171 fields[3].in_check_value = NULL;
172 fields[3].in_check_mask = NULL;
173 fields[3].in_handler = NULL;
174 fields[3].in_handler_priv = NULL;
175
176 jtag_add_dr_scan(4, fields, -1);
177
178 fields[0].in_handler_priv = value;
179 fields[0].in_handler = arm_jtag_buf_to_u32;
180
181 do
182 {
183 /* rescan with NOP, to wait for the access to complete */
184 access = 0;
185 nr_w_buf = 0;
186 jtag_add_dr_scan(4, fields, -1);
187 jtag_execute_queue();
188 } while (buf_get_u32(&access, 0, 1) != 1);
189
190 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
191 DEBUG("addr: 0x%x value: %8.8x", address, *value);
192 #endif
193
194 arm_jtag_set_instr(jtag_info, 0xc, &arm926ejs_catch_broken_irscan);
195
196 return ERROR_OK;
197 }
198
199 int arm926ejs_cp15_write(target_t *target, u32 op1, u32 op2, u32 CRn, u32 CRm, u32 value)
200 {
201 armv4_5_common_t *armv4_5 = target->arch_info;
202 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
203 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
204 u32 address = ARM926EJS_CP15_ADDR(op1, op2, CRn, CRm);
205 scan_field_t fields[4];
206 u8 value_buf[4];
207 u8 address_buf[2];
208 u8 nr_w_buf = 1;
209 u8 access = 1;
210
211 buf_set_u32(address_buf, 0, 14, address);
212 buf_set_u32(value_buf, 0, 32, value);
213
214 jtag_add_end_state(TAP_RTI);
215 arm_jtag_scann(jtag_info, 0xf);
216 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
217
218 fields[0].device = jtag_info->chain_pos;
219 fields[0].num_bits = 32;
220 fields[0].out_value = value_buf;
221 fields[0].out_mask = NULL;
222 fields[0].in_value = NULL;
223 fields[0].in_check_value = NULL;
224 fields[0].in_check_mask = NULL;
225 fields[0].in_handler = NULL;
226 fields[0].in_handler_priv = NULL;
227
228 fields[1].device = jtag_info->chain_pos;
229 fields[1].num_bits = 1;
230 fields[1].out_value = &access;
231 fields[1].out_mask = NULL;
232 fields[1].in_value = &access;
233 fields[1].in_check_value = NULL;
234 fields[1].in_check_mask = NULL;
235 fields[1].in_handler = NULL;
236 fields[1].in_handler_priv = NULL;
237
238 fields[2].device = jtag_info->chain_pos;
239 fields[2].num_bits = 14;
240 fields[2].out_value = address_buf;
241 fields[2].out_mask = NULL;
242 fields[2].in_value = NULL;
243 fields[2].in_check_value = NULL;
244 fields[2].in_check_mask = NULL;
245 fields[2].in_handler = NULL;
246 fields[2].in_handler_priv = NULL;
247
248 fields[3].device = jtag_info->chain_pos;
249 fields[3].num_bits = 1;
250 fields[3].out_value = &nr_w_buf;
251 fields[3].out_mask = NULL;
252 fields[3].in_value = NULL;
253 fields[3].in_check_value = NULL;
254 fields[3].in_check_mask = NULL;
255 fields[3].in_handler = NULL;
256 fields[3].in_handler_priv = NULL;
257
258 jtag_add_dr_scan(4, fields, -1);
259
260 do
261 {
262 /* rescan with NOP, to wait for the access to complete */
263 access = 0;
264 nr_w_buf = 0;
265 jtag_add_dr_scan(4, fields, -1);
266 jtag_execute_queue();
267 } while (buf_get_u32(&access, 0, 1) != 1);
268
269 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
270 DEBUG("addr: 0x%x value: %8.8x", address, value);
271 #endif
272
273 arm_jtag_set_instr(jtag_info, 0xf, &arm926ejs_catch_broken_irscan);
274
275 return ERROR_OK;
276 }
277
278 int arm926ejs_examine_debug_reason(target_t *target)
279 {
280 armv4_5_common_t *armv4_5 = target->arch_info;
281 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
282 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
283 int debug_reason;
284 int retval;
285
286 embeddedice_read_reg(dbg_stat);
287 if ((retval = jtag_execute_queue()) != ERROR_OK)
288 return retval;
289
290 debug_reason = buf_get_u32(dbg_stat->value, 6, 4);
291
292 switch (debug_reason)
293 {
294 case 1:
295 DEBUG("breakpoint from EICE unit 0");
296 target->debug_reason = DBG_REASON_BREAKPOINT;
297 break;
298 case 2:
299 DEBUG("breakpoint from EICE unit 1");
300 target->debug_reason = DBG_REASON_BREAKPOINT;
301 break;
302 case 3:
303 DEBUG("soft breakpoint (BKPT instruction)");
304 target->debug_reason = DBG_REASON_BREAKPOINT;
305 break;
306 case 4:
307 DEBUG("vector catch breakpoint");
308 target->debug_reason = DBG_REASON_BREAKPOINT;
309 break;
310 case 5:
311 DEBUG("external breakpoint");
312 target->debug_reason = DBG_REASON_BREAKPOINT;
313 break;
314 case 6:
315 DEBUG("watchpoint from EICE unit 0");
316 target->debug_reason = DBG_REASON_WATCHPOINT;
317 break;
318 case 7:
319 DEBUG("watchpoint from EICE unit 1");
320 target->debug_reason = DBG_REASON_WATCHPOINT;
321 break;
322 case 8:
323 DEBUG("external watchpoint");
324 target->debug_reason = DBG_REASON_WATCHPOINT;
325 break;
326 case 9:
327 DEBUG("internal debug request");
328 target->debug_reason = DBG_REASON_DBGRQ;
329 break;
330 case 10:
331 DEBUG("external debug request");
332 target->debug_reason = DBG_REASON_DBGRQ;
333 break;
334 case 11:
335 ERROR("BUG: debug re-entry from system speed access shouldn't be handled here");
336 break;
337 default:
338 ERROR("BUG: unknown debug reason: 0x%x", debug_reason);
339 target->debug_reason = DBG_REASON_DBGRQ;
340 retval = ERROR_TARGET_FAILURE;
341 break;
342 }
343
344 return retval;
345 }
346
347 u32 arm926ejs_get_ttb(target_t *target)
348 {
349 armv4_5_common_t *armv4_5 = target->arch_info;
350 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
351 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
352 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
353 int retval;
354 u32 ttb = 0x0;
355
356 if ((retval = arm926ejs->read_cp15(target, 0, 0, 2, 0, &ttb)) != ERROR_OK)
357 return retval;
358
359 return ttb;
360 }
361
362 void arm926ejs_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
363 {
364 armv4_5_common_t *armv4_5 = target->arch_info;
365 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
366 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
367 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
368 u32 cp15_control;
369
370 /* read cp15 control register */
371 arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control);
372 jtag_execute_queue();
373
374 if (mmu)
375 {
376 /* invalidate TLB */
377 arm926ejs->write_cp15(target, 0, 0, 8, 7, 0x0);
378
379 cp15_control &= ~0x1U;
380 }
381
382 if (d_u_cache)
383 {
384 u32 debug_override;
385 /* read-modify-write CP15 debug override register
386 * to enable "test and clean all" */
387 arm926ejs->read_cp15(target, 0, 0, 15, 0, &debug_override);
388 debug_override |= 0x80000;
389 arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override);
390
391 /* clean and invalidate DCache */
392 arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0);
393
394 /* write CP15 debug override register
395 * to disable "test and clean all" */
396 debug_override &= ~0x80000;
397 arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override);
398
399 cp15_control &= ~0x4U;
400 }
401
402 if (i_cache)
403 {
404 /* invalidate ICache */
405 arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0);
406
407 cp15_control &= ~0x1000U;
408 }
409
410 arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control);
411 }
412
413 void arm926ejs_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
414 {
415 armv4_5_common_t *armv4_5 = target->arch_info;
416 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
417 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
418 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
419 u32 cp15_control;
420
421 /* read cp15 control register */
422 arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control);
423 jtag_execute_queue();
424
425 if (mmu)
426 cp15_control |= 0x1U;
427
428 if (d_u_cache)
429 cp15_control |= 0x4U;
430
431 if (i_cache)
432 cp15_control |= 0x1000U;
433
434 arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control);
435 }
436
437 void arm926ejs_post_debug_entry(target_t *target)
438 {
439 armv4_5_common_t *armv4_5 = target->arch_info;
440 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
441 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
442 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
443
444 /* examine cp15 control reg */
445 arm926ejs->read_cp15(target, 0, 0, 1, 0, &arm926ejs->cp15_control_reg);
446 jtag_execute_queue();
447 DEBUG("cp15_control_reg: %8.8x", arm926ejs->cp15_control_reg);
448
449 if (arm926ejs->armv4_5_mmu.armv4_5_cache.ctype == -1)
450 {
451 u32 cache_type_reg;
452 /* identify caches */
453 arm926ejs->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);
454 jtag_execute_queue();
455 armv4_5_identify_cache(cache_type_reg, &arm926ejs->armv4_5_mmu.armv4_5_cache);
456 }
457
458 arm926ejs->armv4_5_mmu.mmu_enabled = (arm926ejs->cp15_control_reg & 0x1U) ? 1 : 0;
459 arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm926ejs->cp15_control_reg & 0x4U) ? 1 : 0;
460 arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm926ejs->cp15_control_reg & 0x1000U) ? 1 : 0;
461
462 /* save i/d fault status and address register */
463 arm926ejs->read_cp15(target, 0, 0, 5, 0, &arm926ejs->d_fsr);
464 arm926ejs->read_cp15(target, 0, 1, 5, 0, &arm926ejs->i_fsr);
465 arm926ejs->read_cp15(target, 0, 0, 6, 0, &arm926ejs->d_far);
466
467 DEBUG("D FSR: 0x%8.8x, D FAR: 0x%8.8x, I FSR: 0x%8.8x",
468 arm926ejs->d_fsr, arm926ejs->d_far, arm926ejs->i_fsr);
469
470
471 u32 cache_dbg_ctrl;
472
473 /* read-modify-write CP15 cache debug control register
474 * to disable I/D-cache linefills and force WT */
475 arm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl);
476 cache_dbg_ctrl |= 0x7;
477 arm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl);
478 }
479
480 void arm926ejs_pre_restore_context(target_t *target)
481 {
482 armv4_5_common_t *armv4_5 = target->arch_info;
483 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
484 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
485 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
486
487 /* restore i/d fault status and address register */
488 arm926ejs->write_cp15(target, 0, 0, 5, 0, arm926ejs->d_fsr);
489 arm926ejs->write_cp15(target, 0, 1, 5, 0, arm926ejs->i_fsr);
490 arm926ejs->write_cp15(target, 0, 0, 6, 0, arm926ejs->d_far);
491
492 u32 cache_dbg_ctrl;
493
494 /* read-modify-write CP15 cache debug control register
495 * to reenable I/D-cache linefills and disable WT */
496 arm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl);
497 cache_dbg_ctrl &= ~0x7;
498 arm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl);
499 }
500
501 int arm926ejs_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm9tdmi_common_t **arm9tdmi_p, arm926ejs_common_t **arm926ejs_p)
502 {
503 armv4_5_common_t *armv4_5 = target->arch_info;
504 arm7_9_common_t *arm7_9;
505 arm9tdmi_common_t *arm9tdmi;
506 arm926ejs_common_t *arm926ejs;
507
508 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
509 {
510 return -1;
511 }
512
513 arm7_9 = armv4_5->arch_info;
514 if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
515 {
516 return -1;
517 }
518
519 arm9tdmi = arm7_9->arch_info;
520 if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
521 {
522 return -1;
523 }
524
525 arm926ejs = arm9tdmi->arch_info;
526 if (arm926ejs->common_magic != ARM926EJS_COMMON_MAGIC)
527 {
528 return -1;
529 }
530
531 *armv4_5_p = armv4_5;
532 *arm7_9_p = arm7_9;
533 *arm9tdmi_p = arm9tdmi;
534 *arm926ejs_p = arm926ejs;
535
536 return ERROR_OK;
537 }
538
539 int arm926ejs_arch_state(struct target_s *target)
540 {
541 armv4_5_common_t *armv4_5 = target->arch_info;
542 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
543 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
544 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
545
546 char *state[] =
547 {
548 "disabled", "enabled"
549 };
550
551 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
552 {
553 ERROR("BUG: called for a non-ARMv4/5 target");
554 exit(-1);
555 }
556
557 USER(
558 "target halted in %s state due to %s, current mode: %s\n"
559 "cpsr: 0x%8.8x pc: 0x%8.8x\n"
560 "MMU: %s, D-Cache: %s, I-Cache: %s",
561 armv4_5_state_strings[armv4_5->core_state],
562 target_debug_reason_strings[target->debug_reason],
563 armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
564 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
565 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
566 state[arm926ejs->armv4_5_mmu.mmu_enabled],
567 state[arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
568 state[arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
569
570 return ERROR_OK;
571 }
572
573 int arm926ejs_soft_reset_halt(struct target_s *target)
574 {
575 armv4_5_common_t *armv4_5 = target->arch_info;
576 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
577 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
578 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
579 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
580
581 if (target->state == TARGET_RUNNING)
582 {
583 target->type->halt(target);
584 }
585
586 while (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0)
587 {
588 embeddedice_read_reg(dbg_stat);
589 jtag_execute_queue();
590 }
591
592 target->state = TARGET_HALTED;
593
594 /* SVC, ARM state, IRQ and FIQ disabled */
595 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
596 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
597 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
598
599 /* start fetching from 0x0 */
600 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
601 armv4_5->core_cache->reg_list[15].dirty = 1;
602 armv4_5->core_cache->reg_list[15].valid = 1;
603
604 armv4_5->core_mode = ARMV4_5_MODE_SVC;
605 armv4_5->core_state = ARMV4_5_STATE_ARM;
606
607 arm926ejs_disable_mmu_caches(target, 1, 1, 1);
608 arm926ejs->armv4_5_mmu.mmu_enabled = 0;
609 arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
610 arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
611
612 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
613
614 return ERROR_OK;
615 }
616
617 int arm926ejs_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
618 {
619 int retval;
620 armv4_5_common_t *armv4_5 = target->arch_info;
621 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
622 arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
623 arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info;
624
625 if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK)
626 return retval;
627
628 /* If ICache is enabled, we have to invalidate affected ICache lines
629 * the DCache is forced to write-through, so we don't have to clean it here
630 */
631 if (arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
632 {
633 if (count <= 1)
634 {
635 /* invalidate ICache single entry with MVA */
636 arm926ejs->write_cp15(target, 0, 1, 7, 5, address);
637 }
638 else
639 {
640 /* invalidate ICache */
641 arm926ejs->write_cp15(target, 0, 0, 7, 5, address);
642 }
643 }
644
645 return retval;
646 }
647
648 int arm926ejs_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
649 {
650 arm9tdmi_init_target(cmd_ctx, target);
651
652 return ERROR_OK;
653
654 }
655
656 int arm926ejs_quit()
657 {
658
659 return ERROR_OK;
660 }
661
662 int arm926ejs_init_arch_info(target_t *target, arm926ejs_common_t *arm926ejs, int chain_pos, char *variant)
663 {
664 arm9tdmi_common_t *arm9tdmi = &arm926ejs->arm9tdmi_common;
665 arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
666
667 /* initialize arm9tdmi specific info (including arm7_9 and armv4_5)
668 */
669 arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
670
671 arm9tdmi->arch_info = arm926ejs;
672 arm926ejs->common_magic = ARM926EJS_COMMON_MAGIC;
673
674 arm7_9->post_debug_entry = arm926ejs_post_debug_entry;
675 arm7_9->pre_restore_context = arm926ejs_pre_restore_context;
676
677 arm926ejs->read_cp15 = arm926ejs_cp15_read;
678 arm926ejs->write_cp15 = arm926ejs_cp15_write;
679 arm926ejs->armv4_5_mmu.armv4_5_cache.ctype = -1;
680 arm926ejs->armv4_5_mmu.get_ttb = arm926ejs_get_ttb;
681 arm926ejs->armv4_5_mmu.read_memory = arm7_9_read_memory;
682 arm926ejs->armv4_5_mmu.write_memory = arm7_9_write_memory;
683 arm926ejs->armv4_5_mmu.disable_mmu_caches = arm926ejs_disable_mmu_caches;
684 arm926ejs->armv4_5_mmu.enable_mmu_caches = arm926ejs_enable_mmu_caches;
685 arm926ejs->armv4_5_mmu.has_tiny_pages = 1;
686 arm926ejs->armv4_5_mmu.mmu_enabled = 0;
687
688 arm7_9->examine_debug_reason = arm926ejs_examine_debug_reason;
689
690 /* The ARM926EJ-S implements the ARMv5TE architecture which
691 * has the BKPT instruction, so we don't have to use a watchpoint comparator
692 */
693 arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
694 arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
695
696 arm7_9->sw_bkpts_use_wp = 0;
697 arm7_9->sw_bkpts_enabled = 1;
698
699 return ERROR_OK;
700 }
701
702 int arm926ejs_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
703 {
704 int chain_pos;
705 char *variant = NULL;
706 arm926ejs_common_t *arm926ejs = malloc(sizeof(arm926ejs_common_t));
707 memset(arm926ejs, 0, sizeof(*arm926ejs));
708
709 if (argc < 4)
710 {
711 ERROR("'target arm926ejs' requires at least one additional argument");
712 exit(-1);
713 }
714
715 chain_pos = strtoul(args[3], NULL, 0);
716
717 if (argc >= 5)
718 variant = args[4];
719
720 DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
721
722 arm926ejs_init_arch_info(target, arm926ejs, chain_pos, variant);
723
724 return ERROR_OK;
725 }
726
727 int arm926ejs_register_commands(struct command_context_s *cmd_ctx)
728 {
729 int retval;
730 command_t *arm926ejs_cmd;
731
732
733 retval = arm9tdmi_register_commands(cmd_ctx);
734
735 arm926ejs_cmd = register_command(cmd_ctx, NULL, "arm926ejs", NULL, COMMAND_ANY, "arm926ejs specific commands");
736
737 register_command(cmd_ctx, arm926ejs_cmd, "cp15", arm926ejs_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <opcode_1> <opcode_2> <CRn> <CRm> [value]");
738
739 register_command(cmd_ctx, arm926ejs_cmd, "cache_info", arm926ejs_handle_cache_info_command, COMMAND_EXEC, "display information about target caches");
740 register_command(cmd_ctx, arm926ejs_cmd, "virt2phys", arm926ejs_handle_virt2phys_command, COMMAND_EXEC, "translate va to pa <va>");
741
742 register_command(cmd_ctx, arm926ejs_cmd, "mdw_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory words <physical addr> [count]");
743 register_command(cmd_ctx, arm926ejs_cmd, "mdh_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory half-words <physical addr> [count]");
744 register_command(cmd_ctx, arm926ejs_cmd, "mdb_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory bytes <physical addr> [count]");
745
746 register_command(cmd_ctx, arm926ejs_cmd, "mww_phys", arm926ejs_handle_mw_phys_command, COMMAND_EXEC, "write memory word <physical addr> <value>");
747 register_command(cmd_ctx, arm926ejs_cmd, "mwh_phys", arm926ejs_handle_mw_phys_command, COMMAND_EXEC, "write memory half-word <physical addr> <value>");
748 register_command(cmd_ctx, arm926ejs_cmd, "mwb_phys", arm926ejs_handle_mw_phys_command, COMMAND_EXEC, "write memory byte <physical addr> <value>");
749
750 return ERROR_OK;
751 }
752
753 int arm926ejs_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
754 {
755 int retval;
756 target_t *target = get_current_target(cmd_ctx);
757 armv4_5_common_t *armv4_5;
758 arm7_9_common_t *arm7_9;
759 arm9tdmi_common_t *arm9tdmi;
760 arm926ejs_common_t *arm926ejs;
761 int opcode_1;
762 int opcode_2;
763 int CRn;
764 int CRm;
765
766 if ((argc < 4) || (argc > 5))
767 {
768 command_print(cmd_ctx, "usage: arm926ejs cp15 <opcode_1> <opcode_2> <CRn> <CRm> [value]");
769 return ERROR_OK;
770 }
771
772 opcode_1 = strtoul(args[0], NULL, 0);
773 opcode_2 = strtoul(args[1], NULL, 0);
774 CRn = strtoul(args[2], NULL, 0);
775 CRm = strtoul(args[3], NULL, 0);
776
777 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
778 {
779 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
780 return ERROR_OK;
781 }
782
783 if (target->state != TARGET_HALTED)
784 {
785 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
786 return ERROR_OK;
787 }
788
789 if (argc == 4)
790 {
791 u32 value;
792 if ((retval = arm926ejs->read_cp15(target, opcode_1, opcode_2, CRn, CRm, &value)) != ERROR_OK)
793 {
794 command_print(cmd_ctx, "couldn't access register");
795 return ERROR_OK;
796 }
797 jtag_execute_queue();
798
799 command_print(cmd_ctx, "%i %i %i %i: %8.8x", opcode_1, opcode_2, CRn, CRm, value);
800 }
801 else
802 {
803 u32 value = strtoul(args[4], NULL, 0);
804 if ((retval = arm926ejs->write_cp15(target, opcode_1, opcode_2, CRn, CRm, value)) != ERROR_OK)
805 {
806 command_print(cmd_ctx, "couldn't access register");
807 return ERROR_OK;
808 }
809 command_print(cmd_ctx, "%i %i %i %i: %8.8x", opcode_1, opcode_2, CRn, CRm, value);
810 }
811
812 return ERROR_OK;
813 }
814
815 int arm926ejs_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
816 {
817 target_t *target = get_current_target(cmd_ctx);
818 armv4_5_common_t *armv4_5;
819 arm7_9_common_t *arm7_9;
820 arm9tdmi_common_t *arm9tdmi;
821 arm926ejs_common_t *arm926ejs;
822
823 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
824 {
825 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
826 return ERROR_OK;
827 }
828
829 return armv4_5_handle_cache_info_command(cmd_ctx, &arm926ejs->armv4_5_mmu.armv4_5_cache);
830 }
831
832 int arm926ejs_handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
833 {
834 target_t *target = get_current_target(cmd_ctx);
835 armv4_5_common_t *armv4_5;
836 arm7_9_common_t *arm7_9;
837 arm9tdmi_common_t *arm9tdmi;
838 arm926ejs_common_t *arm926ejs;
839 arm_jtag_t *jtag_info;
840
841 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
842 {
843 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
844 return ERROR_OK;
845 }
846
847 jtag_info = &arm7_9->jtag_info;
848
849 if (target->state != TARGET_HALTED)
850 {
851 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
852 return ERROR_OK;
853 }
854
855 return armv4_5_mmu_handle_virt2phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
856 }
857
858 int arm926ejs_handle_md_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
859 {
860 target_t *target = get_current_target(cmd_ctx);
861 armv4_5_common_t *armv4_5;
862 arm7_9_common_t *arm7_9;
863 arm9tdmi_common_t *arm9tdmi;
864 arm926ejs_common_t *arm926ejs;
865 arm_jtag_t *jtag_info;
866
867 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
868 {
869 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
870 return ERROR_OK;
871 }
872
873 jtag_info = &arm7_9->jtag_info;
874
875 if (target->state != TARGET_HALTED)
876 {
877 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
878 return ERROR_OK;
879 }
880
881 return armv4_5_mmu_handle_md_phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
882 }
883
884 int arm926ejs_handle_mw_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
885 {
886 target_t *target = get_current_target(cmd_ctx);
887 armv4_5_common_t *armv4_5;
888 arm7_9_common_t *arm7_9;
889 arm9tdmi_common_t *arm9tdmi;
890 arm926ejs_common_t *arm926ejs;
891 arm_jtag_t *jtag_info;
892
893 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
894 {
895 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
896 return ERROR_OK;
897 }
898
899 jtag_info = &arm7_9->jtag_info;
900
901 if (target->state != TARGET_HALTED)
902 {
903 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
904 return ERROR_OK;
905 }
906
907 return armv4_5_mmu_handle_mw_phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
908 }
909 static int arm926ejs_virt2phys(struct target_s *target, u32 virtual, u32 *physical)
910 {
911 int retval;
912 int type;
913 u32 cb;
914 int domain;
915 u32 ap;
916
917 armv4_5_common_t *armv4_5;
918 arm7_9_common_t *arm7_9;
919 arm9tdmi_common_t *arm9tdmi;
920 arm926ejs_common_t *arm926ejs;
921 retval= arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs);
922 if (retval != ERROR_OK)
923 {
924 return retval;
925 }
926 u32 ret = armv4_5_mmu_translate_va(target, &arm926ejs->armv4_5_mmu, virtual, &type, &cb, &domain, &ap);
927 if (type == -1)
928 {
929 return ret;
930 }
931 *physical = ret;
932 return ERROR_OK;
933 }
934
935 static int arm926ejs_mmu(struct target_s *target, int *enabled)
936 {
937 armv4_5_common_t *armv4_5 = target->arch_info;
938 arm926ejs_common_t *arm926ejs = armv4_5->arch_info;
939
940 if (target->state != TARGET_HALTED)
941 {
942 ERROR("Target not halted");
943 return ERROR_TARGET_INVALID;
944 }
945 *enabled = arm926ejs->armv4_5_mmu.mmu_enabled;
946 return ERROR_OK;
947 }

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)