ARM926: remove exports and forward decls
[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 static int arm926ejs_quit(void)
744 {
745 return ERROR_OK;
746 }
747
748 int arm926ejs_init_arch_info(target_t *target, arm926ejs_common_t *arm926ejs,
749 jtag_tap_t *tap)
750 {
751 arm9tdmi_common_t *arm9tdmi = &arm926ejs->arm9tdmi_common;
752 arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
753
754 /* initialize arm9tdmi specific info (including arm7_9 and armv4_5)
755 */
756 arm9tdmi_init_arch_info(target, arm9tdmi, tap);
757
758 arm9tdmi->arch_info = arm926ejs;
759 arm926ejs->common_magic = ARM926EJS_COMMON_MAGIC;
760
761 arm7_9->post_debug_entry = arm926ejs_post_debug_entry;
762 arm7_9->pre_restore_context = arm926ejs_pre_restore_context;
763
764 arm926ejs->read_cp15 = arm926ejs_cp15_read;
765 arm926ejs->write_cp15 = arm926ejs_cp15_write;
766 arm926ejs->armv4_5_mmu.armv4_5_cache.ctype = -1;
767 arm926ejs->armv4_5_mmu.get_ttb = arm926ejs_get_ttb;
768 arm926ejs->armv4_5_mmu.read_memory = arm7_9_read_memory;
769 arm926ejs->armv4_5_mmu.write_memory = arm7_9_write_memory;
770 arm926ejs->armv4_5_mmu.disable_mmu_caches = arm926ejs_disable_mmu_caches;
771 arm926ejs->armv4_5_mmu.enable_mmu_caches = arm926ejs_enable_mmu_caches;
772 arm926ejs->armv4_5_mmu.has_tiny_pages = 1;
773 arm926ejs->armv4_5_mmu.mmu_enabled = 0;
774
775 arm7_9->examine_debug_reason = arm926ejs_examine_debug_reason;
776
777 /* The ARM926EJ-S implements the ARMv5TE architecture which
778 * has the BKPT instruction, so we don't have to use a watchpoint comparator
779 */
780 arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
781 arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
782
783 return ERROR_OK;
784 }
785
786 static int arm926ejs_target_create(struct target_s *target, Jim_Interp *interp)
787 {
788 arm926ejs_common_t *arm926ejs = calloc(1,sizeof(arm926ejs_common_t));
789
790 arm926ejs_init_arch_info(target, arm926ejs, target->tap);
791
792 return ERROR_OK;
793 }
794
795 static int arm926ejs_handle_cp15_command(struct command_context_s *cmd_ctx,
796 char *cmd, char **args, int argc)
797 {
798 int retval;
799 target_t *target = get_current_target(cmd_ctx);
800 armv4_5_common_t *armv4_5;
801 arm7_9_common_t *arm7_9;
802 arm9tdmi_common_t *arm9tdmi;
803 arm926ejs_common_t *arm926ejs;
804 int opcode_1;
805 int opcode_2;
806 int CRn;
807 int CRm;
808
809 if ((argc < 4) || (argc > 5))
810 {
811 command_print(cmd_ctx, "usage: arm926ejs cp15 <opcode_1> <opcode_2> <CRn> <CRm> [value]");
812 return ERROR_OK;
813 }
814
815 opcode_1 = strtoul(args[0], NULL, 0);
816 opcode_2 = strtoul(args[1], NULL, 0);
817 CRn = strtoul(args[2], NULL, 0);
818 CRm = strtoul(args[3], NULL, 0);
819
820 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
821 {
822 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
823 return ERROR_OK;
824 }
825
826 if (target->state != TARGET_HALTED)
827 {
828 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
829 return ERROR_OK;
830 }
831
832 if (argc == 4)
833 {
834 uint32_t value;
835 if ((retval = arm926ejs->read_cp15(target, opcode_1, opcode_2, CRn, CRm, &value)) != ERROR_OK)
836 {
837 command_print(cmd_ctx, "couldn't access register");
838 return ERROR_OK;
839 }
840 if ((retval = jtag_execute_queue()) != ERROR_OK)
841 {
842 return retval;
843 }
844
845 command_print(cmd_ctx, "%i %i %i %i: %8.8" PRIx32 "", opcode_1, opcode_2, CRn, CRm, value);
846 }
847 else
848 {
849 uint32_t value = strtoul(args[4], NULL, 0);
850 if ((retval = arm926ejs->write_cp15(target, opcode_1, opcode_2, CRn, CRm, value)) != ERROR_OK)
851 {
852 command_print(cmd_ctx, "couldn't access register");
853 return ERROR_OK;
854 }
855 command_print(cmd_ctx, "%i %i %i %i: %8.8" PRIx32 "", opcode_1, opcode_2, CRn, CRm, value);
856 }
857
858 return ERROR_OK;
859 }
860
861 static int
862 arm926ejs_handle_cache_info_command(struct command_context_s *cmd_ctx,
863 char *cmd, char **args, int argc)
864 {
865 target_t *target = get_current_target(cmd_ctx);
866 armv4_5_common_t *armv4_5;
867 arm7_9_common_t *arm7_9;
868 arm9tdmi_common_t *arm9tdmi;
869 arm926ejs_common_t *arm926ejs;
870
871 if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK)
872 {
873 command_print(cmd_ctx, "current target isn't an ARM926EJ-S target");
874 return ERROR_OK;
875 }
876
877 return armv4_5_handle_cache_info_command(cmd_ctx, &arm926ejs->armv4_5_mmu.armv4_5_cache);
878 }
879
880 static int arm926ejs_virt2phys(struct target_s *target, uint32_t virtual, uint32_t *physical)
881 {
882 int retval;
883 int type;
884 uint32_t cb;
885 int domain;
886 uint32_t ap;
887
888 armv4_5_common_t *armv4_5;
889 arm7_9_common_t *arm7_9;
890 arm9tdmi_common_t *arm9tdmi;
891 arm926ejs_common_t *arm926ejs;
892 retval= arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs);
893 if (retval != ERROR_OK)
894 {
895 return retval;
896 }
897 uint32_t ret = armv4_5_mmu_translate_va(target, &arm926ejs->armv4_5_mmu, virtual, &type, &cb, &domain, &ap);
898 if (type == -1)
899 {
900 return ret;
901 }
902 *physical = ret;
903 return ERROR_OK;
904 }
905
906 static int arm926ejs_mmu(struct target_s *target, int *enabled)
907 {
908 armv4_5_common_t *armv4_5 = target->arch_info;
909 arm926ejs_common_t *arm926ejs = armv4_5->arch_info;
910
911 if (target->state != TARGET_HALTED)
912 {
913 LOG_ERROR("Target not halted");
914 return ERROR_TARGET_INVALID;
915 }
916 *enabled = arm926ejs->armv4_5_mmu.mmu_enabled;
917 return ERROR_OK;
918 }
919
920 int arm926ejs_register_commands(struct command_context_s *cmd_ctx)
921 {
922 int retval;
923 command_t *arm926ejs_cmd;
924
925 retval = arm9tdmi_register_commands(cmd_ctx);
926
927 arm926ejs_cmd = register_command(cmd_ctx, NULL, "arm926ejs",
928 NULL, COMMAND_ANY,
929 "arm926ejs specific commands");
930
931 register_command(cmd_ctx, arm926ejs_cmd, "cp15",
932 arm926ejs_handle_cp15_command, COMMAND_EXEC,
933 "display/modify cp15 register "
934 "<opcode_1> <opcode_2> <CRn> <CRm> [value]");
935
936 register_command(cmd_ctx, arm926ejs_cmd, "cache_info",
937 arm926ejs_handle_cache_info_command, COMMAND_EXEC,
938 "display information about target caches");
939
940 return retval;
941 }
942
943 target_type_t arm926ejs_target =
944 {
945 .name = "arm926ejs",
946
947 .poll = arm7_9_poll,
948 .arch_state = arm926ejs_arch_state,
949
950 .target_request_data = arm7_9_target_request_data,
951
952 .halt = arm7_9_halt,
953 .resume = arm7_9_resume,
954 .step = arm7_9_step,
955
956 .assert_reset = arm7_9_assert_reset,
957 .deassert_reset = arm7_9_deassert_reset,
958 .soft_reset_halt = arm926ejs_soft_reset_halt,
959
960 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
961
962 .read_memory = arm7_9_read_memory,
963 .write_memory = arm926ejs_write_memory,
964 .bulk_write_memory = arm7_9_bulk_write_memory,
965 .checksum_memory = arm7_9_checksum_memory,
966 .blank_check_memory = arm7_9_blank_check_memory,
967
968 .run_algorithm = armv4_5_run_algorithm,
969
970 .add_breakpoint = arm7_9_add_breakpoint,
971 .remove_breakpoint = arm7_9_remove_breakpoint,
972 .add_watchpoint = arm7_9_add_watchpoint,
973 .remove_watchpoint = arm7_9_remove_watchpoint,
974
975 .register_commands = arm926ejs_register_commands,
976 .target_create = arm926ejs_target_create,
977 .init_target = arm926ejs_init_target,
978 .examine = arm9tdmi_examine,
979 .quit = arm926ejs_quit,
980 .virt2phys = arm926ejs_virt2phys,
981 .mmu = arm926ejs_mmu,
982
983 .read_phys_memory = arm926ejs_read_phys_memory,
984 .write_phys_memory = arm926ejs_write_phys_memory,
985 .mrc = arm926ejs_mrc,
986 .mcr = arm926ejs_mcr,
987 };
988

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)