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

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)