- switch (trace_msg_type)
- {
- case 0: /* Exceptions */
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- exception = (trace_data->entries[i].data & 0x70) >> 4;
-
- /* FIXME: vector table may be at ffff0000 */
- branch_target = (trace_data->entries[i].data & 0xf0) >> 2;
- break;
-
- case 8: /* Direct Branch */
- break;
-
- case 9: /* Indirect Branch */
- xscale_branch_address(trace_data, i, &branch_target);
- break;
-
- case 13: /* Checkpointed Indirect Branch */
- xscale_branch_address(trace_data, i, &branch_target);
- if ((trace_data->num_checkpoints == 2) && (chkpt == 0))
- chkpt_reg = trace_data->chkpt1; /* 2 chkpts, this is oldest */
- else
- chkpt_reg = trace_data->chkpt0; /* 1 chkpt, or 2 and newest */
-
- chkpt++;
- break;
-
- case 12: /* Checkpointed Direct Branch */
- if ((trace_data->num_checkpoints == 2) && (chkpt == 0))
- chkpt_reg = trace_data->chkpt1; /* 2 chkpts, this is oldest */
- else
- chkpt_reg = trace_data->chkpt0; /* 1 chkpt, or 2 and newest */
-
- /* if no current_pc, checkpoint will be starting point */
- if (current_pc == 0)
- branch_target = chkpt_reg;
-
- chkpt++;
- break;
-
- case 15: /* Roll-over */
- break;
-
- default: /* Reserved */
- LOG_WARNING("trace is suspect: invalid trace message byte");
- continue;
-
- }
-
- /* If we don't have the current_pc yet, but we did get the branch target
- * (either from the trace buffer on indirect branch, or from a checkpoint reg),
- * then we can start displaying instructions at the next iteration, with
- * branch_target as the starting point.
- */
- if (current_pc == 0)
- {
- current_pc = branch_target; /* remains 0 unless branch_target obtained */
- continue;
- }
+ if (!xscale->trace.image)
+ LOG_WARNING("No trace image loaded; use 'xscale trace_image'");
+
+ /* loop for each trace buffer that was loaded from target */
+ while (trace_data) {
+ int chkpt = 0; /* incremented as checkpointed entries found */
+ int j;
+
+ /* FIXME: set this to correct mode when trace buffer is first enabled */
+ xscale->trace.core_state = ARM_STATE_ARM;
+
+ /* loop for each entry in this trace buffer */
+ for (i = 0; i < trace_data->depth; i++) {
+ int exception = 0;
+ uint32_t chkpt_reg = 0x0;
+ uint32_t branch_target = 0;
+ int count;
+
+ /* trace entry type is upper nybble of 'message byte' */
+ int trace_msg_type = (trace_data->entries[i].data & 0xf0) >> 4;
+
+ /* Target addresses of indirect branches are written into buffer
+ * before the message byte representing the branch. Skip past it */
+ if (trace_data->entries[i].type == XSCALE_TRACE_ADDRESS)
+ continue;
+
+ switch (trace_msg_type) {
+ case 0: /* Exceptions */
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ exception = (trace_data->entries[i].data & 0x70) >> 4;
+
+ /* FIXME: vector table may be at ffff0000 */
+ branch_target = (trace_data->entries[i].data & 0xf0) >> 2;
+ break;
+
+ case 8: /* Direct Branch */
+ break;
+
+ case 9: /* Indirect Branch */
+ xscale_branch_address(trace_data, i, &branch_target);
+ break;
+
+ case 13: /* Checkpointed Indirect Branch */
+ xscale_branch_address(trace_data, i, &branch_target);
+ if ((trace_data->num_checkpoints == 2) && (chkpt == 0))
+ chkpt_reg = trace_data->chkpt1; /* 2 chkpts, this is
+ *oldest */
+ else
+ chkpt_reg = trace_data->chkpt0; /* 1 chkpt, or 2 and
+ *newest */
+
+ chkpt++;
+ break;
+
+ case 12: /* Checkpointed Direct Branch */
+ if ((trace_data->num_checkpoints == 2) && (chkpt == 0))
+ chkpt_reg = trace_data->chkpt1; /* 2 chkpts, this is
+ *oldest */
+ else
+ chkpt_reg = trace_data->chkpt0; /* 1 chkpt, or 2 and
+ *newest */
+
+ /* if no current_pc, checkpoint will be starting point */
+ if (current_pc == 0)
+ branch_target = chkpt_reg;
+
+ chkpt++;
+ break;
+
+ case 15:/* Roll-over */
+ break;
+
+ default:/* Reserved */
+ LOG_WARNING("trace is suspect: invalid trace message byte");
+ continue;