1
2
3
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
66
67
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
139
140
145
146
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/* ... */
#ifndef OPENOCD_TARGET_ETM_H
#define OPENOCD_TARGET_ETM_H
#include "trace.h"
#include "arm_jtag.h"
struct image;
enum {
ETM_CTRL = 0x00,
ETM_CONFIG = 0x01,
ETM_TRIG_EVENT = 0x02,
ETM_ASIC_CTRL = 0x03,
ETM_STATUS = 0x04,
ETM_SYS_CONFIG = 0x05,
ETM_TRACE_RESOURCE_CTRL = 0x06,
ETM_TRACE_EN_CTRL2 = 0x07,
ETM_TRACE_EN_EVENT = 0x08,
ETM_TRACE_EN_CTRL1 = 0x09,
ETM_FIFOFULL_REGION = 0x0a,
ETM_FIFOFULL_LEVEL = 0x0b,
ETM_VIEWDATA_EVENT = 0x0c,
ETM_VIEWDATA_CTRL1 = 0x0d,
ETM_VIEWDATA_CTRL2 = 0x0e,
ETM_VIEWDATA_CTRL3 = 0x0f,
ETM_ADDR_COMPARATOR_VALUE = 0x10,
ETM_ADDR_ACCESS_TYPE = 0x20,
ETM_DATA_COMPARATOR_VALUE = 0x30,
ETM_DATA_COMPARATOR_MASK = 0x40,
ETM_COUNTER_RELOAD_VALUE = 0x50,
ETM_COUNTER_ENABLE = 0x54,
ETM_COUNTER_RELOAD_EVENT = 0x58,
ETM_COUNTER_VALUE = 0x5c,
ETM_SEQUENCER_EVENT = 0x60,
ETM_SEQUENCER_STATE = 0x67,
ETM_EXTERNAL_OUTPUT = 0x68,
ETM_CONTEXTID_COMPARATOR_VALUE = 0x6c,
ETM_CONTEXTID_COMPARATOR_MASK = 0x6f,
ETM_ID = 0x79,
...};
struct etm_reg {
uint8_t value[4];
const struct etm_reg_info *reg_info;
struct arm_jtag *jtag_info;
...};
/* ... */
enum {
ETM_CTRL_POWERDOWN = (1 << 0),
ETM_CTRL_MONITOR_CPRT = (1 << 1),
ETM_CTRL_TRACE_DATA = (1 << 2),
ETM_CTRL_TRACE_ADDR = (2 << 2),
ETM_CTRL_TRACE_MASK = (3 << 2),
ETM_PORT_4BIT = 0x00,
ETM_PORT_8BIT = 0x10,
ETM_PORT_16BIT = 0x20,
ETM_PORT_24BIT = 0x30,
ETM_PORT_32BIT = 0x40,
ETM_PORT_48BIT = 0x50,
ETM_PORT_64BIT = 0x60,
ETM_PORT_1BIT = 0x00 | (1 << 21),
ETM_PORT_2BIT = 0x10 | (1 << 21),
ETM_PORT_WIDTH_MASK = 0x70 | (1 << 21),
ETM_CTRL_FIFOFULL_STALL = (1 << 7),
ETM_CTRL_BRANCH_OUTPUT = (1 << 8),
ETM_CTRL_DBGRQ = (1 << 9),
ETM_CTRL_ETM_PROG = (1 << 10),
ETM_CTRL_ETMEN = (1 << 11),
ETM_CTRL_CYCLE_ACCURATE = (1 << 12),
ETM_PORT_FULL_CLOCK = (0 << 13),
ETM_PORT_HALF_CLOCK = (1 << 13),
ETM_PORT_CLOCK_MASK = (1 << 13),
ETM_CTRL_CONTEXTID_NONE = (0 << 14),
ETM_CTRL_CONTEXTID_8 = (1 << 14),
ETM_CTRL_CONTEXTID_16 = (2 << 14),
ETM_CTRL_CONTEXTID_32 = (3 << 14),
ETM_CTRL_CONTEXTID_MASK = (3 << 14),
ETM_PORT_NORMAL = (0 << 16),
ETM_PORT_MUXED = (1 << 16),
ETM_PORT_DEMUXED = (2 << 16),
ETM_PORT_MODE_MASK = (3 << 16),
...};
struct etm_context;
struct etm_capture_driver {
const char *name;
const struct command_registration *commands;
int (*init)(struct etm_context *etm_ctx);
trace_status_t (*status)(struct etm_context *etm_ctx);
int (*read_trace)(struct etm_context *etm_ctx);
int (*start_capture)(struct etm_context *etm_ctx);
int (*stop_capture)(struct etm_context *etm_ctx);
...};
enum {
ETMV1_TRACESYNC_CYCLE = 0x1,
ETMV1_TRIGGER_CYCLE = 0x2,
...};
struct etmv1_trace_data {
uint8_t pipestat;
uint16_t packet;
int flags;
...};
/* ... */
struct etm_context {
struct target *target;
struct reg_cache *reg_cache;
struct etm_capture_driver *capture_driver;
void *capture_driver_priv;
trace_status_t capture_status;
struct etmv1_trace_data *trace_data;
uint32_t trace_depth;
uint32_t control;
int core_state;
struct image *image;
uint32_t pipe_index;
uint32_t data_index;
bool data_half;
bool pc_ok;
bool ptr_ok;
uint8_t bcd_vers;
uint32_t config;
uint32_t id;
uint32_t current_pc;
uint32_t last_branch;
uint32_t last_branch_reason;
uint32_t last_ptr;
uint32_t last_instruction;
...};
typedef enum {
STAT_IE = 0x0,
STAT_ID = 0x1,
STAT_IN = 0x2,
STAT_WT = 0x3,
STAT_BE = 0x4,
STAT_BD = 0x5,
STAT_TR = 0x6,
STAT_TD = 0x7
...} etmv1_pipestat_t;
typedef enum {
BR_NORMAL = 0x0,
BR_ENABLE = 0x1,
BR_RESTART = 0x2,
BR_NODEBUG = 0x3,
BR_PERIOD = 0x4,
BR_RSVD5 = 0x5,
BR_RSVD6 = 0x6,
BR_RSVD7 = 0x7,
...} etmv1_branch_reason_t;
struct reg_cache *etm_build_reg_cache(struct target *target,
struct arm_jtag *jtag_info, struct etm_context *etm_ctx);
int etm_setup(struct target *target);
extern const struct command_registration etm_command_handlers[];
#define ERROR_ETM_INVALID_DRIVER (-1300)
#define ERROR_ETM_PORTMODE_NOT_SUPPORTED (-1301)
#define ERROR_ETM_CAPTURE_INIT_FAILED (-1302)
#define ERROR_ETM_ANALYSIS_FAILED (-1303)
/* ... */
#endif