jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / target / arm720t.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2005 by Dominic Rath *
5 * Dominic.Rath@gmx.de *
6 * *
7 * Copyright (C) 2009 by Øyvind Harboe *
8 * oyvind.harboe@zylin.com *
9 ***************************************************************************/
10
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
14
15 #include "arm720t.h"
16 #include <helper/time_support.h>
17 #include "target_type.h"
18 #include "register.h"
19 #include "arm_opcodes.h"
20
21
22 /*
23 * ARM720 is an ARM7TDMI-S with MMU and ETM7. For information, see
24 * ARM DDI 0229C especially Chapter 9 about debug support.
25 */
26
27 #if 0
28 #define _DEBUG_INSTRUCTION_EXECUTION_
29 #endif
30
31 static int arm720t_scan_cp15(struct target *target,
32 uint32_t out, uint32_t *in, int instruction, int clock_arg)
33 {
34 int retval;
35 struct arm720t_common *arm720t = target_to_arm720(target);
36 struct arm_jtag *jtag_info;
37 struct scan_field fields[2];
38 uint8_t out_buf[4];
39 uint8_t instruction_buf = instruction;
40
41 jtag_info = &arm720t->arm7_9_common.jtag_info;
42
43 buf_set_u32(out_buf, 0, 32, flip_u32(out, 32));
44
45 retval = arm_jtag_scann(jtag_info, 0xf, TAP_DRPAUSE);
46 if (retval != ERROR_OK)
47 return retval;
48 retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
49 if (retval != ERROR_OK)
50 return retval;
51
52 fields[0].num_bits = 1;
53 fields[0].out_value = &instruction_buf;
54 fields[0].in_value = NULL;
55
56 fields[1].num_bits = 32;
57 fields[1].out_value = out_buf;
58 fields[1].in_value = NULL;
59
60 if (in) {
61 fields[1].in_value = (uint8_t *)in;
62 jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);
63 jtag_add_callback(arm7flip32, (jtag_callback_data_t)in);
64 } else
65 jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);
66
67 if (clock_arg)
68 jtag_add_runtest(0, TAP_DRPAUSE);
69
70 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
71 retval = jtag_execute_queue();
72 if (retval != ERROR_OK)
73 return retval;
74
75 if (in)
76 LOG_DEBUG("out: %8.8x, in: %8.8x, instruction: %i, clock: %i", out, *in, instruction, clock);
77 else
78 LOG_DEBUG("out: %8.8x, instruction: %i, clock: %i", out, instruction, clock_arg);
79 #else
80 LOG_DEBUG("out: %8.8" PRIx32 ", instruction: %i, clock: %i", out, instruction, clock_arg);
81 #endif
82
83 return ERROR_OK;
84 }
85
86 static int arm720t_read_cp15(struct target *target, uint32_t opcode, uint32_t *value)
87 {
88 /* fetch CP15 opcode */
89 arm720t_scan_cp15(target, opcode, NULL, 1, 1);
90 /* "DECODE" stage */
91 arm720t_scan_cp15(target, ARMV4_5_NOP, NULL, 1, 1);
92 /* "EXECUTE" stage (1) */
93 arm720t_scan_cp15(target, ARMV4_5_NOP, NULL, 1, 0);
94 arm720t_scan_cp15(target, 0x0, NULL, 0, 1);
95 /* "EXECUTE" stage (2) */
96 arm720t_scan_cp15(target, 0x0, NULL, 0, 1);
97 /* "EXECUTE" stage (3), CDATA is read */
98 arm720t_scan_cp15(target, ARMV4_5_NOP, value, 1, 1);
99
100 return ERROR_OK;
101 }
102
103 static int arm720t_write_cp15(struct target *target, uint32_t opcode, uint32_t value)
104 {
105 /* fetch CP15 opcode */
106 arm720t_scan_cp15(target, opcode, NULL, 1, 1);
107 /* "DECODE" stage */
108 arm720t_scan_cp15(target, ARMV4_5_NOP, NULL, 1, 1);
109 /* "EXECUTE" stage (1) */
110 arm720t_scan_cp15(target, ARMV4_5_NOP, NULL, 1, 0);
111 arm720t_scan_cp15(target, 0x0, NULL, 0, 1);
112 /* "EXECUTE" stage (2) */
113 arm720t_scan_cp15(target, value, NULL, 0, 1);
114 arm720t_scan_cp15(target, ARMV4_5_NOP, NULL, 1, 1);
115
116 return ERROR_OK;
117 }
118
119 static int arm720t_get_ttb(struct target *target, uint32_t *result)
120 {
121 uint32_t ttb = 0x0;
122
123 int retval;
124
125 retval = arm720t_read_cp15(target, 0xee120f10, &ttb);
126 if (retval != ERROR_OK)
127 return retval;
128 retval = jtag_execute_queue();
129 if (retval != ERROR_OK)
130 return retval;
131
132 ttb &= 0xffffc000;
133
134 *result = ttb;
135
136 return ERROR_OK;
137 }
138
139 static int arm720t_disable_mmu_caches(struct target *target,
140 int mmu, int d_u_cache, int i_cache)
141 {
142 uint32_t cp15_control;
143 int retval;
144
145 /* read cp15 control register */
146 retval = arm720t_read_cp15(target, 0xee110f10, &cp15_control);
147 if (retval != ERROR_OK)
148 return retval;
149 retval = jtag_execute_queue();
150 if (retval != ERROR_OK)
151 return retval;
152
153 if (mmu)
154 cp15_control &= ~0x1U;
155
156 if (d_u_cache || i_cache)
157 cp15_control &= ~0x4U;
158
159 retval = arm720t_write_cp15(target, 0xee010f10, cp15_control);
160 return retval;
161 }
162
163 static int arm720t_enable_mmu_caches(struct target *target,
164 int mmu, int d_u_cache, int i_cache)
165 {
166 uint32_t cp15_control;
167 int retval;
168
169 /* read cp15 control register */
170 retval = arm720t_read_cp15(target, 0xee110f10, &cp15_control);
171 if (retval != ERROR_OK)
172 return retval;
173 retval = jtag_execute_queue();
174 if (retval != ERROR_OK)
175 return retval;
176
177 if (mmu)
178 cp15_control |= 0x1U;
179
180 if (d_u_cache || i_cache)
181 cp15_control |= 0x4U;
182
183 retval = arm720t_write_cp15(target, 0xee010f10, cp15_control);
184 return retval;
185 }
186
187 static int arm720t_post_debug_entry(struct target *target)
188 {
189 struct arm720t_common *arm720t = target_to_arm720(target);
190 int retval;
191
192 /* examine cp15 control reg */
193 retval = arm720t_read_cp15(target, 0xee110f10, &arm720t->cp15_control_reg);
194 if (retval != ERROR_OK)
195 return retval;
196 retval = jtag_execute_queue();
197 if (retval != ERROR_OK)
198 return retval;
199 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32 "", arm720t->cp15_control_reg);
200
201 arm720t->armv4_5_mmu.mmu_enabled = (arm720t->cp15_control_reg & 0x1U) ? 1 : 0;
202 arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm720t->cp15_control_reg & 0x4U) ? 1 : 0;
203 arm720t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
204
205 /* save i/d fault status and address register */
206 retval = arm720t_read_cp15(target, 0xee150f10, &arm720t->fsr_reg);
207 if (retval != ERROR_OK)
208 return retval;
209 retval = arm720t_read_cp15(target, 0xee160f10, &arm720t->far_reg);
210 if (retval != ERROR_OK)
211 return retval;
212 retval = jtag_execute_queue();
213 return retval;
214 }
215
216 static void arm720t_pre_restore_context(struct target *target)
217 {
218 struct arm720t_common *arm720t = target_to_arm720(target);
219
220 /* restore i/d fault status and address register */
221 arm720t_write_cp15(target, 0xee050f10, arm720t->fsr_reg);
222 arm720t_write_cp15(target, 0xee060f10, arm720t->far_reg);
223 }
224
225 static int arm720t_arch_state(struct target *target)
226 {
227 struct arm720t_common *arm720t = target_to_arm720(target);
228
229 static const char *state[] = {
230 "disabled", "enabled"
231 };
232
233 arm_arch_state(target);
234 LOG_USER("MMU: %s, Cache: %s",
235 state[arm720t->armv4_5_mmu.mmu_enabled],
236 state[arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled]);
237
238 return ERROR_OK;
239 }
240
241 static int arm720_mmu(struct target *target, int *enabled)
242 {
243 if (target->state != TARGET_HALTED) {
244 LOG_ERROR("%s: target not halted", __func__);
245 return ERROR_TARGET_INVALID;
246 }
247
248 *enabled = target_to_arm720(target)->armv4_5_mmu.mmu_enabled;
249 return ERROR_OK;
250 }
251
252 static int arm720_virt2phys(struct target *target,
253 target_addr_t virtual, target_addr_t *physical)
254 {
255 uint32_t cb;
256 struct arm720t_common *arm720t = target_to_arm720(target);
257
258 uint32_t ret;
259 int retval = armv4_5_mmu_translate_va(target,
260 &arm720t->armv4_5_mmu, virtual, &cb, &ret);
261 if (retval != ERROR_OK)
262 return retval;
263 *physical = ret;
264 return ERROR_OK;
265 }
266
267 static int arm720t_read_memory(struct target *target,
268 target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
269 {
270 int retval;
271 struct arm720t_common *arm720t = target_to_arm720(target);
272
273 /* disable cache, but leave MMU enabled */
274 if (arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) {
275 retval = arm720t_disable_mmu_caches(target, 0, 1, 0);
276 if (retval != ERROR_OK)
277 return retval;
278 }
279 retval = arm7_9_read_memory(target, address, size, count, buffer);
280
281 if (arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) {
282 retval = arm720t_enable_mmu_caches(target, 0, 1, 0);
283 if (retval != ERROR_OK)
284 return retval;
285 }
286
287 return retval;
288 }
289
290 static int arm720t_read_phys_memory(struct target *target,
291 target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
292 {
293 struct arm720t_common *arm720t = target_to_arm720(target);
294
295 return armv4_5_mmu_read_physical(target, &arm720t->armv4_5_mmu, address, size, count, buffer);
296 }
297
298 static int arm720t_write_phys_memory(struct target *target,
299 target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
300 {
301 struct arm720t_common *arm720t = target_to_arm720(target);
302
303 return armv4_5_mmu_write_physical(target, &arm720t->armv4_5_mmu, address, size, count, buffer);
304 }
305
306 static int arm720t_soft_reset_halt(struct target *target)
307 {
308 int retval = ERROR_OK;
309 struct arm720t_common *arm720t = target_to_arm720(target);
310 struct reg *dbg_stat = &arm720t->arm7_9_common
311 .eice_cache->reg_list[EICE_DBG_STAT];
312 struct arm *arm = &arm720t->arm7_9_common.arm;
313
314 retval = target_halt(target);
315 if (retval != ERROR_OK)
316 return retval;
317
318 int64_t then = timeval_ms();
319 int timeout;
320 while (!(timeout = ((timeval_ms()-then) > 1000))) {
321 if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) {
322 embeddedice_read_reg(dbg_stat);
323 retval = jtag_execute_queue();
324 if (retval != ERROR_OK)
325 return retval;
326 } else
327 break;
328 if (debug_level >= 3)
329 alive_sleep(100);
330 else
331 keep_alive();
332 }
333 if (timeout) {
334 LOG_ERROR("Failed to halt CPU after 1 sec");
335 return ERROR_TARGET_TIMEOUT;
336 }
337
338 target->state = TARGET_HALTED;
339
340 /* SVC, ARM state, IRQ and FIQ disabled */
341 uint32_t cpsr;
342
343 cpsr = buf_get_u32(arm->cpsr->value, 0, 32);
344 cpsr &= ~0xff;
345 cpsr |= 0xd3;
346 arm_set_cpsr(arm, cpsr);
347 arm->cpsr->dirty = true;
348
349 /* start fetching from 0x0 */
350 buf_set_u32(arm->pc->value, 0, 32, 0x0);
351 arm->pc->dirty = true;
352 arm->pc->valid = true;
353
354 retval = arm720t_disable_mmu_caches(target, 1, 1, 1);
355 if (retval != ERROR_OK)
356 return retval;
357 arm720t->armv4_5_mmu.mmu_enabled = 0;
358 arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
359 arm720t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
360
361 retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED);
362 if (retval != ERROR_OK)
363 return retval;
364
365 return ERROR_OK;
366 }
367
368 static int arm720t_init_target(struct command_context *cmd_ctx, struct target *target)
369 {
370 return arm7tdmi_init_target(cmd_ctx, target);
371 }
372
373 static void arm720t_deinit_target(struct target *target)
374 {
375 arm7tdmi_deinit_target(target);
376 }
377
378 /* FIXME remove forward decls */
379 static int arm720t_mrc(struct target *target, int cpnum,
380 uint32_t op1, uint32_t op2,
381 uint32_t crn, uint32_t crm,
382 uint32_t *value);
383 static int arm720t_mcr(struct target *target, int cpnum,
384 uint32_t op1, uint32_t op2,
385 uint32_t crn, uint32_t crm,
386 uint32_t value);
387
388 static int arm720t_init_arch_info(struct target *target,
389 struct arm720t_common *arm720t, struct jtag_tap *tap)
390 {
391 struct arm7_9_common *arm7_9 = &arm720t->arm7_9_common;
392
393 arm7_9->arm.mrc = arm720t_mrc;
394 arm7_9->arm.mcr = arm720t_mcr;
395
396 arm7tdmi_init_arch_info(target, arm7_9, tap);
397
398 arm720t->common_magic = ARM720T_COMMON_MAGIC;
399
400 arm7_9->post_debug_entry = arm720t_post_debug_entry;
401 arm7_9->pre_restore_context = arm720t_pre_restore_context;
402
403 arm720t->armv4_5_mmu.armv4_5_cache.ctype = -1;
404 arm720t->armv4_5_mmu.get_ttb = arm720t_get_ttb;
405 arm720t->armv4_5_mmu.read_memory = arm7_9_read_memory;
406 arm720t->armv4_5_mmu.write_memory = arm7_9_write_memory;
407 arm720t->armv4_5_mmu.disable_mmu_caches = arm720t_disable_mmu_caches;
408 arm720t->armv4_5_mmu.enable_mmu_caches = arm720t_enable_mmu_caches;
409 arm720t->armv4_5_mmu.has_tiny_pages = 0;
410 arm720t->armv4_5_mmu.mmu_enabled = 0;
411
412 return ERROR_OK;
413 }
414
415 static int arm720t_target_create(struct target *target, Jim_Interp *interp)
416 {
417 struct arm720t_common *arm720t = calloc(1, sizeof(*arm720t));
418
419 arm720t->arm7_9_common.arm.arch = ARM_ARCH_V4;
420 return arm720t_init_arch_info(target, arm720t, target->tap);
421 }
422
423 static int arm720t_mrc(struct target *target, int cpnum,
424 uint32_t op1, uint32_t op2,
425 uint32_t crn, uint32_t crm,
426 uint32_t *value)
427 {
428 if (cpnum != 15) {
429 LOG_ERROR("Only cp15 is supported");
430 return ERROR_FAIL;
431 }
432
433 /* read "to" r0 */
434 return arm720t_read_cp15(target,
435 ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2),
436 value);
437
438 }
439
440 static int arm720t_mcr(struct target *target, int cpnum,
441 uint32_t op1, uint32_t op2,
442 uint32_t crn, uint32_t crm,
443 uint32_t value)
444 {
445 if (cpnum != 15) {
446 LOG_ERROR("Only cp15 is supported");
447 return ERROR_FAIL;
448 }
449
450 /* write "from" r0 */
451 return arm720t_write_cp15(target,
452 ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2),
453 value);
454 }
455
456 static const struct command_registration arm720t_command_handlers[] = {
457 {
458 .chain = arm7_9_command_handlers,
459 },
460 COMMAND_REGISTRATION_DONE
461 };
462
463 /** Holds methods for ARM720 targets. */
464 struct target_type arm720t_target = {
465 .name = "arm720t",
466
467 .poll = arm7_9_poll,
468 .arch_state = arm720t_arch_state,
469
470 .halt = arm7_9_halt,
471 .resume = arm7_9_resume,
472 .step = arm7_9_step,
473
474 .assert_reset = arm7_9_assert_reset,
475 .deassert_reset = arm7_9_deassert_reset,
476 .soft_reset_halt = arm720t_soft_reset_halt,
477
478 .get_gdb_arch = arm_get_gdb_arch,
479 .get_gdb_reg_list = arm_get_gdb_reg_list,
480
481 .read_memory = arm720t_read_memory,
482 .write_memory = arm7_9_write_memory_opt,
483 .read_phys_memory = arm720t_read_phys_memory,
484 .write_phys_memory = arm720t_write_phys_memory,
485 .mmu = arm720_mmu,
486 .virt2phys = arm720_virt2phys,
487
488 .checksum_memory = arm_checksum_memory,
489 .blank_check_memory = arm_blank_check_memory,
490
491 .run_algorithm = armv4_5_run_algorithm,
492
493 .add_breakpoint = arm7_9_add_breakpoint,
494 .remove_breakpoint = arm7_9_remove_breakpoint,
495 .add_watchpoint = arm7_9_add_watchpoint,
496 .remove_watchpoint = arm7_9_remove_watchpoint,
497
498 .commands = arm720t_command_handlers,
499 .target_create = arm720t_target_create,
500 .init_target = arm720t_init_target,
501 .deinit_target = arm720t_deinit_target,
502 .examine = arm7_9_examine,
503 .check_reset = arm7_9_check_reset,
504 };

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)