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

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)