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

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)