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

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)