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

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)