a6b63451d076797ecc2888bc3b01deb7f058602d
[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, 17,
68 26, 16, 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
203 int etm_write_reg(reg_t *reg, u32 value);
204 int etm_read_reg(reg_t *reg);
205
206 reg_cache_t* etm_build_reg_cache(target_t *target, arm_jtag_t *jtag_info, int extra_reg)
207 {
208 reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
209 reg_t *reg_list = NULL;
210 etm_reg_t *arch_info = NULL;
211 int num_regs = sizeof(etm_reg_arch_info)/sizeof(int);
212 int i;
213
214 /* register a register arch-type for etm registers only once */
215 if (etm_reg_arch_type == -1)
216 etm_reg_arch_type = register_reg_arch_type(etm_get_reg, etm_set_reg_w_exec);
217
218 /* the actual registers are kept in two arrays */
219 reg_list = calloc(num_regs, sizeof(reg_t));
220 arch_info = calloc(num_regs, sizeof(etm_reg_t));
221
222 /* fill in values for the reg cache */
223 reg_cache->name = "etm registers";
224 reg_cache->next = NULL;
225 reg_cache->reg_list = reg_list;
226 reg_cache->num_regs = num_regs;
227
228 /* set up registers */
229 for (i = 0; i < num_regs; i++)
230 {
231 reg_list[i].name = etm_reg_list[i];
232 reg_list[i].size = 32;
233 reg_list[i].dirty = 0;
234 reg_list[i].valid = 0;
235 reg_list[i].bitfield_desc = NULL;
236 reg_list[i].num_bitfields = 0;
237 reg_list[i].value = calloc(1, 4);
238 reg_list[i].arch_info = &arch_info[i];
239 reg_list[i].arch_type = etm_reg_arch_type;
240 reg_list[i].size = etm_reg_arch_size_info[i];
241 arch_info[i].addr = etm_reg_arch_info[i];
242 arch_info[i].jtag_info = jtag_info;
243 }
244 return reg_cache;
245 }
246
247 int etm_get_reg(reg_t *reg)
248 {
249 if (etm_read_reg(reg) != ERROR_OK)
250 {
251 ERROR("BUG: error scheduling etm register read");
252 exit(-1);
253 }
254
255 if (jtag_execute_queue() != ERROR_OK)
256 {
257 ERROR("register read failed");
258 }
259
260 return ERROR_OK;
261 }
262
263 int etm_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
264 {
265 etm_reg_t *etm_reg = reg->arch_info;
266 u8 reg_addr = etm_reg->addr & 0x7f;
267 scan_field_t fields[3];
268
269 DEBUG("%i", etm_reg->addr);
270
271 jtag_add_end_state(TAP_RTI);
272 arm_jtag_scann(etm_reg->jtag_info, 0x6);
273 arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr);
274
275 fields[0].device = etm_reg->jtag_info->chain_pos;
276 fields[0].num_bits = 32;
277 fields[0].out_value = reg->value;
278 fields[0].out_mask = NULL;
279 fields[0].in_value = NULL;
280 fields[0].in_check_value = NULL;
281 fields[0].in_check_mask = NULL;
282 fields[0].in_handler = NULL;
283 fields[0].in_handler_priv = NULL;
284
285 fields[1].device = etm_reg->jtag_info->chain_pos;
286 fields[1].num_bits = 7;
287 fields[1].out_value = malloc(1);
288 buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
289 fields[1].out_mask = NULL;
290 fields[1].in_value = NULL;
291 fields[1].in_check_value = NULL;
292 fields[1].in_check_mask = NULL;
293 fields[1].in_handler = NULL;
294 fields[1].in_handler_priv = NULL;
295
296 fields[2].device = etm_reg->jtag_info->chain_pos;
297 fields[2].num_bits = 1;
298 fields[2].out_value = malloc(1);
299 buf_set_u32(fields[2].out_value, 0, 1, 0);
300 fields[2].out_mask = NULL;
301 fields[2].in_value = NULL;
302 fields[2].in_check_value = NULL;
303 fields[2].in_check_mask = NULL;
304 fields[2].in_handler = NULL;
305 fields[2].in_handler_priv = NULL;
306
307 jtag_add_dr_scan(3, fields, -1);
308
309 fields[0].in_value = reg->value;
310 fields[0].in_check_value = check_value;
311 fields[0].in_check_mask = check_mask;
312
313 jtag_add_dr_scan(3, fields, -1);
314
315 free(fields[1].out_value);
316 free(fields[2].out_value);
317
318 return ERROR_OK;
319 }
320
321 int etm_read_reg(reg_t *reg)
322 {
323 return etm_read_reg_w_check(reg, NULL, NULL);
324 }
325
326 int etm_set_reg(reg_t *reg, u32 value)
327 {
328 if (etm_write_reg(reg, value) != ERROR_OK)
329 {
330 ERROR("BUG: error scheduling etm register write");
331 exit(-1);
332 }
333
334 buf_set_u32(reg->value, 0, reg->size, value);
335 reg->valid = 1;
336 reg->dirty = 0;
337
338 return ERROR_OK;
339 }
340
341 int etm_set_reg_w_exec(reg_t *reg, u32 value)
342 {
343 etm_set_reg(reg, value);
344
345 if (jtag_execute_queue() != ERROR_OK)
346 {
347 ERROR("register write failed");
348 exit(-1);
349 }
350 return ERROR_OK;
351 }
352
353 int etm_write_reg(reg_t *reg, u32 value)
354 {
355 etm_reg_t *etm_reg = reg->arch_info;
356 u8 reg_addr = etm_reg->addr & 0x7f;
357 scan_field_t fields[3];
358
359 DEBUG("%i: 0x%8.8x", etm_reg->addr, value);
360
361 jtag_add_end_state(TAP_RTI);
362 arm_jtag_scann(etm_reg->jtag_info, 0x6);
363 arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr);
364
365 fields[0].device = etm_reg->jtag_info->chain_pos;
366 fields[0].num_bits = 32;
367 fields[0].out_value = malloc(4);
368 buf_set_u32(fields[0].out_value, 0, 32, value);
369 fields[0].out_mask = NULL;
370 fields[0].in_value = NULL;
371 fields[0].in_check_value = NULL;
372 fields[0].in_check_mask = NULL;
373 fields[0].in_handler = NULL;
374 fields[0].in_handler_priv = NULL;
375
376 fields[1].device = etm_reg->jtag_info->chain_pos;
377 fields[1].num_bits = 7;
378 fields[1].out_value = malloc(1);
379 buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
380 fields[1].out_mask = NULL;
381 fields[1].in_value = NULL;
382 fields[1].in_check_value = NULL;
383 fields[1].in_check_mask = NULL;
384 fields[1].in_handler = NULL;
385 fields[1].in_handler_priv = NULL;
386
387 fields[2].device = etm_reg->jtag_info->chain_pos;
388 fields[2].num_bits = 1;
389 fields[2].out_value = malloc(1);
390 buf_set_u32(fields[2].out_value, 0, 1, 1);
391 fields[2].out_mask = NULL;
392 fields[2].in_value = NULL;
393 fields[2].in_check_value = NULL;
394 fields[2].in_check_mask = NULL;
395 fields[2].in_handler = NULL;
396 fields[2].in_handler_priv = NULL;
397
398 jtag_add_dr_scan(3, fields, -1);
399
400 free(fields[0].out_value);
401 free(fields[1].out_value);
402 free(fields[2].out_value);
403
404 return ERROR_OK;
405 }
406
407 int etm_store_reg(reg_t *reg)
408 {
409 return etm_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
410 }
411

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)