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

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)