92 { 0x78, 12,
WO, 0x20,
"ETM_sync_freq", },
93 { 0x7a, 22,
RO, 0x31,
"ETM_config_code_ext", },
94 { 0x7b, 32,
WO, 0x31,
"ETM_ext_input_select", },
95 { 0x7c, 32,
WO, 0x34,
"ETM_trace_start_stop", },
96 { 0x7d, 8,
WO, 0x34,
"ETM_behavior_control", },
107 #define ADDR_COMPARATOR(i) \
108 { ETM_ADDR_COMPARATOR_VALUE + (i) - 1, 32, WO, 0x10, \
109 "ETM_addr_" #i "_comparator_value", }, \
110 { ETM_ADDR_ACCESS_TYPE + (i) - 1, 7, WO, 0x10, \
111 "ETM_addr_" #i "_access_type", }
130 #undef ADDR_COMPARATOR
135 #define DATA_COMPARATOR(i) \
136 { ETM_DATA_COMPARATOR_VALUE + 2*(i) - 1, 32, WO, 0x10, \
137 "ETM_data_" #i "_comparator_value", }, \
138 { ETM_DATA_COMPARATOR_MASK + 2*(i) - 1, 32, WO, 0x10, \
139 "ETM_data_" #i "_comparator_mask", }
149 #undef DATA_COMPARATOR
153 #define ETM_COUNTER(i) \
154 { ETM_COUNTER_RELOAD_VALUE + (i) - 1, 16, WO, 0x10, \
155 "ETM_counter_" #i "_reload_value", }, \
156 { ETM_COUNTER_ENABLE + (i) - 1, 18, WO, 0x10, \
157 "ETM_counter_" #i "_enable", }, \
158 { ETM_COUNTER_RELOAD_EVENT + (i) - 1, 17, WO, 0x10, \
159 "ETM_counter_" #i "_reload_event", }, \
160 { ETM_COUNTER_VALUE + (i) - 1, 16, RO, 0x10, \
161 "ETM_counter_" #i "_value", }
172 { ETM_SEQUENCER_EVENT + (i), 17, WO, 0x10, \
173 "ETM_sequencer_event" #i, }
186 #define ETM_OUTPUT(i) \
187 { ETM_EXTERNAL_OUTPUT + (i) - 1, 17, WO, 0x10, \
188 "ETM_external_output" #i, }
202 { 0x6c, 32,
RO, 0x20,
"ETM_contextid_comparator_value1", }
203 { 0x6d, 32,
RO, 0x20,
"ETM_contextid_comparator_value2", }
204 { 0x6e, 32,
RO, 0x20,
"ETM_contextid_comparator_value3", }
205 { 0x6f, 32,
RO, 0x20,
"ETM_contextid_comparator_mask", }
210 uint8_t *check_value, uint8_t *check_mask);
228 for (i = 0; i < cache->
num_regs; i++) {
231 if (
reg->reg_info->addr ==
id)
237 LOG_ERROR(
"ETM: register 0x%02x not available",
id);
253 for (; nreg--; r++) {
256 LOG_ERROR(
"etm_reg_add is requested to add non-existing registers, ETM config might be bogus");
284 unsigned int bcd_vers,
config;
287 reg_list = calloc(128,
sizeof(
struct reg));
288 arch_info = calloc(128,
sizeof(
struct etm_reg));
290 if (!
reg_cache || !reg_list || !arch_info) {
325 bcd_vers = 0x10 + (((etm_ctx->
id) >> 4) & 0xff);
350 LOG_INFO(
"ETM v%d.%d", bcd_vers >> 4, bcd_vers & 0xf);
387 LOG_ERROR(
"etb selected as etm capture driver, but no ETB configured");
419 uint32_t etm_ctrl_value;
422 struct reg *etm_ctrl_reg;
438 etm_ctrl_value = (etm_ctrl_value
448 etm_ctx->
control = etm_ctrl_value;
460 LOG_ERROR(
"ETM capture driver initialization failed");
472 LOG_ERROR(
"BUG: error scheduling etm register read");
486 uint8_t *check_value, uint8_t *check_mask)
491 uint8_t reg_addr = r->
addr & 0x7f;
496 LOG_ERROR(
"BUG: can't read write-only register %s", r->
name);
549 LOG_ERROR(
"BUG: error scheduling etm register write");
578 uint8_t reg_addr = r->
addr & 0x7f;
583 LOG_ERROR(
"BUG: can't write read--only register %s", r->
name);
587 LOG_DEBUG(
"%s (%u): 0x%8.8" PRIx32
"", r->
name, reg_addr, value);
663 LOG_ERROR(
"error while reading instruction");
675 LOG_ERROR(
"error while reading instruction");
681 LOG_ERROR(
"BUG: tracing of jazelle code not supported");
684 LOG_ERROR(
"BUG: unknown core state encountered");
772 for (i = ctx->
pipe_index; i < ctx->data_index; i++) {
785 }
while ((packet & 0x80) && (shift < 28));
788 if ((shift == 28) && (packet & 0x80)) {
803 if ((shift == 32) && (packet & 0x80))
826 for (j = 0; j <
size; j++) {
833 LOG_ERROR(
"TODO: add support for 64-bit values");
835 }
else if (
size == 4)
878 int current_pc_ok = ctx->
pc_ok;
917 "abandoned branch encountered, correctness of analysis uncertain");
931 "--- tracing enabled at 0x%8.8" PRIx32
" ---",
939 "--- trace restarted after FIFO overflow at 0x%8.8" PRIx32
" ---",
947 "--- exit from debug state at 0x%8.8" PRIx32
" ---",
958 if (!current_pc_ok) {
960 "--- periodic synchronization point at 0x%8.8" PRIx32
" ---",
969 "BUG: branch reason code 0x%" PRIx32
" is reserved",
989 "exception vector 0x%2.2" PRIx32
"",
1015 cycles = old_index - last_instruction;
1020 uint32_t new_data_half = ctx->
data_half;
1038 ctx->
last_ptr |= (packet & 0x7f) << shift;
1040 }
while ((packet & 0x80) && (shift < 32));
1047 "address: 0x%8.8" PRIx32
"",
1055 for (i = 0; i < 16; i++) {
1062 "data: 0x%8.8" PRIx32
"",
1092 }
else if (pipestat ==
STAT_IN)
1096 char cycles_text[32] =
"";
1102 snprintf(cycles_text, 32,
" (%i %s)",
1104 (cycles == 1) ?
"cycle" :
"cycles");
1109 (pipestat ==
STAT_IN) ?
" (not executed)" :
"",
1135 if (strcmp(
CMD_ARGV[0],
"none") == 0)
1137 else if (strcmp(
CMD_ARGV[0],
"data") == 0)
1139 else if (strcmp(
CMD_ARGV[0],
"address") == 0)
1141 else if (strcmp(
CMD_ARGV[0],
"all") == 0)
1150 switch (context_id) {
1168 bool etmv1_cycle_accurate;
1170 if (etmv1_cycle_accurate)
1173 bool etmv1_branch_output;
1175 if (etmv1_branch_output)
1205 uint32_t tracemode = etm->
control;
1265 #define TRACEMODE_MASK ( \
1266 ETM_CTRL_CONTEXTID_MASK \
1267 | ETM_CTRL_BRANCH_OUTPUT \
1268 | ETM_CTRL_CYCLE_ACCURATE \
1269 | ETM_CTRL_TRACE_MASK \
1274 struct reg *etm_ctrl_reg;
1295 #undef TRACEMODE_MASK
1304 uint32_t portmode = 0x0;
1339 switch (port_width) {
1371 "unsupported ETM port width '%s'",
CMD_ARGV[1]);
1375 if (strcmp(
"normal",
CMD_ARGV[2]) == 0)
1377 else if (strcmp(
"multiplexed",
CMD_ARGV[2]) == 0)
1379 else if (strcmp(
"demultiplexed",
CMD_ARGV[2]) == 0)
1383 "unsupported ETM port mode '%s', must be 'normal', 'multiplexed' or 'demultiplexed'",
1388 if (strcmp(
"half",
CMD_ARGV[3]) == 0)
1390 else if (strcmp(
"full",
CMD_ARGV[3]) == 0)
1394 "unsupported ETM port clocking '%s', must be 'full' or 'half'",
1441 struct reg *etm_sys_config_reg;
1461 (
int) (etm->
config >> 0) & 0x0f);
1463 (
int) (etm->
config >> 4) & 0x0f);
1465 (
int) (etm->
config >> 8) & 0x1f);
1467 (
int) (etm->
config >> 13) & 0x07);
1469 (
int) (etm->
config & (1 << 16)) ?
"" :
"not ");
1471 (
int) (etm->
config >> 17) & 0x07);
1473 (
int) (etm->
config >> 20) & 0x07);
1475 (
int) (etm->
config & (1 << 23)) ?
"" :
"not ");
1478 (
int) (etm->
config >> 28) & 0x07);
1481 "coprocessor and memory access %ssupported",
1482 (etm->
config & (1 << 26)) ?
"" :
"not ");
1484 (etm->
config & (1 << 26)) ?
"" :
"not ");
1486 (
int) (etm->
config >> 24) & 0x03);
1491 if (!etm_sys_config_reg)
1499 max_port_size =
config & 0x7;
1501 max_port_size |= (
config >> 6) & 0x08;
1502 switch (max_port_size) {
1540 (
config & (1 << 3)) ?
"" :
"not ");
1542 (
config & (1 << 4)) ?
"" :
"not ");
1544 (
config & (1 << 5)) ?
"" :
"not ");
1546 (
config & (1 << 6)) ?
"" :
"not ");
1548 (
config & (1 << 7)) ?
"" :
"not ");
1552 (
config & (1 << 10)) ?
"" :
"not ");
1554 (
config & (1 << 11)) ?
"" :
"not ");
1558 (
config & (1 << 17)) ?
"not " :
"");
1560 (
config & (1 << 8)) ?
"" :
"not ");
1599 ?
"disabled" :
"enabled")
1601 ((s & (1 << 3)) && etm->
bcd_vers >= 0x31)
1602 ?
" triggered" :
"",
1603 ((s & (1 << 2)) && etm->
bcd_vers >= 0x12)
1604 ?
" start/stop" :
"",
1605 ((s & (1 << 0)) && etm->
bcd_vers >= 0x11)
1606 ?
" untraced-overflow" :
"");
1615 static char *completed =
" completed";
1616 static char *running =
" is running";
1617 static char *overflowed =
", overflowed";
1618 static char *triggered =
", triggered";
1657 if (etm_ctx->
image) {
1659 free(etm_ctx->
image);
1663 etm_ctx->
image = malloc(
sizeof(
struct image));
1676 free(etm_ctx->
image);
1709 command_print(
CMD,
"trace capture wasn't enabled, no trace data captured");
1805 uint32_t pipestat, packet, flags;
1824 struct reg *etm_ctrl_reg;
1869 struct reg *etm_ctrl_reg;
1923 struct reg *etm_ctrl_reg;
1945 :
"does not trigger");
1975 "further analysis failed (corrupted trace data or just end of data");
1979 "no instruction for current address available, analysis aborted");
2000 .handler = handle_etm_config_command,
2002 .help =
"Set up ETM output port.",
2003 .usage =
"target port_width port_mode clocking capture_driver",
2011 .help =
"Embedded Trace Macrocell command group",
2020 .
name =
"tracemode",
2021 .handler = handle_etm_tracemode_command,
2023 .help =
"configure/display trace mode",
2024 .usage =
"('none'|'data'|'address'|'all') "
2026 "['enable'|'disable'] "
2027 "['enable'|'disable']",
2031 .handler = handle_etm_info_command,
2034 .help =
"display info about the current target's ETM",
2038 .handler = handle_etm_status_command,
2041 .help =
"display current target's ETM status",
2045 .handler = handle_etm_start_command,
2048 .help =
"start ETM trace collection",
2052 .handler = handle_etm_stop_command,
2055 .help =
"stop ETM trace collection",
2058 .name =
"trigger_debug",
2059 .handler = handle_etm_trigger_debug_command,
2061 .help =
"enable/disable debug entry on trigger",
2062 .usage =
"['enable'|'disable']",
2066 .handler = handle_etm_analyze_command,
2069 .help =
"analyze collected ETM trace",
2073 .handler = handle_etm_image_command,
2075 .help =
"load image from file with optional offset",
2076 .usage =
"<file> [base address] [type]",
2080 .handler = handle_etm_dump_command,
2082 .help =
"dump captured trace data to file",
2083 .usage =
"filename",
2087 .handler = handle_etm_load_command,
2090 .help =
"load trace data for analysis <file>",
Holds the interface to ARM cores.
static bool is_arm(struct arm *arm)
static struct arm * target_to_arm(const struct target *target)
Convert target handle to generic ARM target state handle.
int arm_evaluate_opcode(uint32_t opcode, uint32_t address, struct arm_instruction *instruction)
int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruction *instruction)
int arm_access_size(struct arm_instruction *instruction)
static int arm_jtag_scann(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state)
static int arm_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr, void *no_verify_capture, tap_state_t end_state)
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
void command_print(struct command_invocation *cmd, const char *format,...)
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_PARSE_ENABLE(in, out)
parses an enable/disable command argument
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
static int register_commands(struct command_context *cmd_ctx, const char *cmd_prefix, const struct command_registration *cmds)
Register one or more commands in the specified context, as children of parent (or top-level commends,...
struct reg_cache * etb_build_reg_cache(struct etb *etb)
struct etm_capture_driver etb_capture_driver
static int etmv1_next_packet(struct etm_context *ctx, uint8_t *packet, int apo)
struct reg_cache * etm_build_reg_cache(struct target *target, struct arm_jtag *jtag_info, struct etm_context *etm_ctx)
static int etm_read_reg_w_check(struct reg *reg, uint8_t *check_value, uint8_t *check_mask)
int etm_setup(struct target *target)
static const struct command_registration etm_config_command_handlers[]
static struct etm_capture_driver * etm_capture_drivers[]
#define DATA_COMPARATOR(i)
static void etm_reg_add(unsigned int bcd_vers, struct arm_jtag *jtag_info, struct reg_cache *cache, struct etm_reg *ereg, const struct etm_reg_info *r, unsigned int nreg)
static int etm_store_reg(struct reg *reg)
static const struct etm_reg_info etm_core[]
static int etm_set_reg(struct reg *reg, uint32_t value)
static const struct etm_reg_info etm_outputs[]
static int etm_read_reg(struct reg *reg)
static struct reg * etm_reg_lookup(struct etm_context *etm_ctx, unsigned int id)
const struct command_registration etm_command_handlers[]
static int etmv1_branch_address(struct etm_context *ctx)
static const struct etm_reg_info etm_data_comp[]
static const struct etm_reg_info etm_fifofull[]
static const struct command_registration etm_exec_command_handlers[]
static COMMAND_HELPER(handle_etm_tracemode_command_update, uint32_t *mode)
#define ADDR_COMPARATOR(i)
static int etm_write_reg(struct reg *reg, uint32_t value)
static int etm_get_reg(struct reg *reg)
static const struct etm_reg_info etm_counters[]
static int etm_set_reg_w_exec(struct reg *reg, uint8_t *buf)
static const struct reg_arch_type etm_scan6_type
COMMAND_HANDLER(handle_etm_tracemode_command)
static int etmv1_data(struct etm_context *ctx, int size, uint32_t *data)
static int etm_register_user_commands(struct command_context *cmd_ctx)
static const struct etm_reg_info etm_basic[]
static const struct etm_reg_info etm_sequencer[]
static const struct etm_reg_info etm_addr_comp[]
static int etm_read_instruction(struct etm_context *ctx, struct arm_instruction *instruction)
static int etmv1_analyze_trace(struct etm_context *ctx, struct command_invocation *cmd)
#define ERROR_ETM_ANALYSIS_FAILED
@ ETM_TRACE_RESOURCE_CTRL
@ ETM_CTRL_CONTEXTID_NONE
@ ETM_CTRL_CONTEXTID_MASK
@ ETM_CTRL_CYCLE_ACCURATE
struct etm_capture_driver etm_dummy_capture_driver
int fileio_write_u32(struct fileio *fileio, uint32_t data)
int fileio_read_u32(struct fileio *fileio, uint32_t *data)
int fileio_close(struct fileio *fileio)
int fileio_size(struct fileio *fileio, size_t *size)
FIX!!!!
int fileio_open(struct fileio **fileio, const char *url, enum fileio_access access_type, enum fileio_type type)
void image_close(struct image *image)
int image_read_section(struct image *image, int section, target_addr_t offset, uint32_t size, uint8_t *buffer, size_t *size_read)
int image_open(struct image *image, const char *url, const char *type_string)
static struct device_config config
int jtag_execute_queue(void)
For software FIFO implementations, the queued commands can be executed during this call or earlier.
void jtag_add_dr_scan_check(struct jtag_tap *active, int in_num_fields, struct scan_field *in_fields, tap_state_t state)
A version of jtag_add_dr_scan() that uses the check_value/mask fields.
void jtag_add_dr_scan(struct jtag_tap *active, int in_num_fields, const struct scan_field *in_fields, tap_state_t state)
Generate a DR SCAN using the fields passed to the function.
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
size_t size
Size of the control block search area.
struct arm_load_store_multiple_instr load_store_multiple
enum arm_instruction_type type
struct arm_b_bl_bx_blx_instr b_bl_bx_blx
union arm_instruction::@69 info
Represents a generic ARM core, with standard application registers.
struct etm_context * etm
Handle for the Embedded Trace Module, if one is present.
When run_command is called, a new instance will be created on the stack, filled with the proper value...
struct reg_cache * reg_cache
struct etm_context * etm_ctx
int(* stop_capture)(struct etm_context *etm_ctx)
int(* init)(struct etm_context *etm_ctx)
int(* start_capture)(struct etm_context *etm_ctx)
int(* read_trace)(struct etm_context *etm_ctx)
trace_status_t(* status)(struct etm_context *etm_ctx)
struct etm_capture_driver * capture_driver
uint32_t last_instruction
struct etmv1_trace_data * trace_data
uint32_t last_branch_reason
trace_status_t capture_status
void * capture_driver_priv
struct reg_cache * reg_cache
struct arm_jtag * jtag_info
const struct etm_reg_info * reg_info
unsigned int num_sections
struct imagesection * sections
target_addr_t base_address
int(* get)(struct reg *reg)
const struct reg_arch_type * type
This structure defines a single scan field in the scan.
uint8_t * in_value
A pointer to a 32-bit memory location for data scanned out.
uint8_t * check_value
The value used to check the data scanned out.
const uint8_t * out_value
A pointer to value to be scanned into the device.
unsigned int num_bits
The number of bits this field specifies.
uint8_t * check_mask
The mask to go with check_value.
struct target * get_target(const char *id)
uint16_t target_buffer_get_u16(struct target *target, const uint8_t *buffer)
struct target * get_current_target(struct command_context *cmd_ctx)
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
const char * target_type_name(const struct target *target)
Get the target type name.
static const char * target_name(const struct target *target)
Returns the instance-specific name of the specified target.
#define ERROR_TRACE_INSTRUCTION_UNAVAILABLE
enum trace_status trace_status_t
#define ERROR_TRACE_IMAGE_UNAVAILABLE
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.