- added support for error handlers to JTAG scan commands (jtag_[plain_][ir|dr]_scan)
[openocd.git] / src / target / etm.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 "etm.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 etm_comms_ctrl_bitfield_desc[] =
40 {
41 {"R", 1},
42 {"W", 1},
43 {"reserved", 26},
44 {"version", 4}
45 };
46
47 int etm_reg_arch_info[] =
48 {
49 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
50 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
51 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
52 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
53 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
54 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
55 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
56 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
57 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
58 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
59 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
60 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
61 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x67,
62 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
63 };
64
65 int etm_reg_arch_size_info[] =
66 {
67 32, 32, 17, 8, 3, 9, 32, 16,
68 17, 26, 25, 8, 17, 32, 32, 17,
69 32, 32, 32, 32, 32, 32, 32, 32,
70 32, 32, 32, 32, 32, 32, 32, 32,
71 7, 7, 7, 7, 7, 7, 7, 7,
72 7, 7, 7, 7, 7, 7, 7, 7,
73 32, 32, 32, 32, 32, 32, 32, 32,
74 32, 32, 32, 32, 32, 32, 32, 32,
75 32, 32, 32, 32, 32, 32, 32, 32,
76 32, 32, 32, 32, 32, 32, 32, 32,
77 16, 16, 16, 16, 18, 18, 18, 18,
78 17, 17, 17, 17, 16, 16, 16, 16,
79 17, 17, 17, 17, 17, 17, 2,
80 17, 17, 17, 17, 32, 32, 32, 32
81 };
82
83 char* etm_reg_list[] =
84 {
85 "ETM_CTRL",
86 "ETM_CONFIG",
87 "ETM_TRIG_EVENT",
88 "ETM_MMD_CTRL",
89 "ETM_STATUS",
90 "ETM_SYS_CONFIG",
91 "ETM_TRACE_RESOURCE_CTRL",
92 "ETM_TRACE_EN_CTRL2",
93 "ETM_TRACE_EN_EVENT",
94 "ETM_TRACE_EN_CTRL1",
95 "ETM_FIFOFULL_REGION",
96 "ETM_FIFOFULL_LEVEL",
97 "ETM_VIEWDATA_EVENT",
98 "ETM_VIEWDATA_CTRL1",
99 "ETM_VIEWDATA_CTRL2",
100 "ETM_VIEWDATA_CTRL3",
101 "ETM_ADDR_COMPARATOR_VALUE1",
102 "ETM_ADDR_COMPARATOR_VALUE2",
103 "ETM_ADDR_COMPARATOR_VALUE3",
104 "ETM_ADDR_COMPARATOR_VALUE4",
105 "ETM_ADDR_COMPARATOR_VALUE5",
106 "ETM_ADDR_COMPARATOR_VALUE6",
107 "ETM_ADDR_COMPARATOR_VALUE7",
108 "ETM_ADDR_COMPARATOR_VALUE8",
109 "ETM_ADDR_COMPARATOR_VALUE9",
110 "ETM_ADDR_COMPARATOR_VALUE10",
111 "ETM_ADDR_COMPARATOR_VALUE11",
112 "ETM_ADDR_COMPARATOR_VALUE12",
113 "ETM_ADDR_COMPARATOR_VALUE13",
114 "ETM_ADDR_COMPARATOR_VALUE14",
115 "ETM_ADDR_COMPARATOR_VALUE15",
116 "ETM_ADDR_COMPARATOR_VALUE16",
117 "ETM_ADDR_ACCESS_TYPE1",
118 "ETM_ADDR_ACCESS_TYPE2",
119 "ETM_ADDR_ACCESS_TYPE3",
120 "ETM_ADDR_ACCESS_TYPE4",
121 "ETM_ADDR_ACCESS_TYPE5",
122 "ETM_ADDR_ACCESS_TYPE6",
123 "ETM_ADDR_ACCESS_TYPE7",
124 "ETM_ADDR_ACCESS_TYPE8",
125 "ETM_ADDR_ACCESS_TYPE9",
126 "ETM_ADDR_ACCESS_TYPE10",
127 "ETM_ADDR_ACCESS_TYPE11",
128 "ETM_ADDR_ACCESS_TYPE12",
129 "ETM_ADDR_ACCESS_TYPE13",
130 "ETM_ADDR_ACCESS_TYPE14",
131 "ETM_ADDR_ACCESS_TYPE15",
132 "ETM_ADDR_ACCESS_TYPE16",
133 "ETM_DATA_COMPARATOR_VALUE1",
134 "ETM_DATA_COMPARATOR_VALUE2",
135 "ETM_DATA_COMPARATOR_VALUE3",
136 "ETM_DATA_COMPARATOR_VALUE4",
137 "ETM_DATA_COMPARATOR_VALUE5",
138 "ETM_DATA_COMPARATOR_VALUE6",
139 "ETM_DATA_COMPARATOR_VALUE7",
140 "ETM_DATA_COMPARATOR_VALUE8",
141 "ETM_DATA_COMPARATOR_VALUE9",
142 "ETM_DATA_COMPARATOR_VALUE10",
143 "ETM_DATA_COMPARATOR_VALUE11",
144 "ETM_DATA_COMPARATOR_VALUE12",
145 "ETM_DATA_COMPARATOR_VALUE13",
146 "ETM_DATA_COMPARATOR_VALUE14",
147 "ETM_DATA_COMPARATOR_VALUE15",
148 "ETM_DATA_COMPARATOR_VALUE16",
149 "ETM_DATA_COMPARATOR_MASK1",
150 "ETM_DATA_COMPARATOR_MASK2",
151 "ETM_DATA_COMPARATOR_MASK3",
152 "ETM_DATA_COMPARATOR_MASK4",
153 "ETM_DATA_COMPARATOR_MASK5",
154 "ETM_DATA_COMPARATOR_MASK6",
155 "ETM_DATA_COMPARATOR_MASK7",
156 "ETM_DATA_COMPARATOR_MASK8",
157 "ETM_DATA_COMPARATOR_MASK9",
158 "ETM_DATA_COMPARATOR_MASK10",
159 "ETM_DATA_COMPARATOR_MASK11",
160 "ETM_DATA_COMPARATOR_MASK12",
161 "ETM_DATA_COMPARATOR_MASK13",
162 "ETM_DATA_COMPARATOR_MASK14",
163 "ETM_DATA_COMPARATOR_MASK15",
164 "ETM_DATA_COMPARATOR_MASK16",
165 "ETM_COUNTER_INITAL_VALUE1",
166 "ETM_COUNTER_INITAL_VALUE2",
167 "ETM_COUNTER_INITAL_VALUE3",
168 "ETM_COUNTER_INITAL_VALUE4",
169 "ETM_COUNTER_ENABLE1",
170 "ETM_COUNTER_ENABLE2",
171 "ETM_COUNTER_ENABLE3",
172 "ETM_COUNTER_ENABLE4",
173 "ETM_COUNTER_RELOAD_VALUE1",
174 "ETM_COUNTER_RELOAD_VALUE2",
175 "ETM_COUNTER_RELOAD_VALUE3",
176 "ETM_COUNTER_RELOAD_VALUE4",
177 "ETM_COUNTER_VALUE1",
178 "ETM_COUNTER_VALUE2",
179 "ETM_COUNTER_VALUE3",
180 "ETM_COUNTER_VALUE4",
181 "ETM_SEQUENCER_CTRL1",
182 "ETM_SEQUENCER_CTRL2",
183 "ETM_SEQUENCER_CTRL3",
184 "ETM_SEQUENCER_CTRL4",
185 "ETM_SEQUENCER_CTRL5",
186 "ETM_SEQUENCER_CTRL6",
187 "ETM_SEQUENCER_STATE",
188 "ETM_EXTERNAL_OUTPUT1",
189 "ETM_EXTERNAL_OUTPUT2",
190 "ETM_EXTERNAL_OUTPUT3",
191 "ETM_EXTERNAL_OUTPUT4",
192 "ETM_CONTEXTID_COMPARATOR_VALUE1",
193 "ETM_CONTEXTID_COMPARATOR_VALUE2",
194 "ETM_CONTEXTID_COMPARATOR_VALUE3",
195 "ETM_CONTEXTID_COMPARATOR_MASK"
196 };
197
198 int etm_reg_arch_type = -1;
199
200 int etm_get_reg(reg_t *reg);
201 int etm_set_reg(reg_t *reg, u32 value);
202 int etm_set_reg_w_exec(reg_t *reg, u8 *buf);
203
204 int etm_write_reg(reg_t *reg, u32 value);
205 int etm_read_reg(reg_t *reg);
206
207 reg_cache_t* etm_build_reg_cache(target_t *target, arm_jtag_t *jtag_info, int extra_reg)
208 {
209 reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
210 reg_t *reg_list = NULL;
211 etm_reg_t *arch_info = NULL;
212 int num_regs = sizeof(etm_reg_arch_info)/sizeof(int);
213 int i;
214
215 /* register a register arch-type for etm registers only once */
216 if (etm_reg_arch_type == -1)
217 etm_reg_arch_type = register_reg_arch_type(etm_get_reg, etm_set_reg_w_exec);
218
219 /* the actual registers are kept in two arrays */
220 reg_list = calloc(num_regs, sizeof(reg_t));
221 arch_info = calloc(num_regs, sizeof(etm_reg_t));
222
223 /* fill in values for the reg cache */
224 reg_cache->name = "etm registers";
225 reg_cache->next = NULL;
226 reg_cache->reg_list = reg_list;
227 reg_cache->num_regs = num_regs;
228
229 /* set up registers */
230 for (i = 0; i < num_regs; i++)
231 {
232 reg_list[i].name = etm_reg_list[i];
233 reg_list[i].size = 32;
234 reg_list[i].dirty = 0;
235 reg_list[i].valid = 0;
236 reg_list[i].bitfield_desc = NULL;
237 reg_list[i].num_bitfields = 0;
238 reg_list[i].value = calloc(1, 4);
239 reg_list[i].arch_info = &arch_info[i];
240 reg_list[i].arch_type = etm_reg_arch_type;
241 reg_list[i].size = etm_reg_arch_size_info[i];
242 arch_info[i].addr = etm_reg_arch_info[i];
243 arch_info[i].jtag_info = jtag_info;
244 }
245 return reg_cache;
246 }
247
248 int etm_get_reg(reg_t *reg)
249 {
250 if (etm_read_reg(reg) != ERROR_OK)
251 {
252 ERROR("BUG: error scheduling etm register read");
253 exit(-1);
254 }
255
256 if (jtag_execute_queue() != ERROR_OK)
257 {
258 ERROR("register read failed");
259 }
260
261 return ERROR_OK;
262 }
263
264 int etm_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
265 {
266 etm_reg_t *etm_reg = reg->arch_info;
267 u8 reg_addr = etm_reg->addr & 0x7f;
268 scan_field_t fields[3];
269
270 DEBUG("%i", etm_reg->addr);
271
272 jtag_add_end_state(TAP_RTI);
273 arm_jtag_scann(etm_reg->jtag_info, 0x6);
274 arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL);
275
276 fields[0].device = etm_reg->jtag_info->chain_pos;
277 fields[0].num_bits = 32;
278 fields[0].out_value = reg->value;
279 fields[0].out_mask = NULL;
280 fields[0].in_value = NULL;
281 fields[0].in_check_value = NULL;
282 fields[0].in_check_mask = NULL;
283 fields[0].in_handler = NULL;
284 fields[0].in_handler_priv = NULL;
285
286 fields[1].device = etm_reg->jtag_info->chain_pos;
287 fields[1].num_bits = 7;
288 fields[1].out_value = malloc(1);
289 buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
290 fields[1].out_mask = NULL;
291 fields[1].in_value = NULL;
292 fields[1].in_check_value = NULL;
293 fields[1].in_check_mask = NULL;
294 fields[1].in_handler = NULL;
295 fields[1].in_handler_priv = NULL;
296
297 fields[2].device = etm_reg->jtag_info->chain_pos;
298 fields[2].num_bits = 1;
299 fields[2].out_value = malloc(1);
300 buf_set_u32(fields[2].out_value, 0, 1, 0);
301 fields[2].out_mask = NULL;
302 fields[2].in_value = NULL;
303 fields[2].in_check_value = NULL;
304 fields[2].in_check_mask = NULL;
305 fields[2].in_handler = NULL;
306 fields[2].in_handler_priv = NULL;
307
308 jtag_add_dr_scan(3, fields, -1, NULL);
309
310 fields[0].in_value = reg->value;
311 fields[0].in_check_value = check_value;
312 fields[0].in_check_mask = check_mask;
313
314 jtag_add_dr_scan(3, fields, -1, NULL);
315
316 free(fields[1].out_value);
317 free(fields[2].out_value);
318
319 return ERROR_OK;
320 }
321
322 int etm_read_reg(reg_t *reg)
323 {
324 return etm_read_reg_w_check(reg, NULL, NULL);
325 }
326
327 int etm_set_reg(reg_t *reg, u32 value)
328 {
329 if (etm_write_reg(reg, value) != ERROR_OK)
330 {
331 ERROR("BUG: error scheduling etm register write");
332 exit(-1);
333 }
334
335 buf_set_u32(reg->value, 0, reg->size, value);
336 reg->valid = 1;
337 reg->dirty = 0;
338
339 return ERROR_OK;
340 }
341
342 int etm_set_reg_w_exec(reg_t *reg, u8 *buf)
343 {
344 etm_set_reg(reg, buf_get_u32(buf, 0, reg->size));
345
346 if (jtag_execute_queue() != ERROR_OK)
347 {
348 ERROR("register write failed");
349 exit(-1);
350 }
351 return ERROR_OK;
352 }
353
354 int etm_write_reg(reg_t *reg, u32 value)
355 {
356 etm_reg_t *etm_reg = reg->arch_info;
357 u8 reg_addr = etm_reg->addr & 0x7f;
358 scan_field_t fields[3];
359
360 DEBUG("%i: 0x%8.8x", etm_reg->addr, value);
361
362 jtag_add_end_state(TAP_RTI);
363 arm_jtag_scann(etm_reg->jtag_info, 0x6);
364 arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL);
365
366 fields[0].device = etm_reg->jtag_info->chain_pos;
367 fields[0].num_bits = 32;
368 fields[0].out_value = malloc(4);
369 buf_set_u32(fields[0].out_value, 0, 32, value);
370 fields[0].out_mask = NULL;
371 fields[0].in_value = NULL;
372 fields[0].in_check_value = NULL;
373 fields[0].in_check_mask = NULL;
374 fields[0].in_handler = NULL;
375 fields[0].in_handler_priv = NULL;
376
377 fields[1].device = etm_reg->jtag_info->chain_pos;
378 fields[1].num_bits = 7;
379 fields[1].out_value = malloc(1);
380 buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
381 fields[1].out_mask = NULL;
382 fields[1].in_value = NULL;
383 fields[1].in_check_value = NULL;
384 fields[1].in_check_mask = NULL;
385 fields[1].in_handler = NULL;
386 fields[1].in_handler_priv = NULL;
387
388 fields[2].device = etm_reg->jtag_info->chain_pos;
389 fields[2].num_bits = 1;
390 fields[2].out_value = malloc(1);
391 buf_set_u32(fields[2].out_value, 0, 1, 1);
392 fields[2].out_mask = NULL;
393 fields[2].in_value = NULL;
394 fields[2].in_check_value = NULL;
395 fields[2].in_check_mask = NULL;
396 fields[2].in_handler = NULL;
397 fields[2].in_handler_priv = NULL;
398
399 jtag_add_dr_scan(3, fields, -1, NULL);
400
401 free(fields[0].out_value);
402 free(fields[1].out_value);
403 free(fields[2].out_value);
404
405 return ERROR_OK;
406 }
407
408 int etm_store_reg(reg_t *reg)
409 {
410 return etm_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
411 }
412

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)