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