etm.c 54.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/***************************************************************************
 *   Copyright (C) 2005 by Dominic Rath                                    *
 *   Dominic.Rath@gmx.de                                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

24
#include "armv4_5.h"
25
#include "etb.h"
26
#include "image.h"
27
28
29
#include "arm_disassembler.h"


30
31
/*
 * ARM "Embedded Trace Macrocell" (ETM) support -- direct JTAG access.
32
 *
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
 * ETM modules collect instruction and/or data trace information, compress
 * it, and transfer it to a debugging host through either a (buffered) trace
 * port (often a 38-pin Mictor connector) or an Embedded Trace Buffer (ETB).
 *
 * There are several generations of these modules.  Original versions have
 * JTAG access through a dedicated scan chain.  Recent versions have added
 * access via coprocessor instructions, memory addressing, and the ARM Debug
 * Interface v5 (ADIv5); and phased out direct JTAG access.
 *
 * This code supports up to the ETMv1.3 architecture, as seen in ETM9 and
 * most common ARM9 systems.  Note: "CoreSight ETM9" implements ETMv3.2,
 * implying non-JTAG connectivity options.
 *
 * Relevant documentation includes:
 *  ARM DDI 0157G ... ETM9 (r2p2) Technical Reference Manual
 *  ARM DDI 0315B ... CoreSight ETM9 (r0p1) Technical Reference Manual
 *  ARM IHI 0014O ... Embedded Trace Macrocell, Architecture Specification
50
51
 */

52
53
54
55
56
57
#define ARRAY_SIZE(x)	((int)(sizeof(x)/sizeof((x)[0])))

enum {
	RO,				/* read/only */
	WO,				/* write/only */
	RW,				/* read/write */
58
59
};

60
61
62
63
64
65
struct etm_reg_info {
	uint8_t		addr;
	uint8_t		size;		/* low-N of 32 bits */
	uint8_t		mode;		/* RO, WO, RW */
	uint8_t		bcd_vers;	/* 1.0, 2.0, etc */
	char		*name;
66
67
};

68
69
/*
 * Registers 0..0x7f are JTAG-addressable using scanchain 6.
dbrownell's avatar
dbrownell committed
70
 * (Or on some processors, through coprocessor operations.)
71
72
73
 * Newer versions of ETM make some W/O registers R/W, and
 * provide definitions for some previously-unused bits.
 */
74
75
76
77

/* basic registers that are always there given the right ETM version */
static const struct etm_reg_info etm_core[] = {
	/* NOTE: we "know" ETM_CONFIG is listed first */
78
	{ ETM_CONFIG, 32, RO, 0x10, "ETM_config", },
79

80
	/* ETM Trace Registers */
81
82
83
84
85
	{ ETM_CTRL, 32, RW, 0x10, "ETM_ctrl", },
	{ ETM_TRIG_EVENT, 17, WO, 0x10, "ETM_trig_event", },
	{ ETM_ASIC_CTRL,  8, WO, 0x10, "ETM_asic_ctrl", },
	{ ETM_STATUS,  3, RO, 0x11, "ETM_status", },
	{ ETM_SYS_CONFIG,  9, RO, 0x12, "ETM_sys_config", },
86
87

	/* TraceEnable configuration */
88
89
90
91
	{ ETM_TRACE_RESOURCE_CTRL, 32, WO, 0x12, "ETM_trace_resource_ctrl", },
	{ ETM_TRACE_EN_CTRL2, 16, WO, 0x12, "ETM_trace_en_ctrl2", },
	{ ETM_TRACE_EN_EVENT, 17, WO, 0x10, "ETM_trace_en_event", },
	{ ETM_TRACE_EN_CTRL1, 26, WO, 0x10, "ETM_trace_en_ctrl1", },
92
93

	/* ViewData configuration (data trace) */
94
95
96
97
	{ ETM_VIEWDATA_EVENT, 17, WO, 0x10, "ETM_viewdata_event", },
	{ ETM_VIEWDATA_CTRL1, 32, WO, 0x10, "ETM_viewdata_ctrl1", },
	{ ETM_VIEWDATA_CTRL2, 32, WO, 0x10, "ETM_viewdata_ctrl2", },
	{ ETM_VIEWDATA_CTRL3, 17, WO, 0x10, "ETM_viewdata_ctrl3", },
98

99
100
	/* REVISIT exclude VIEWDATA_CTRL2 when it's not there */

101
102
	{ 0x78, 12, WO, 0x20, "ETM_sync_freq", },
	{ 0x79, 32, RO, 0x20, "ETM_id", },
103
104
105
106
};

static const struct etm_reg_info etm_fifofull[] = {
	/* FIFOFULL configuration */
107
108
	{ ETM_FIFOFULL_REGION, 25, WO, 0x10, "ETM_fifofull_region", },
	{ ETM_FIFOFULL_LEVEL,  8, WO, 0x10, "ETM_fifofull_level", },
109
110
111
};

