+ trace_data[j++] = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_DATA].value, 0, 32);
+ i++;
+ } while ((i % arm7_9->etb->RAM_depth) != (first_frame % arm7_9->etb->RAM_depth));
+
+ for (i = 0, j = 0; i < arm7_9->etb->RAM_depth; i++)
+ {
+ int trigger = 0;
+
+ trace_output_len = 0;
+
+ /* catch trigger, actual PIPESTAT is encoded in TRACEPKT[2:0] */
+ if (PIPESTAT(trace_data[i]) == 0x6)
+ {
+ trigger = 1;
+ trace_data[i] &= ~0x7;
+ trace_data[i] |= TRACEPKT(trace_data[i]) & 0x7;
+ }
+
+ if (addressbits_valid == 32)
+ {
+ trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
+ "%i: 0x%8.8x %s", i, address, (trigger) ? "(TRIGGER) " : "");
+ }
+ else if (addressbits_valid != 0)
+ {
+ trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
+ "%i: 0x...%x %s", i, address, (trigger) ? "(TRIGGER) " : "");
+ }
+ else
+ {
+ trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
+ "%i: 0xUNK %s", i, (trigger) ? "(TRIGGER) " : "");
+ }
+
+ switch (PIPESTAT(trace_data[i]))
+ {
+ case 0x0:
+ trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
+ "IE");
+ break;
+ case 0x1:
+ trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
+ "ID");
+ break;
+ case 0x2:
+ /* Instruction exectued - TRACEPKT might be valid, but belongs to another cycle */
+ trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
+ "IN");
+ break;
+ case 0x3:
+ /* WAIT cycle - TRACEPKT is valid, but belongs to another cycle */
+ trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
+ "WT");
+ break;
+ case 0x4:
+ /* following a branch two APO cycles are output on PIPESTAT[1:0]
+ * but another BE/BD could overwrite the current branch,
+ * or a trigger could cause the APO to be output on TRACEPKT[1:0]
+ */
+ if ((PIPESTAT(trace_data[i + 1]) == 0x4)
+ || (PIPESTAT(trace_data[i + 1]) == 0x5))
+ {
+ /* another branch occured, we ignore this one */
+ j = (j < i + 1) ? i + 1 : j;
+ break;
+ }
+ else if (PIPESTAT(trace_data[i + 1]) == 0x6)
+ {
+ apo = TRACEPKT(trace_data[i + 1]) & 0x3;
+ }
+ else
+ {
+ apo = PIPESTAT(trace_data[i + 1]) & 0x3;
+ }
+
+ if ((PIPESTAT(trace_data[i + 2]) == 0x4)
+ || (PIPESTAT(trace_data[i + 2]) == 0x5))
+ {
+ j = (j < i + 2) ? i + 1 : j;
+ i = i + 1;
+ break;
+ }
+ else if (PIPESTAT(trace_data[i + 2]) == 0x6)
+ {
+ apo |= (TRACEPKT(trace_data[i + 2]) & 0x3) << 2;
+ }
+ else
+ {
+ apo = (PIPESTAT(trace_data[i + 1]) & 0x3) << 2;
+ }
+
+ branch_reason = -1;
+ k = 0;
+ do
+ {
+ if ((j = etmv1_next_packet(arm7_9->etb->RAM_depth, trace_data, j, &port_half, apo, &packet)) != -1)
+ {
+ address &= ~(0x7f << (k * 7));
+ address |= (packet & 0x7f) << (k * 7);
+ }
+ else
+ {
+ break;
+ }
+ k++;
+ } while ((k < 5) && (packet & 0x80));
+
+ if (addressbits_valid < ((k * 7 > 32) ? 32 : k * 7))
+ addressbits_valid = (k * 7 > 32) ? 32 : k * 7;
+
+ if (k == 5)
+ {
+ branch_reason = (packet & 0x7) >> 4;
+ trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
+ "BE 0x%x (/%i) (%s)", address, addressbits_valid, etmv1_branch_reason_string[branch_reason]);
+ }
+ else
+ {
+ trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
+ "BE 0x%x (/%i)", address, addressbits_valid);
+ }
+
+ break;
+ case 0x5:
+ trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
+ "BD");
+ break;
+ case 0x6:
+ /* We catch the trigger event before we get here */
+ ERROR("TR pipestat should have been caught earlier");
+ trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
+ "--");
+ break;
+ case 0x7:
+ /* TRACE disabled - TRACEPKT = invalid */
+ trace_output_len += snprintf(trace_output + trace_output_len, 256 - trace_output_len,
+ "TD");
+ break;
+ }
+
+ /* PIPESTAT other than WT (b011) and TD (b111) mean we executed an instruction */
+ if ((PIPESTAT(trace_data[i]) & 0x3) != 0x3)
+ {
+ last_instruction = i;
+ address += 4;
+ }
+
+ /* The group of packets for a particular instruction cannot start on or before any
+ * previous functional PIPESTAT (IE, IN, ID, BE, or BD)
+ */
+ if (j < last_instruction)
+ {
+ j = last_instruction + 1;
+ }
+
+ /* restore trigger PIPESTAT to ensure TRACEPKT is ignored */
+ if (trigger == 1)
+ {
+ trace_data[i] &= ~0x7;
+ trace_data[i] |= 0x6;
+ }
+
+ command_print(cmd_ctx, "%s (raw: 0x%8.8x)", trace_output, trace_data[i]);