- improved ETB trace output
[openocd.git] / src / target / embeddedice.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "embeddedice.h"
25
26 #include "armv4_5.h"
27 #include "arm7_9_common.h"
28
29 #include "log.h"
30 #include "arm_jtag.h"
31 #include "types.h"
32 #include "binarybuffer.h"
33 #include "target.h"
34 #include "register.h"
35 #include "jtag.h"
36
37 #include <stdlib.h>
38
39 bitfield_desc_t embeddedice_comms_ctrl_bitfield_desc[] =
40 {
41 {"R", 1},
42 {"W", 1},
43 {"reserved", 26},
44 {"version", 4}
45 };
46
47 int embeddedice_reg_arch_info[] =
48 {
49 0x0, 0x1, 0x4, 0x5,
50 0x8, 0x9, 0xa, 0xb, 0xc, 0xd,
51 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
52 0x2
53 };
54
55 char* embeddedice_reg_list[] =
56 {
57 "debug_ctrl",
58 "debug_status",
59
60 "comms_ctrl",
61 "comms_data",
62
63 "watch 0 addr value",
64 "watch 0 addr mask",
65 "watch 0 data value",
66 "watch 0 data mask",
67 "watch 0 control value",
68 "watch 0 control mask",
69
70 "watch 1 addr value",
71 "watch 1 addr mask",
72 "watch 1 data value",
73 "watch 1 data mask",
74 "watch 1 control value",
75 "watch 1 control mask",
76
77 "vector catch"
78 };
79
80 int embeddedice_reg_arch_type = -1;
81
82 int embeddedice_get_reg(reg_t *reg);
83 int embeddedice_set_reg(reg_t *reg, u32 value);
84 int embeddedice_set_reg_w_exec(reg_t *reg, u8 *buf);
85
86 int embeddedice_write_reg(reg_t *reg, u32 value);
87 int embeddedice_read_reg(reg_t *reg);
88
89 int embeddedice_jtag_error_handler(u8 *in_value, void *priv)
90 {
91 char *caller = priv;
92
93 DEBUG("caller: %s", caller);
94
95 return ERROR_OK;
96 }
97
98 reg_cache_t* embeddedice_build_reg_cache(target_t *target, arm7_9_common_t *arm7_9)
99 {
100 reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
101 reg_t *reg_list = NULL;
102 embeddedice_reg_t *arch_info = NULL;
103 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
104 int num_regs;
105 int i;
106 int eice_version = 0;
107
108 /* register a register arch-type for EmbeddedICE registers only once */
109 if (embeddedice_reg_arch_type == -1)
110 embeddedice_reg_arch_type = register_reg_arch_type(embeddedice_get_reg, embeddedice_set_reg_w_exec);
111
112 if (arm7_9->has_vector_catch)
113 num_regs = 17;
114 else
115 num_regs = 16;
116
117 /* the actual registers are kept in two arrays */
118 reg_list = calloc(num_regs, sizeof(reg_t));
119 arch_info = calloc(num_regs, sizeof(embeddedice_reg_t));
120
121 /* fill in values for the reg cache */
122 reg_cache->name = "EmbeddedICE registers";
123 reg_cache->next = NULL;
124 reg_cache->reg_list = reg_list;
125 reg_cache->num_regs = num_regs;
126
127 /* set up registers */
128 for (i = 0; i < num_regs; i++)
129 {
130 reg_list[i].name = embeddedice_reg_list[i];
131 reg_list[i].size = 32;
132 reg_list[i].dirty = 0;
133 reg_list[i].valid = 0;
134 reg_list[i].bitfield_desc = NULL;
135 reg_list[i].num_bitfields = 0;
136 reg_list[i].value = calloc(1, 4);
137 reg_list[i].arch_info = &arch_info[i];
138 reg_list[i].arch_type = embeddedice_reg_arch_type;
139 arch_info[i].addr = embeddedice_reg_arch_info[i];
140 arch_info[i].jtag_info = jtag_info;
141 }
142
143 /* identify EmbeddedICE version by reading DCC control register */
144 embeddedice_read_reg(&reg_list[EICE_COMMS_CTRL]);
145 jtag_execute_queue();
146
147 eice_version = buf_get_u32(reg_list[EICE_COMMS_CTRL].value, 28, 4);
148
149 switch (eice_version)
150 {
151 case 1:
152 reg_list[EICE_DBG_CTRL].size = 3;
153 reg_list[EICE_DBG_STAT].size = 5;
154 break;
155 case 2:
156 reg_list[EICE_DBG_CTRL].size = 4;
157 reg_list[EICE_DBG_STAT].size = 5;
158 arm7_9->has_single_step = 1;
159 break;
160 case 3:
161 ERROR("EmbeddedICE version 3 detected, EmbeddedICE handling might be broken");
162 reg_list[EICE_DBG_CTRL].size = 6;
163 reg_list[EICE_DBG_STAT].size = 5;
164 arm7_9->has_single_step = 1;
165 arm7_9->has_monitor_mode = 1;
166 break;
167 case 4:
168 reg_list[EICE_DBG_CTRL].size = 6;
169 reg_list[EICE_DBG_STAT].size = 5;
170 arm7_9->has_monitor_mode = 1;
171 break;
172 case 5:
173 reg_list[EICE_DBG_CTRL].size = 6;
174 reg_list[EICE_DBG_STAT].size = 5;
175 arm7_9->has_single_step = 1;
176 arm7_9->has_monitor_mode = 1;
177 break;
178 case 6:
179 reg_list[EICE_DBG_CTRL].size = 6;
180 reg_list[EICE_DBG_STAT].size = 10;
181 arm7_9->has_monitor_mode = 1;
182 break;
183 case 7:
184 WARNING("EmbeddedICE version 7 detected, EmbeddedICE handling might be broken");
185 reg_list[EICE_DBG_CTRL].size = 6;
186 reg_list[EICE_DBG_STAT].size = 5;
187 arm7_9->has_monitor_mode = 1;
188 break;
189 default:
190 ERROR("unknown EmbeddedICE version (comms ctrl: 0x%8.8x)", buf_get_u32(reg_list[EICE_COMMS_CTRL].value, 0, 32));
191 }
192
193 /* explicitly disable monitor mode */
194 if (arm7_9->has_monitor_mode)
195 {
196 embeddedice_read_reg(&reg_list[EICE_DBG_CTRL]);
197 jtag_execute_queue();
198 buf_set_u32(reg_list[EICE_DBG_CTRL].value, 4, 1, 0);
199 embeddedice_set_reg_w_exec(&reg_list[EICE_DBG_CTRL], reg_list[EICE_DBG_CTRL].value);
200 }
201
202 return reg_cache;
203 }
204
205 int embeddedice_get_reg(reg_t *reg)
206 {
207 if (embeddedice_read_reg(reg) != ERROR_OK)
208 {
209 ERROR("BUG: error scheduling EmbeddedICE register read");
210 exit(-1);
211 }
212
213 if (jtag_execute_queue() != ERROR_OK)
214 {
215 ERROR("register read failed");
216 }
217
218 return ERROR_OK;
219 }
220
221 int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
222 {
223 embeddedice_reg_t *ice_reg = reg->arch_info;
224 u8 reg_addr = ice_reg->addr & 0x1f;
225 scan_field_t fields[3];
226 error_handler_t error_handler;
227
228 DEBUG("%i", ice_reg->addr);
229
230 jtag_add_end_state(TAP_RTI);
231 arm_jtag_scann(ice_reg->jtag_info, 0x2);
232
233 error_handler.error_handler = embeddedice_jtag_error_handler;
234 error_handler.error_handler_priv = "embeddedice_read_reg_w_check";
235
236 arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr, &error_handler);
237
238 fields[0].device = ice_reg->jtag_info->chain_pos;
239 fields[0].num_bits = 32;
240 fields[0].out_value = reg->value;
241 fields[0].out_mask = NULL;
242 fields[0].in_value = NULL;
243 fields[0].in_check_value = NULL;
244 fields[0].in_check_mask = NULL;
245 fields[0].in_handler = NULL;
246 fields[0].in_handler_priv = NULL;
247
248 fields[1].device = ice_reg->jtag_info->chain_pos;
249 fields[1].num_bits = 5;
250 fields[1].out_value = malloc(1);
251 buf_set_u32(fields[1].out_value, 0, 5, reg_addr);
252 fields[1].out_mask = NULL;
253 fields[1].in_value = NULL;
254 fields[1].in_check_value = NULL;
255 fields[1].in_check_mask = NULL;
256 fields[1].in_handler = NULL;
257 fields[1].in_handler_priv = NULL;
258
259 fields[2].device = ice_reg->jtag_info->chain_pos;
260 fields[2].num_bits = 1;
261 fields[2].out_value = malloc(1);
262 buf_set_u32(fields[2].out_value, 0, 1, 0);
263 fields[2].out_mask = NULL;
264 fields[2].in_value = NULL;
265 fields[2].in_check_value = NULL;
266 fields[2].in_check_mask = NULL;
267 fields[2].in_handler = NULL;
268 fields[2].in_handler_priv = NULL;
269
270 jtag_add_dr_scan(3, fields, -1, NULL);
271
272 fields[0].in_value = reg->value;
273 fields[0].in_check_value = check_value;
274 fields[0].in_check_mask = check_mask;
275
276 /* when reading the DCC data register, leaving the address field set to
277 * EICE_COMMS_DATA would read the register twice
278 * reading the control register is safe
279 */
280 buf_set_u32(fields[1].out_value, 0, 5, embeddedice_reg_arch_info[EICE_COMMS_CTRL]);
281
282 jtag_add_dr_scan(3, fields, -1, NULL);
283
284 free(fields[1].out_value);
285 free(fields[2].out_value);
286
287 return ERROR_OK;
288 }
289
290 int embeddedice_read_reg(reg_t *reg)
291 {
292 return embeddedice_read_reg_w_check(reg, NULL, NULL);
293 }
294
295 int embeddedice_set_reg(reg_t *reg, u32 value)
296 {
297 if (embeddedice_write_reg(reg, value) != ERROR_OK)
298 {
299 ERROR("BUG: error scheduling EmbeddedICE register write");
300 exit(-1);
301 }
302
303 buf_set_u32(reg->value, 0, reg->size, value);
304 reg->valid = 1;
305 reg->dirty = 0;
306
307 return ERROR_OK;
308 }
309
310 int embeddedice_set_reg_w_exec(reg_t *reg, u8 *buf)
311 {
312 embeddedice_set_reg(reg, buf_get_u32(buf, 0, reg->size));
313
314 if (jtag_execute_queue() != ERROR_OK)
315 {
316 ERROR("register write failed");
317 exit(-1);
318 }
319 return ERROR_OK;
320 }
321
322 int embeddedice_write_reg(reg_t *reg, u32 value)
323 {
324 embeddedice_reg_t *ice_reg = reg->arch_info;
325 u8 reg_addr = ice_reg->addr & 0x1f;
326 scan_field_t fields[3];
327 error_handler_t error_handler;
328
329 DEBUG("%i: 0x%8.8x", ice_reg->addr, value);
330
331 jtag_add_end_state(TAP_RTI);
332 arm_jtag_scann(ice_reg->jtag_info, 0x2);
333
334 error_handler.error_handler = embeddedice_jtag_error_handler;
335 error_handler.error_handler_priv = "embeddedice_write_reg";
336
337 arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr, NULL);
338
339 fields[0].device = ice_reg->jtag_info->chain_pos;
340 fields[0].num_bits = 32;
341 fields[0].out_value = malloc(4);
342 buf_set_u32(fields[0].out_value, 0, 32, value);
343 fields[0].out_mask = NULL;
344 fields[0].in_value = NULL;
345 fields[0].in_check_value = NULL;
346 fields[0].in_check_mask = NULL;
347 fields[0].in_handler = NULL;
348 fields[0].in_handler_priv = NULL;
349
350 fields[1].device = ice_reg->jtag_info->chain_pos;
351 fields[1].num_bits = 5;
352 fields[1].out_value = malloc(1);
353 buf_set_u32(fields[1].out_value, 0, 5, reg_addr);
354 fields[1].out_mask = NULL;
355 fields[1].in_value = NULL;
356 fields[1].in_check_value = NULL;
357 fields[1].in_check_mask = NULL;
358 fields[1].in_handler = NULL;
359 fields[1].in_handler_priv = NULL;
360
361 fields[2].device = ice_reg->jtag_info->chain_pos;
362 fields[2].num_bits = 1;
363 fields[2].out_value = malloc(1);
364 buf_set_u32(fields[2].out_value, 0, 1, 1);
365 fields[2].out_mask = NULL;
366 fields[2].in_value = NULL;
367 fields[2].in_check_value = NULL;
368 fields[2].in_check_mask = NULL;
369 fields[2].in_handler = NULL;
370 fields[2].in_handler_priv = NULL;
371
372 jtag_add_dr_scan(3, fields, -1, NULL);
373
374 free(fields[0].out_value);
375 free(fields[1].out_value);
376 free(fields[2].out_value);
377
378 return ERROR_OK;
379 }
380
381 int embeddedice_store_reg(reg_t *reg)
382 {
383 return embeddedice_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
384 }
385

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)