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

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)