static const struct etm_reg_info etm_addr_comp[] = {
112
113
	/* Address comparator register pairs */
#define ADDR_COMPARATOR(i) \
114
115
116
117
		{ ETM_ADDR_COMPARATOR_VALUE + (i) - 1, 32, WO, 0x10, \
				"ETM_addr_" #i "_comparator_value", }, \
		{ ETM_ADDR_ACCESS_TYPE + (i) - 1,  7, WO, 0x10, \
				"ETM_addr_" #i "_access_type", }
118
119
120
121
122
123
124
125
	ADDR_COMPARATOR(1),
	ADDR_COMPARATOR(2),
	ADDR_COMPARATOR(3),
	ADDR_COMPARATOR(4),
	ADDR_COMPARATOR(5),
	ADDR_COMPARATOR(6),
	ADDR_COMPARATOR(7),
	ADDR_COMPARATOR(8),
126

127
128
129
130
131
132
133
	ADDR_COMPARATOR(9),
	ADDR_COMPARATOR(10),
	ADDR_COMPARATOR(11),
	ADDR_COMPARATOR(12),
	ADDR_COMPARATOR(13),
	ADDR_COMPARATOR(14),
	ADDR_COMPARATOR(15),
134
	ADDR_COMPARATOR(16),
135
#undef ADDR_COMPARATOR
136
};
137

138
static const struct etm_reg_info etm_data_comp[] = {
139
140
	/* Data Value Comparators (NOTE: odd addresses are reserved) */
#define DATA_COMPARATOR(i) \
141
142
143
144
		{ ETM_DATA_COMPARATOR_VALUE + 2*(i) - 1, 32, WO, 0x10, \
				"ETM_data_" #i "_comparator_value", }, \
		{ ETM_DATA_COMPARATOR_MASK + 2*(i) - 1, 32, WO, 0x10, \
				"ETM_data_" #i "_comparator_mask", }
145
146
147
148
149
150
151
	DATA_COMPARATOR(1),
	DATA_COMPARATOR(2),
	DATA_COMPARATOR(3),
	DATA_COMPARATOR(4),
	DATA_COMPARATOR(5),
	DATA_COMPARATOR(6),
	DATA_COMPARATOR(7),
152
	DATA_COMPARATOR(8),
153
#undef DATA_COMPARATOR
154
};
155

156
static const struct etm_reg_info etm_counters[] = {
dbrownell's avatar
dbrownell committed
157
#define ETM_COUNTER(i) \
158
159
160
161
162
163
164
165
		{ ETM_COUNTER_RELOAD_VALUE + (i) - 1, 16, WO, 0x10, \
				"ETM_counter_" #i "_reload_value", }, \
		{ ETM_COUNTER_ENABLE + (i) - 1, 18, WO, 0x10, \
				"ETM_counter_" #i "_enable", }, \
		{ ETM_COUNTER_RELOAD_EVENT + (i) - 1, 17, WO, 0x10, \
				"ETM_counter_" #i "_reload_event", }, \
		{ ETM_COUNTER_VALUE + (i) - 1, 16, RO, 0x10, \
				"ETM_counter_" #i "_value", }
dbrownell's avatar
dbrownell committed
166
167
168
	ETM_COUNTER(1),
	ETM_COUNTER(2),
	ETM_COUNTER(3),
169
	ETM_COUNTER(4),
dbrownell's avatar
dbrownell committed
170
#undef ETM_COUNTER
171
};
172

173
static const struct etm_reg_info etm_sequencer[] = {
dbrownell's avatar
dbrownell committed
174
#define ETM_SEQ(i) \
175
		{ ETM_SEQUENCER_EVENT + (i), 17, WO, 0x10, \
176
				"ETM_sequencer_event" #i, }
dbrownell's avatar
dbrownell committed
177
178
179
180
181
182
183
	ETM_SEQ(0),				/* 1->2 */
	ETM_SEQ(1),				/* 2->1 */
	ETM_SEQ(2),				/* 2->3 */
	ETM_SEQ(3),				/* 3->1 */
	ETM_SEQ(4),				/* 3->2 */
	ETM_SEQ(5),				/* 1->3 */
#undef ETM_SEQ
184
	/* 0x66 reserved */
185
	{ ETM_SEQUENCER_STATE,  2, RO, 0x10, "ETM_sequencer_state", },
186
};
187

188
static const struct etm_reg_info etm_outputs[] = {
dbrownell's avatar
dbrownell committed
189
#define ETM_OUTPUT(i) \
190
191
		{ ETM_EXTERNAL_OUTPUT + (i) - 1, 17, WO, 0x10, \
				"ETM_external_output" #i, }
192

dbrownell's avatar
dbrownell committed
193
194
195
	ETM_OUTPUT(1),
	ETM_OUTPUT(2),
	ETM_OUTPUT(3),
196
	ETM_OUTPUT(4),
dbrownell's avatar
dbrownell committed
197
#undef ETM_OUTPUT
198
};
199
200
201
202
203

#if 0
	/* registers from 0x6c..0x7f were added after ETMv1.3 */

	/* Context ID Comparators */
204
205
206
207
	{ 0x6c, 32, RO, 0x20, "ETM_contextid_comparator_value1", }
	{ 0x6d, 32, RO, 0x20, "ETM_contextid_comparator_value2", }
	{ 0x6e, 32, RO, 0x20, "ETM_contextid_comparator_value3", }
	{ 0x6f, 32, RO, 0x20, "ETM_contextid_comparator_mask", }
208
#endif
209

210
static int etm_reg_arch_type = -1;
211

212
static int etm_get_reg(reg_t *reg);
213
214
215
216
217
218
219
static int etm_read_reg_w_check(reg_t *reg,
		uint8_t* check_value, uint8_t* check_mask);
static int etm_register_user_commands(struct command_context_s *cmd_ctx);
static int etm_set_reg_w_exec(reg_t *reg, uint8_t *buf);
static int etm_write_reg(reg_t *reg, uint32_t value);

static command_t *etm_cmd;
220
221


222
223
224
225
226
227
228
229
230
231
232
/* Look up register by ID ... most ETM instances only
 * support a subset of the possible registers.
 */
static reg_t *etm_reg_lookup(etm_context_t *etm_ctx, unsigned id)
{
	reg_cache_t *cache = etm_ctx->reg_cache;
	int i;

	for (i = 0; i < cache->num_regs; i++) {
		struct etm_reg_s *reg = cache->reg_list[i].arch_info;

233
		if (reg->reg_info->addr == id)
234
235
236
237
238
239
240
241
242
			return &cache->reg_list[i];
	}

	/* caller asking for nonexistent register is a bug! */
	/* REVISIT say which of the N targets was involved */
	LOG_ERROR("ETM: register 0x%02x not available", id);
	return NULL;
}

243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
static void etm_reg_add(unsigned bcd_vers, arm_jtag_t *jtag_info,
		reg_cache_t *cache, etm_reg_t *ereg,
		const struct etm_reg_info *r, unsigned nreg)
{
	reg_t *reg = cache->reg_list;

	reg += cache->num_regs;
	ereg += cache->num_regs;

	/* add up to "nreg" registers from "r", if supported by this
	 * version of the ETM, to the specified cache.
	 */
	for (; nreg--; r++) {

		/* this ETM may be too old to have some registers */
		if (r->bcd_vers > bcd_vers)
			continue;

		reg->name = r->name;
		reg->size = r->size;
		reg->value = &ereg->value;
		reg->arch_info = ereg;
		reg->arch_type = etm_reg_arch_type;
		reg++;
		cache->num_regs++;

		ereg->reg_info = r;
		ereg->jtag_info = jtag_info;
		ereg++;
	}
}

275
276
reg_cache_t *etm_build_reg_cache(target_t *target,
		arm_jtag_t *jtag_info, etm_context_t *etm_ctx)
277
278
279
280
{
	reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
	reg_t *reg_list = NULL;
	etm_reg_t *arch_info = NULL;
281
	unsigned bcd_vers, config;
282

283
284
	/* register a register arch-type for etm registers only once */
	if (etm_reg_arch_type == -1)
285
286
		etm_reg_arch_type = register_reg_arch_type(etm_get_reg,
				etm_set_reg_w_exec);
287

288
	/* the actual registers are kept in two arrays */
289
290
	reg_list = calloc(128, sizeof(reg_t));
	arch_info = calloc(128, sizeof(etm_reg_t));
291

292
293
294
295
	/* fill in values for the reg cache */
	reg_cache->name = "etm registers";
	reg_cache->next = NULL;
	reg_cache->reg_list = reg_list;
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
	reg_cache->num_regs = 0;

	/* add ETM_CONFIG, then parse its values to see
	 * which other registers exist in this ETM
	 */
	etm_reg_add(0x10, jtag_info, reg_cache, arch_info,
			etm_core, 1);

	etm_get_reg(reg_list);
	etm_ctx->config = buf_get_u32((void *)&arch_info->value, 0, 32);
	config = etm_ctx->config;

	/* figure ETM version then add base registers */
	if (config & (1 << 31)) {
		bcd_vers = 0x20;
		LOG_WARNING("ETMv2+ support is incomplete");

		/* REVISIT read ID register, distinguish ETMv3.3 etc;
		 * don't presume trace start/stop support is present;
		 * and include any context ID comparator registers.
		 */
	} else {
		switch (config >> 28) {
		case 7:
		case 5:
		case 3:
			bcd_vers = 0x13;
			break;
		case 4:
		case 2:
			bcd_vers = 0x12;
			break;
		case 1:
			bcd_vers = 0x11;
			break;
		case 0:
			bcd_vers = 0x10;
			break;
		default:
			LOG_WARNING("Bad ETMv1 protocol %d", config >> 28);
			free(reg_cache);
			free(reg_list);
			free(arch_info);
			return ERROR_OK;
		}
341
	}
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
	etm_ctx->bcd_vers = bcd_vers;
	LOG_INFO("ETM v%d.%d", bcd_vers >> 4, bcd_vers & 0xf);

	etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info,
			etm_core + 1, ARRAY_SIZE(etm_core) - 1);

	/* address and data comparators; counters; outputs */
	etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info,
			etm_addr_comp, 4 * (0x0f & (config >> 0)));
	etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info,
			etm_data_comp, 2 * (0x0f & (config >> 4)));
	etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info,
			etm_counters, 4 * (0x07 & (config >> 13)));
	etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info,
			etm_outputs, (0x07 & (config >> 20)));

	/* FIFOFULL presence is optional
	 * REVISIT for ETMv1.2 and later, don't bother adding this
	 * unless ETM_SYS_CONFIG says it's also *supported* ...
	 */
	if (config & (1 << 23))
		etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info,
				etm_fifofull, ARRAY_SIZE(etm_fifofull));

	/* sequencer is optional (for state-dependant triggering) */
	if (config & (1 << 16))
		etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info,
				etm_sequencer, ARRAY_SIZE(etm_sequencer));

	/* REVISIT could realloc and likely save half the memory
	 * in the two chunks we allocated...
	 */
374
375
376
377
378

	/* the ETM might have an ETB connected */
	if (strcmp(etm_ctx->capture_driver->name, "etb") == 0)
	{
		etb_t *etb = etm_ctx->capture_driver_priv;
379

380
381
		if (!etb)
		{
382
			LOG_ERROR("etb selected as etm capture driver, but no ETB configured");
383
			free(reg_cache);
384
			free(reg_list);
385
			free(arch_info);
386
387
			return ERROR_OK;
		}
388

389
		reg_cache->next = etb_build_reg_cache(etb);
390

391
392
		etb->reg_cache = reg_cache->next;
	}
393
394


oharboe's avatar
oharboe committed
395
396
397
	return reg_cache;
}

398
399
400
401
402
403
404
405
406
407
static int etm_read_reg(reg_t *reg)
{
	return etm_read_reg_w_check(reg, NULL, NULL);
}

static int etm_store_reg(reg_t *reg)
{
	return etm_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
}

oharboe's avatar
oharboe committed
408
409
410
int etm_setup(target_t *target)
{
	int retval;
411
	uint32_t etm_ctrl_value;
412
413
	struct arm *arm = target_to_arm(target);
	etm_context_t *etm_ctx = arm->etm;
414
415
416
417
418
	reg_t *etm_ctrl_reg;

	etm_ctrl_reg = etm_reg_lookup(etm_ctx, ETM_CTRL);
	if (!etm_ctrl_reg)
		return ERROR_OK;
oharboe's avatar
oharboe committed
419

420
	/* initialize some ETM control register settings */
oharboe's avatar
oharboe committed
421
422
	etm_get_reg(etm_ctrl_reg);
	etm_ctrl_value = buf_get_u32(etm_ctrl_reg->value, 0, etm_ctrl_reg->size);
423

oharboe's avatar
oharboe committed
424
425
	/* clear the ETM powerdown bit (0) */
	etm_ctrl_value &= ~0x1;
426

oharboe's avatar
oharboe committed
427
	/* configure port width (6:4), mode (17:16) and clocking (13) */
428
	etm_ctrl_value = (etm_ctrl_value &
oharboe's avatar
oharboe committed
429
430
		~ETM_PORT_WIDTH_MASK & ~ETM_PORT_MODE_MASK & ~ETM_PORT_CLOCK_MASK)
		| etm_ctx->portmode;
431

oharboe's avatar
oharboe committed
432
433
	buf_set_u32(etm_ctrl_reg->value, 0, etm_ctrl_reg->size, etm_ctrl_value);
	etm_store_reg(etm_ctrl_reg);
434

zwelch's avatar
zwelch committed
435
	if ((retval = jtag_execute_queue()) != ERROR_OK)
oharboe's avatar
oharboe committed
436
		return retval;
437

zwelch's avatar
zwelch committed
438
	if ((retval = etm_ctx->capture_driver->init(etm_ctx)) != ERROR_OK)
439
	{
440
		LOG_ERROR("ETM capture driver initialization failed");
oharboe's avatar
oharboe committed
441
		return retval;
442
	}
oharboe's avatar
oharboe committed
443
	return ERROR_OK;
444
445
}

446
static int etm_get_reg(reg_t *reg)
447
{
448
	int retval;
oharboe's avatar
oharboe committed
449

450
	if ((retval = etm_read_reg(reg)) != ERROR_OK)
451
	{
452
		LOG_ERROR("BUG: error scheduling etm register read");
453
		return retval;
454
	}
455

456
	if ((retval = jtag_execute_queue()) != ERROR_OK)
457
	{
458
		LOG_ERROR("register read failed");
459
		return retval;
460
	}
461

462
463
464
	return ERROR_OK;
}

465
466
static int etm_read_reg_w_check(reg_t *reg,
		uint8_t* check_value, uint8_t* check_mask)
467
468
{
	etm_reg_t *etm_reg = reg->arch_info;
469
470
	const struct etm_reg_info *r = etm_reg->reg_info;
	uint8_t reg_addr = r->addr & 0x7f;
471
	scan_field_t fields[3];
472

473
474
475
476
477
478
	if (etm_reg->reg_info->mode == WO) {
		LOG_ERROR("BUG: can't read write-only register %s", r->name);
		return ERROR_INVALID_ARGUMENTS;
	}

	LOG_DEBUG("%s (%u)", r->name, reg_addr);
479

480
	jtag_set_end_state(TAP_IDLE);
481
482
	arm_jtag_scann(etm_reg->jtag_info, 0x6);
	arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL);
483

484
	fields[0].tap = etm_reg->jtag_info->tap;
485
486
487
	fields[0].num_bits = 32;
	fields[0].out_value = reg->value;
	fields[0].in_value = NULL;
488
489
	fields[0].check_value = NULL;
	fields[0].check_mask = NULL;
490

491
	fields[1].tap = etm_reg->jtag_info->tap;
492
493
494
495
	fields[1].num_bits = 7;
	fields[1].out_value = malloc(1);
	buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
	fields[1].in_value = NULL;
496
497
	fields[1].check_value = NULL;
	fields[1].check_mask = NULL;
498

499
	fields[2].tap = etm_reg->jtag_info->tap;
500
501
502
503
	fields[2].num_bits = 1;
	fields[2].out_value = malloc(1);
	buf_set_u32(fields[2].out_value, 0, 1, 0);
	fields[2].in_value = NULL;
504
505
	fields[2].check_value = NULL;
	fields[2].check_mask = NULL;
506

507
	jtag_add_dr_scan(3, fields, jtag_get_end_state());
508

509
	fields[0].in_value = reg->value;
510
511
	fields[0].check_value = check_value;
	fields[0].check_mask = check_mask;
512

513
	jtag_add_dr_scan_check(3, fields, jtag_get_end_state());
oharboe's avatar
oharboe committed
514

515
516
	free(fields[1].out_value);
	free(fields[2].out_value);
517

518
519
520
	return ERROR_OK;
}

521
static int etm_set_reg(reg_t *reg, uint32_t value)
522
{
523
	int retval;
oharboe's avatar
oharboe committed
524

525
	if ((retval = etm_write_reg(reg, value)) != ERROR_OK)
526
	{
527
		LOG_ERROR("BUG: error scheduling etm register write");
528
		return retval;
529
	}
530

531
532
533
	buf_set_u32(reg->value, 0, reg->size, value);
	reg->valid = 1;
	reg->dirty = 0;
534

535
536
537
	return ERROR_OK;
}

538
static int etm_set_reg_w_exec(reg_t *reg, uint8_t *buf)
539
{
540
	int retval;
oharboe's avatar
oharboe committed
541

542
	etm_set_reg(reg, buf_get_u32(buf, 0, reg->size));
543

544
	if ((retval = jtag_execute_queue()) != ERROR_OK)
545
	{
546
		LOG_ERROR("register write failed");
547
		return retval;
548
549
550
551
	}
	return ERROR_OK;
}

552
static int etm_write_reg(reg_t *reg, uint32_t value)
553
554
{
	etm_reg_t *etm_reg = reg->arch_info;
555
556
	const struct etm_reg_info *r = etm_reg->reg_info;
	uint8_t reg_addr = r->addr & 0x7f;
557
	scan_field_t fields[3];
558

559
560
561
562
563
564
	if (etm_reg->reg_info->mode == RO) {
		LOG_ERROR("BUG: can't write read--only register %s", r->name);
		return ERROR_INVALID_ARGUMENTS;
	}

	LOG_DEBUG("%s (%u): 0x%8.8" PRIx32 "", r->name, reg_addr, value);
565

566
	jtag_set_end_state(TAP_IDLE);
567
568
	arm_jtag_scann(etm_reg->jtag_info, 0x6);
	arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL);
569

570
	fields[0].tap = etm_reg->jtag_info->tap;
571
	fields[0].num_bits = 32;
572
	uint8_t tmp1[4];
573
	fields[0].out_value = tmp1;
574
575
	buf_set_u32(fields[0].out_value, 0, 32, value);
	fields[0].in_value = NULL;
oharboe's avatar
oharboe committed
576

577
	fields[1].tap = etm_reg->jtag_info->tap;
578
	fields[1].num_bits = 7;
579
	uint8_t tmp2;
580
	fields[1].out_value = &tmp2;
581
582
	buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
	fields[1].in_value = NULL;
oharboe's avatar
oharboe committed
583

584
	fields[2].tap = etm_reg->jtag_info->tap;
585
	fields[2].num_bits = 1;
586
	uint8_t tmp3;
587
	fields[2].out_value = &tmp3;
588
589
	buf_set_u32(fields[2].out_value, 0, 1, 1);
	fields[2].in_value = NULL;
oharboe's avatar
oharboe committed
590

591
	jtag_add_dr_scan(3, fields, jtag_get_end_state());
592

593
594
595
596
597
	return ERROR_OK;
}


/* ETM trace analysis functionality
598
 *
599
600
601
602
603
604
 */
extern etm_capture_driver_t etm_dummy_capture_driver;
#if BUILD_OOCD_TRACE == 1
extern etm_capture_driver_t oocd_trace_capture_driver;
#endif

605
static etm_capture_driver_t *etm_capture_drivers[] =
606
607
608
609
610
611
612
613
614
{
	&etb_capture_driver,
	&etm_dummy_capture_driver,
#if BUILD_OOCD_TRACE == 1
	&oocd_trace_capture_driver,
#endif
	NULL
};

615
static int etm_read_instruction(etm_context_t *ctx, arm_instruction_t *instruction)
616
617
618
{
	int i;
	int section = -1;
619
620
	uint32_t size_read;
	uint32_t opcode;
621
	int retval;
622

623
624
	if (!ctx->image)
		return ERROR_TRACE_IMAGE_UNAVAILABLE;
625
626

	/* search for the section the current instruction belongs to */
627
628
629
630
631
632
633
634
635
	for (i = 0; i < ctx->image->num_sections; i++)
	{
		if ((ctx->image->sections[i].base_address <= ctx->current_pc) &&
			(ctx->image->sections[i].base_address + ctx->image->sections[i].size > ctx->current_pc))
		{
			section = i;
			break;
		}
	}
636

637
638
639
640
641
	if (section == -1)
	{
		/* current instruction couldn't be found in the image */
		return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
	}
642

643
644
	if (ctx->core_state == ARMV4_5_STATE_ARM)
	{
645
		uint8_t buf[4];
646
		if ((retval = image_read_section(ctx->image, section,
647
648
649
			ctx->current_pc - ctx->image->sections[section].base_address,
			4, buf, &size_read)) != ERROR_OK)
		{
650
			LOG_ERROR("error while reading instruction: %i", retval);
651
652
653
654
655
656
657
			return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
		}
		opcode = target_buffer_get_u32(ctx->target, buf);
		arm_evaluate_opcode(opcode, ctx->current_pc, instruction);
	}
	else if (ctx->core_state == ARMV4_5_STATE_THUMB)
	{
658
		uint8_t buf[2];
659
		if ((retval = image_read_section(ctx->image, section,
660
661
662
			ctx->current_pc - ctx->image->sections[section].base_address,
			2, buf, &size_read)) != ERROR_OK)
		{
663
			LOG_ERROR("error while reading instruction: %i", retval);
664
665
666
667
668
669
670
			return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
		}
		opcode = target_buffer_get_u16(ctx->target, buf);
		thumb_evaluate_opcode(opcode, ctx->current_pc, instruction);
	}
	else if (ctx->core_state == ARMV4_5_STATE_JAZELLE)
	{
671
		LOG_ERROR("BUG: tracing of jazelle code not supported");
David Brownell's avatar
David Brownell committed
672
		return ERROR_FAIL;
673
674
675
	}
	else
	{
676
		LOG_ERROR("BUG: unknown core state encountered");
David Brownell's avatar
David Brownell committed
677
		return ERROR_FAIL;
678
	}
679

680
681
682
	return ERROR_OK;
}

683
static int etmv1_next_packet(etm_context_t *ctx, uint8_t *packet, int apo)
684
685
686
687
688
689
690
691
692
{
	while (ctx->data_index < ctx->trace_depth)
	{
		/* if the caller specified an address packet offset, skip until the
		 * we reach the n-th cycle marked with tracesync */
		if (apo > 0)
		{
			if (ctx->trace_data[ctx->data_index].flags & ETMV1_TRACESYNC_CYCLE)
				apo--;
693

694
695
696
697
698
699
700
			if (apo > 0)
			{
				ctx->data_index++;
				ctx->data_half = 0;
			}
			continue;
		}
701

702
703
704
705
706
707
708
709
710
		/* no tracedata output during a TD cycle
		 * or in a trigger cycle */
		if ((ctx->trace_data[ctx->data_index].pipestat == STAT_TD)
			|| (ctx->trace_data[ctx->data_index].flags & ETMV1_TRIGGER_CYCLE))
		{
			ctx->data_index++;
			ctx->data_half = 0;
			continue;
		}
711

712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
		if ((ctx->portmode & ETM_PORT_WIDTH_MASK) == ETM_PORT_16BIT)
		{
			if (ctx->data_half == 0)
			{
				*packet = ctx->trace_data[ctx->data_index].packet & 0xff;
				ctx->data_half = 1;
			}
			else
			{
				*packet = (ctx->trace_data[ctx->data_index].packet & 0xff00) >> 8;
				ctx->data_half = 0;
				ctx->data_index++;
			}
		}
		else if ((ctx->portmode & ETM_PORT_WIDTH_MASK) == ETM_PORT_8BIT)
		{
			*packet = ctx->trace_data[ctx->data_index].packet & 0xff;
			ctx->data_index++;
		}
		else
		{
			/* on a 4-bit port, a packet will be output during two consecutive cycles */
			if (ctx->data_index > (ctx->trace_depth - 2))
				return -1;
736

737
738
739
740
			*packet = ctx->trace_data[ctx->data_index].packet & 0xf;
			*packet |= (ctx->trace_data[ctx->data_index + 1].packet & 0xf) << 4;
			ctx->data_index += 2;
		}
741

742
743
		return 0;
	}
744

745
746
747
	return -1;
}

748
static int etmv1_branch_address(etm_context_t *ctx)
749
750
{
	int retval;
751
	uint8_t packet;
752
753
	int shift = 0;
	int apo;
754
	uint32_t i;
755

756
757
758
759
	/* quit analysis if less than two cycles are left in the trace
	 * because we can't extract the APO */
	if (ctx->data_index > (ctx->trace_depth - 2))
		return -1;
760

761
762
763
764
765
766
	/* a BE could be output during an APO cycle, skip the current
	 * and continue with the new one */
	if (ctx->trace_data[ctx->pipe_index + 1].pipestat & 0x4)
		return 1;
	if (ctx->trace_data[ctx->pipe_index + 2].pipestat & 0x4)
		return 2;
767

768
769
770
	/* address packet offset encoded in the next two cycles' pipestat bits */
	apo = ctx->trace_data[ctx->pipe_index + 1].pipestat & 0x3;
	apo |= (ctx->trace_data[ctx->pipe_index + 2].pipestat & 0x3) << 2;
771

772
773
774
775
776
777
778
779
	/* count number of tracesync cycles between current pipe_index and data_index
	 * i.e. the number of tracesyncs that data_index already passed by
	 * to subtract them from the APO */
	for (i = ctx->pipe_index; i < ctx->data_index; i++)
	{
		if (ctx->trace_data[ctx->pipe_index + 1].pipestat & ETMV1_TRACESYNC_CYCLE)
			apo--;
	}
780

781
782
783
784
785
786
787
788
	/* extract up to four 7-bit packets */
	do {
		if ((retval = etmv1_next_packet(ctx, &packet, (shift == 0) ? apo + 1 : 0)) != 0)
			return -1;
		ctx->last_branch &= ~(0x7f << shift);
		ctx->last_branch |= (packet & 0x7f) << shift;
		shift += 7;
	} while ((packet & 0x80) && (shift < 28));
789

790
791
792
793
794
795
796
797
798
799
800
801
802
803
	/* one last packet holding 4 bits of the address, plus the branch reason code */
	if ((shift == 28) && (packet & 0x80))
	{
		if ((retval = etmv1_next_packet(ctx, &packet, 0)) != 0)
			return -1;
		ctx->last_branch &= 0x0fffffff;
		ctx->last_branch |= (packet & 0x0f) << 28;
		ctx->last_branch_reason = (packet & 0x70) >> 4;
		shift += 4;
	}
	else
	{
		ctx->last_branch_reason = 0;
	}
804

805
806
807
808
	if (shift == 32)
	{
		ctx->pc_ok = 1;
	}
809

810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
	/* if a full address was output, we might have branched into Jazelle state */
	if ((shift == 32) && (packet & 0x80))
	{
		ctx->core_state = ARMV4_5_STATE_JAZELLE;
	}
	else
	{
		/* if we didn't branch into Jazelle state, the current processor state is
		 * encoded in bit 0 of the branch target address */
		if (ctx->last_branch & 0x1)
		{
			ctx->core_state = ARMV4_5_STATE_THUMB;
			ctx->last_branch &= ~0x1;
		}
		else
		{
			ctx->core_state = ARMV4_5_STATE_ARM;
			ctx->last_branch &= ~0x3;
		}
	}
830

831
832
833
	return 0;
}

834
static int etmv1_data(etm_context_t *ctx, int size, uint32_t *data)
835
836
{
	int j;
837
	uint8_t buf[4];
838
	int retval;
839

840
841
842
843
844
	for (j = 0; j < size; j++)
	{
		if ((retval = etmv1_next_packet(ctx, &buf[j], 0)) != 0)
			return -1;
	}
845

846
	if (size == 8)
oharboe's avatar
oharboe committed
847
	{
848
		LOG_ERROR("TODO: add support for 64-bit values");
oharboe's avatar
oharboe committed
849
850
		return -1;
	}
851
852
853
854
855
856
	else if (size == 4)
		*data = target_buffer_get_u32(ctx->target, buf);
	else if (size == 2)
		*data = target_buffer_get_u16(ctx->target, buf);
	else if (size == 1)
		*data = buf[0];
oharboe's avatar
oharboe committed
857
858
	else
		return -1;
859

860
861
862
	return 0;
}

863
static int etmv1_analyze_trace(etm_context_t *ctx, struct command_context_s *cmd_ctx)
864
865
866
{
	int retval;
	arm_instruction_t instruction;
867

868
869
870
	/* read the trace data if it wasn't read already */
	if (ctx->trace_depth == 0)
		ctx->capture_driver->read_trace(ctx);
871

872
873
874
875
876
	/* start at the beginning of the captured trace */
	ctx->pipe_index = 0;
	ctx->data_index = 0;
	ctx->data_half = 0;

877
	/* neither the PC nor the data pointer are valid */
878
879
	ctx->pc_ok = 0;
	ctx->ptr_ok = 0;
880

881
882
	while (ctx->pipe_index < ctx->trace_depth)
	{
883
		uint8_t pipestat = ctx->trace_data[ctx->pipe_index].pipestat;
884
885
886
887
888
889
		uint32_t next_pc = ctx->current_pc;
		uint32_t old_data_index = ctx->data_index;
		uint32_t old_data_half = ctx->data_half;
		uint32_t old_index = ctx->pipe_index;
		uint32_t last_instruction = ctx->last_instruction;
		uint32_t cycles = 0;
890
		int current_pc_ok = ctx->pc_ok;
891

892
893
894
895
896
897
898
899
		if (ctx->trace_data[ctx->pipe_index].flags & ETMV1_TRIGGER_CYCLE)
		{
			command_print(cmd_ctx, "--- trigger ---");
		}

		/* instructions execute in IE/D or BE/D cycles */
		if ((pipestat == STAT_IE) || (pipestat == STAT_ID))
			ctx->last_instruction = ctx->pipe_index;
900

901
902
903
904
905
906
		/* if we don't have a valid pc skip until we reach an indirect branch */
		if ((!ctx->pc_ok) && (pipestat != STAT_BE))
		{
			ctx->pipe_index++;
			continue;
		}
907

908
909
910
911
912
913
914
915
916
917
918
919
920
		/* any indirect branch could have interrupted instruction flow
		 * - the branch reason code could indicate a trace discontinuity
		 * - a branch to the exception vectors indicates an exception
		 */
		if ((pipestat == STAT_BE) || (pipestat == STAT_BD))
		{
			/* backup current data index, to be able to consume the branch address
			 * before examining data address and values
			 */
			old_data_index = ctx->data_index;
			old_data_half = ctx->data_half;

			ctx->last_instruction = ctx->pipe_index;
921

922
923
924
925
926
927
			if ((retval = etmv1_branch_address(ctx)) != 0)
			{
				/* negative return value from etmv1_branch_address means we ran out of packets,
				 * quit analysing the trace */
				if (retval < 0)
					break;
928

929
930
931
				/* a positive return values means the current branch was abandoned,
				 * and a new branch was encountered in cycle ctx->pipe_index + retval;
				 */
932
				LOG_WARNING("abandoned branch encountered, correctnes of analysis uncertain");
933
934
935
				ctx->pipe_index += retval;
				continue;
			}
936

937
938
			/* skip over APO cycles */
			ctx->pipe_index += 2;
939

940
941
942
943
944
945
			switch (ctx->last_branch_reason)
			{
				case 0x0:	/* normal PC change */
					next_pc = ctx->last_branch;
					break;
				case 0x1:	/* tracing enabled */
duane's avatar
duane committed
946
					command_print(cmd_ctx, "--- tracing enabled at 0x%8.8" PRIx32 " ---", ctx->last_branch);
947
948
949
950
951
					ctx->current_pc = ctx->last_branch;
					ctx->pipe_index++;
					continue;
					break;
				case 0x2:	/* trace restarted after FIFO overflow */
duane's avatar
duane committed
952
					command_print(cmd_ctx, "--- trace restarted after FIFO overflow at 0x%8.8" PRIx32 " ---", ctx->last_branch);
953
954
955
956
957
					ctx->current_pc = ctx->last_branch;
					ctx->pipe_index++;
					continue;
					break;
				case 0x3:	/* exit from debug state */
duane's avatar
duane committed
958
					command_print(cmd_ctx, "--- exit from debug state at 0x%8.8" PRIx32 " ---", ctx->last_branch);
959
960
961
962
963
964
965
966
967
968
969
					ctx->current_pc = ctx->last_branch;
					ctx->pipe_index++;
					continue;
					break;
				case 0x4:	/* periodic synchronization point */
					next_pc = ctx->last_branch;
					/* if we had no valid PC prior to this synchronization point,
					 * we have to move on with the next trace cycle
					 */
					if (!current_pc_ok)
					{
duane's avatar
duane committed
970
						command_print(cmd_ctx, "--- periodic synchronization point at 0x%8.8" PRIx32 " ---", next_pc);
971
972
973
974
975
976
						ctx->current_pc = next_pc;
						ctx->pipe_index++;
						continue;
					}
					break;
				default:	/* reserved */
duane's avatar
duane committed
977
					LOG_ERROR("BUG: branch reason code 0x%" PRIx32 " is reserved", ctx->last_branch_reason);
David Brownell's avatar
David Brownell committed
978
					return ERROR_FAIL;
979
			}
980

981
982
983
984
985
986
			/* if we got here the branch was a normal PC change
			 * (or a periodic synchronization point, which means the same for that matter)
			 * if we didn't accquire a complete PC continue with the next cycle
			 */
			if (!ctx->pc_ok)
				continue;
987

988
			/* indirect branch to the exception vector means an exception occured */
mifi's avatar
mifi committed
989
			if ((ctx->last_branch <= 0x20)
990
991
992
993
994
995
996
997
				|| ((ctx->last_branch >= 0xffff0000) && (ctx->last_branch <= 0xffff0020)))
			{
				if ((ctx->last_branch & 0xff) == 0x10)
				{
					command_print(cmd_ctx, "data abort");
				}
				else
				{
duane's avatar
duane committed
998
					command_print(cmd_ctx, "exception vector 0x%2.2" PRIx32 "", ctx->last_branch);
999
1000
					ctx->current_pc = ctx->last_branch;
					ctx->pipe_index++;