target: use one second timeout while halting target at gdb attach
[fw/openocd] / src / target / arm966e.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   Copyright (C) 2008 by Spencer Oliver                                  *
6  *   spen@spen-soft.co.uk                                                  *
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, see <http://www.gnu.org/licenses/>. *
20  ***************************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "arm966e.h"
27 #include "target_type.h"
28 #include "arm_opcodes.h"
29
30 #if 0
31 #define _DEBUG_INSTRUCTION_EXECUTION_
32 #endif
33
34 int arm966e_init_arch_info(struct target *target, struct arm966e_common *arm966e, struct jtag_tap *tap)
35 {
36         struct arm7_9_common *arm7_9 = &arm966e->arm7_9_common;
37
38         /* initialize arm7/arm9 specific info (including armv4_5) */
39         arm9tdmi_init_arch_info(target, arm7_9, tap);
40
41         arm966e->common_magic = ARM966E_COMMON_MAGIC;
42
43         /* The ARM966E-S implements the ARMv5TE architecture which
44          * has the BKPT instruction, so we don't have to use a watchpoint comparator
45          */
46         arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
47         arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
48
49         return ERROR_OK;
50 }
51
52 static int arm966e_target_create(struct target *target, Jim_Interp *interp)
53 {
54         struct arm966e_common *arm966e = calloc(1, sizeof(struct arm966e_common));
55
56         return arm966e_init_arch_info(target, arm966e, target->tap);
57 }
58
59 static void arm966e_deinit_target(struct target *target)
60 {
61         struct arm *arm = target_to_arm(target);
62         struct arm966e_common *arm966e = target_to_arm966(target);
63
64         arm7_9_deinit(target);
65         arm_free_reg_cache(arm);
66         free(arm966e);
67 }
68
69 static int arm966e_verify_pointer(struct command_invocation *cmd,
70                 struct arm966e_common *arm966e)
71 {
72         if (arm966e->common_magic != ARM966E_COMMON_MAGIC) {
73                 command_print(cmd, "target is not an ARM966");
74                 return ERROR_TARGET_INVALID;
75         }
76         return ERROR_OK;
77 }
78
79 /*
80  * REVISIT:  The "read_cp15" and "write_cp15" commands could hook up
81  * to eventual mrc() and mcr() routines ... the reg_addr values being
82  * constructed (for CP15 only) from Opcode_1, Opcode_2, and CRn values.
83  * See section 7.3 of the ARM966E-S TRM.
84  */
85
86 static int arm966e_read_cp15(struct target *target, int reg_addr, uint32_t *value)
87 {
88         int retval = ERROR_OK;
89         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
90         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
91         struct scan_field fields[3];
92         uint8_t reg_addr_buf = reg_addr & 0x3f;
93         uint8_t nr_w_buf = 0;
94
95         retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
96         if (retval != ERROR_OK)
97                 return retval;
98         retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);
99         if (retval != ERROR_OK)
100                 return retval;
101
102         fields[0].num_bits = 32;
103         /* REVISIT: table 7-2 shows that bits 31-31 need to be
104          * specified for accessing BIST registers ...
105          */
106         fields[0].out_value = NULL;
107         fields[0].in_value = NULL;
108
109         fields[1].num_bits = 6;
110         fields[1].out_value = &reg_addr_buf;
111         fields[1].in_value = NULL;
112
113         fields[2].num_bits = 1;
114         fields[2].out_value = &nr_w_buf;
115         fields[2].in_value = NULL;
116
117         jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
118
119         fields[1].in_value = (uint8_t *)value;
120
121         jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
122
123         jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
124
125
126 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
127         retval = jtag_execute_queue();
128         if (retval != ERROR_OK)
129                 return retval;
130         LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
131 #endif
132
133         return ERROR_OK;
134 }
135
136 /* EXPORTED to str9x (flash) */
137 int arm966e_write_cp15(struct target *target, int reg_addr, uint32_t value)
138 {
139         int retval = ERROR_OK;
140         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
141         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
142         struct scan_field fields[3];
143         uint8_t reg_addr_buf = reg_addr & 0x3f;
144         uint8_t nr_w_buf = 1;
145         uint8_t value_buf[4];
146
147         buf_set_u32(value_buf, 0, 32, value);
148
149         retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
150         if (retval != ERROR_OK)
151                 return retval;
152         retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);
153         if (retval != ERROR_OK)
154                 return retval;
155
156         fields[0].num_bits = 32;
157         fields[0].out_value = value_buf;
158         fields[0].in_value = NULL;
159
160         fields[1].num_bits = 6;
161         fields[1].out_value = &reg_addr_buf;
162         fields[1].in_value = NULL;
163
164         fields[2].num_bits = 1;
165         fields[2].out_value = &nr_w_buf;
166         fields[2].in_value = NULL;
167
168         jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
169
170 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
171         LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
172 #endif
173
174         return ERROR_OK;
175 }
176
177 COMMAND_HANDLER(arm966e_handle_cp15_command)
178 {
179         int retval;
180         struct target *target = get_current_target(CMD_CTX);
181         struct arm966e_common *arm966e = target_to_arm966(target);
182
183         retval = arm966e_verify_pointer(CMD, arm966e);
184         if (retval != ERROR_OK)
185                 return retval;
186
187         if (target->state != TARGET_HALTED) {
188                 command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
189                 return ERROR_OK;
190         }
191
192         /* one or more argument, access a single register (write if second argument is given */
193         if (CMD_ARGC >= 1) {
194                 uint32_t address;
195                 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
196
197                 if (CMD_ARGC == 1) {
198                         uint32_t value;
199                         retval = arm966e_read_cp15(target, address, &value);
200                         if (retval != ERROR_OK) {
201                                 command_print(CMD,
202                                                 "couldn't access reg %" PRIi32,
203                                                 address);
204                                 return ERROR_OK;
205                         }
206                         retval = jtag_execute_queue();
207                         if (retval != ERROR_OK)
208                                 return retval;
209
210                         command_print(CMD, "%" PRIi32 ": %8.8" PRIx32,
211                                         address, value);
212                 } else if (CMD_ARGC == 2) {
213                         uint32_t value;
214                         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
215                         retval = arm966e_write_cp15(target, address, value);
216                         if (retval != ERROR_OK) {
217                                 command_print(CMD,
218                                                 "couldn't access reg %" PRIi32,
219                                                 address);
220                                 return ERROR_OK;
221                         }
222                         command_print(CMD, "%" PRIi32 ": %8.8" PRIx32,
223                                         address, value);
224                 }
225         }
226
227         return ERROR_OK;
228 }
229
230 static const struct command_registration arm966e_exec_command_handlers[] = {
231         {
232                 .name = "cp15",
233                 .handler = arm966e_handle_cp15_command,
234                 .mode = COMMAND_EXEC,
235                 .usage = "regnum [value]",
236                 .help = "display/modify cp15 register",
237         },
238         COMMAND_REGISTRATION_DONE
239 };
240
241 const struct command_registration arm966e_command_handlers[] = {
242         {
243                 .chain = arm9tdmi_command_handlers,
244         },
245         {
246                 .name = "arm966e",
247                 .mode = COMMAND_ANY,
248                 .help = "arm966e command group",
249                 .usage = "",
250                 .chain = arm966e_exec_command_handlers,
251         },
252         COMMAND_REGISTRATION_DONE
253 };
254
255 /** Holds methods for ARM966 targets. */
256 struct target_type arm966e_target = {
257         .name = "arm966e",
258
259         .poll = arm7_9_poll,
260         .arch_state = arm_arch_state,
261
262         .target_request_data = arm7_9_target_request_data,
263
264         .halt = arm7_9_halt,
265         .resume = arm7_9_resume,
266         .step = arm7_9_step,
267
268         .assert_reset = arm7_9_assert_reset,
269         .deassert_reset = arm7_9_deassert_reset,
270         .soft_reset_halt = arm7_9_soft_reset_halt,
271
272         .get_gdb_arch = arm_get_gdb_arch,
273         .get_gdb_reg_list = arm_get_gdb_reg_list,
274
275         .read_memory = arm7_9_read_memory,
276         .write_memory = arm7_9_write_memory_opt,
277
278         .checksum_memory = arm_checksum_memory,
279         .blank_check_memory = arm_blank_check_memory,
280
281         .run_algorithm = armv4_5_run_algorithm,
282
283         .add_breakpoint = arm7_9_add_breakpoint,
284         .remove_breakpoint = arm7_9_remove_breakpoint,
285         .add_watchpoint = arm7_9_add_watchpoint,
286         .remove_watchpoint = arm7_9_remove_watchpoint,
287
288         .commands = arm966e_command_handlers,
289         .target_create = arm966e_target_create,
290         .init_target = arm9tdmi_init_target,
291         .deinit_target = arm966e_deinit_target,
292         .examine = arm7_9_examine,
293         .check_reset = arm7_9_check_reset,
294 };