File Index
Files and directories
Sign in
FILE

arm-spe-pkt-decoder.c

File preview with syntax highlighting.

linux-6.19.14/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Arm Statistical Profiling Extensions (SPE) support
  4 * Copyright (c) 2017-2018, Arm Ltd.
  5 */
  6
  7#include <stdio.h>
  8#include <string.h>
  9#include <endian.h>
 10#include <byteswap.h>
 11#include <linux/bitops.h>
 12#include <stdarg.h>
 13#include <linux/kernel.h>
 14#include <linux/unaligned.h>
 15
 16#include "arm-spe-pkt-decoder.h"
 17
 18static const char * const arm_spe_packet_name[] = {
 19	[ARM_SPE_PAD]		= "PAD",
 20	[ARM_SPE_END]		= "END",
 21	[ARM_SPE_TIMESTAMP]	= "TS",
 22	[ARM_SPE_ADDRESS]	= "ADDR",
 23	[ARM_SPE_COUNTER]	= "LAT",
 24	[ARM_SPE_CONTEXT]	= "CONTEXT",
 25	[ARM_SPE_OP_TYPE]	= "OP-TYPE",
 26	[ARM_SPE_EVENTS]	= "EVENTS",
 27	[ARM_SPE_DATA_SOURCE]	= "DATA-SOURCE",
 28};
 29
 30const char *arm_spe_pkt_name(enum arm_spe_pkt_type type)
 31{
 32	return arm_spe_packet_name[type];
 33}
 34
 35/*
 36 * Extracts the field "sz" from header bits and converts to bytes:
 37 *   00 : byte (1)
 38 *   01 : halfword (2)
 39 *   10 : word (4)
 40 *   11 : doubleword (8)
 41 */
 42static unsigned int arm_spe_payload_len(unsigned char hdr)
 43{
 44	return 1U << ((hdr & GENMASK_ULL(5, 4)) >> 4);
 45}
 46
 47static int arm_spe_get_payload(const unsigned char *buf, size_t len,
 48			       unsigned char ext_hdr,
 49			       struct arm_spe_pkt *packet)
 50{
 51	size_t payload_len = arm_spe_payload_len(buf[ext_hdr]);
 52
 53	if (len < 1 + ext_hdr + payload_len)
 54		return ARM_SPE_NEED_MORE_BYTES;
 55
 56	buf += 1 + ext_hdr;
 57
 58	switch (payload_len) {
 59	case 1: packet->payload = *(uint8_t *)buf; break;
 60	case 2: packet->payload = get_unaligned_le16(buf); break;
 61	case 4: packet->payload = get_unaligned_le32(buf); break;
 62	case 8: packet->payload = get_unaligned_le64(buf); break;
 63	default: return ARM_SPE_BAD_PACKET;
 64	}
 65
 66	return 1 + ext_hdr + payload_len;
 67}
 68
 69static int arm_spe_get_pad(struct arm_spe_pkt *packet)
 70{
 71	packet->type = ARM_SPE_PAD;
 72	return 1;
 73}
 74
 75static int arm_spe_get_alignment(const unsigned char *buf, size_t len,
 76				 struct arm_spe_pkt *packet)
 77{
 78	unsigned int alignment = 1 << ((buf[0] & 0xf) + 1);
 79
 80	if (len < alignment)
 81		return ARM_SPE_NEED_MORE_BYTES;
 82
 83	packet->type = ARM_SPE_PAD;
 84	return alignment - (((uintptr_t)buf) & (alignment - 1));
 85}
 86
 87static int arm_spe_get_end(struct arm_spe_pkt *packet)
 88{
 89	packet->type = ARM_SPE_END;
 90	return 1;
 91}
 92
 93static int arm_spe_get_timestamp(const unsigned char *buf, size_t len,
 94				 struct arm_spe_pkt *packet)
 95{
 96	packet->type = ARM_SPE_TIMESTAMP;
 97	return arm_spe_get_payload(buf, len, 0, packet);
 98}
 99
100static int arm_spe_get_events(const unsigned char *buf, size_t len,
101			      struct arm_spe_pkt *packet)
102{
103	packet->type = ARM_SPE_EVENTS;
104
105	/* we use index to identify Events with a less number of
106	 * comparisons in arm_spe_pkt_desc(): E.g., the LLC-ACCESS,
107	 * LLC-REFILL, and REMOTE-ACCESS events are identified if
108	 * index > 1.
109	 */
110	packet->index = arm_spe_payload_len(buf[0]);
111
112	return arm_spe_get_payload(buf, len, 0, packet);
113}
114
115static int arm_spe_get_data_source(const unsigned char *buf, size_t len,
116				   struct arm_spe_pkt *packet)
117{
118	packet->type = ARM_SPE_DATA_SOURCE;
119	return arm_spe_get_payload(buf, len, 0, packet);
120}
121
122static int arm_spe_get_context(const unsigned char *buf, size_t len,
123			       struct arm_spe_pkt *packet)
124{
125	packet->type = ARM_SPE_CONTEXT;
126	packet->index = SPE_CTX_PKT_HDR_INDEX(buf[0]);
127	return arm_spe_get_payload(buf, len, 0, packet);
128}
129
130static int arm_spe_get_op_type(const unsigned char *buf, size_t len,
131			       struct arm_spe_pkt *packet)
132{
133	packet->type = ARM_SPE_OP_TYPE;
134	packet->index = SPE_OP_PKT_HDR_CLASS(buf[0]);
135	return arm_spe_get_payload(buf, len, 0, packet);
136}
137
138static int arm_spe_get_counter(const unsigned char *buf, size_t len,
139			       const unsigned char ext_hdr, struct arm_spe_pkt *packet)
140{
141	packet->type = ARM_SPE_COUNTER;
142
143	if (ext_hdr)
144		packet->index = SPE_HDR_EXTENDED_INDEX(buf[0], buf[1]);
145	else
146		packet->index = SPE_HDR_SHORT_INDEX(buf[0]);
147
148	return arm_spe_get_payload(buf, len, ext_hdr, packet);
149}
150
151static int arm_spe_get_addr(const unsigned char *buf, size_t len,
152			    const unsigned char ext_hdr, struct arm_spe_pkt *packet)
153{
154	packet->type = ARM_SPE_ADDRESS;
155
156	if (ext_hdr)
157		packet->index = SPE_HDR_EXTENDED_INDEX(buf[0], buf[1]);
158	else
159		packet->index = SPE_HDR_SHORT_INDEX(buf[0]);
160
161	return arm_spe_get_payload(buf, len, ext_hdr, packet);
162}
163
164static int arm_spe_do_get_packet(const unsigned char *buf, size_t len,
165				 struct arm_spe_pkt *packet)
166{
167	unsigned int hdr;
168	unsigned char ext_hdr = 0;
169
170	memset(packet, 0, sizeof(struct arm_spe_pkt));
171
172	if (!len)
173		return ARM_SPE_NEED_MORE_BYTES;
174
175	hdr = buf[0];
176
177	if (hdr == SPE_HEADER0_PAD)
178		return arm_spe_get_pad(packet);
179
180	if (hdr == SPE_HEADER0_END) /* no timestamp at end of record */
181		return arm_spe_get_end(packet);
182
183	if (hdr == SPE_HEADER0_TIMESTAMP)
184		return arm_spe_get_timestamp(buf, len, packet);
185
186	if ((hdr & SPE_HEADER0_MASK1) == SPE_HEADER0_EVENTS)
187		return arm_spe_get_events(buf, len, packet);
188
189	if ((hdr & SPE_HEADER0_MASK1) == SPE_HEADER0_SOURCE)
190		return arm_spe_get_data_source(buf, len, packet);
191
192	if ((hdr & SPE_HEADER0_MASK2) == SPE_HEADER0_CONTEXT)
193		return arm_spe_get_context(buf, len, packet);
194
195	if ((hdr & SPE_HEADER0_MASK2) == SPE_HEADER0_OP_TYPE)
196		return arm_spe_get_op_type(buf, len, packet);
197
198	if ((hdr & SPE_HEADER0_MASK2) == SPE_HEADER0_EXTENDED) {
199		/* 16-bit extended format header */
200		if (len == 1)
201			return ARM_SPE_BAD_PACKET;
202
203		ext_hdr = 1;
204		hdr = buf[1];
205		if (hdr == SPE_HEADER1_ALIGNMENT)
206			return arm_spe_get_alignment(buf, len, packet);
207	}
208
209	/*
210	 * The short format header's byte 0 or the extended format header's
211	 * byte 1 has been assigned to 'hdr', which uses the same encoding for
212	 * address packet and counter packet, so don't need to distinguish if
213	 * it's short format or extended format and handle in once.
214	 */
215	if ((hdr & SPE_HEADER0_MASK3) == SPE_HEADER0_ADDRESS)
216		return arm_spe_get_addr(buf, len, ext_hdr, packet);
217
218	if ((hdr & SPE_HEADER0_MASK3) == SPE_HEADER0_COUNTER)
219		return arm_spe_get_counter(buf, len, ext_hdr, packet);
220
221	return ARM_SPE_BAD_PACKET;
222}
223
224int arm_spe_get_packet(const unsigned char *buf, size_t len,
225		       struct arm_spe_pkt *packet)
226{
227	int ret;
228
229	ret = arm_spe_do_get_packet(buf, len, packet);
230	/* put multiple consecutive PADs on the same line, up to
231	 * the fixed-width output format of 16 bytes per line.
232	 */
233	if (ret > 0 && packet->type == ARM_SPE_PAD) {
234		while (ret < 16 && len > (size_t)ret && !buf[ret])
235			ret += 1;
236	}
237	return ret;
238}
239
240static int arm_spe_pkt_out_string(int *err, char **buf_p, size_t *blen,
241				  const char *fmt, ...)
242{
243	va_list ap;
244	int ret;
245
246	/* Bail out if any error occurred */
247	if (err && *err)
248		return *err;
249
250	va_start(ap, fmt);
251	ret = vsnprintf(*buf_p, *blen, fmt, ap);
252	va_end(ap);
253
254	if (ret < 0) {
255		if (err && !*err)
256			*err = ret;
257
258	/*
259	 * A return value of *blen or more means that the output was
260	 * truncated and the buffer is overrun.
261	 */
262	} else if ((size_t)ret >= *blen) {
263		(*buf_p)[*blen - 1] = '\0';
264
265		/*
266		 * Set *err to 'ret' to avoid overflow if tries to
267		 * fill this buffer sequentially.
268		 */
269		if (err && !*err)
270			*err = ret;
271	} else {
272		*buf_p += ret;
273		*blen -= ret;
274	}
275
276	return ret;
277}
278
279static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
280				  char *buf, size_t buf_len)
281{
282	u64 payload = packet->payload;
283	int err = 0;
284
285	arm_spe_pkt_out_string(&err, &buf, &buf_len, "EV");
286
287	if (payload & BIT(EV_EXCEPTION_GEN))
288		arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCEPTION-GEN");
289	if (payload & BIT(EV_RETIRED))
290		arm_spe_pkt_out_string(&err, &buf, &buf_len, " RETIRED");
291	if (payload & BIT(EV_L1D_ACCESS))
292		arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-ACCESS");
293	if (payload & BIT(EV_L1D_REFILL))
294		arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-REFILL");
295	if (payload & BIT(EV_TLB_ACCESS))
296		arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-ACCESS");
297	if (payload & BIT(EV_TLB_WALK))
298		arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-REFILL");
299	if (payload & BIT(EV_NOT_TAKEN))
300		arm_spe_pkt_out_string(&err, &buf, &buf_len, " NOT-TAKEN");
301	if (payload & BIT(EV_MISPRED))
302		arm_spe_pkt_out_string(&err, &buf, &buf_len, " MISPRED");
303	if (payload & BIT(EV_LLC_ACCESS))
304		arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-ACCESS");
305	if (payload & BIT(EV_LLC_MISS))
306		arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-REFILL");
307	if (payload & BIT(EV_REMOTE_ACCESS))
308		arm_spe_pkt_out_string(&err, &buf, &buf_len, " REMOTE-ACCESS");
309	if (payload & BIT(EV_ALIGNMENT))
310		arm_spe_pkt_out_string(&err, &buf, &buf_len, " ALIGNMENT");
311	if (payload & BIT(EV_TRANSACTIONAL))
312		arm_spe_pkt_out_string(&err, &buf, &buf_len, " TXN");
313	if (payload & BIT(EV_PARTIAL_PREDICATE))
314		arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-PARTIAL-PRED");
315	if (payload & BIT(EV_EMPTY_PREDICATE))
316		arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-EMPTY-PRED");
317	if (payload & BIT(EV_L2D_ACCESS))
318		arm_spe_pkt_out_string(&err, &buf, &buf_len, " L2D-ACCESS");
319	if (payload & BIT(EV_L2D_MISS))
320		arm_spe_pkt_out_string(&err, &buf, &buf_len, " L2D-MISS");
321	if (payload & BIT(EV_CACHE_DATA_MODIFIED))
322		arm_spe_pkt_out_string(&err, &buf, &buf_len, " HITM");
323	if (payload & BIT(EV_RECENTLY_FETCHED))
324		arm_spe_pkt_out_string(&err, &buf, &buf_len, " LFB");
325	if (payload & BIT(EV_DATA_SNOOPED))
326		arm_spe_pkt_out_string(&err, &buf, &buf_len, " SNOOPED");
327	if (payload & BIT(EV_STREAMING_SVE_MODE))
328		arm_spe_pkt_out_string(&err, &buf, &buf_len, " STREAMING-SVE");
329	if (payload & BIT(EV_SMCU))
330		arm_spe_pkt_out_string(&err, &buf, &buf_len, " SMCU");
331
332	return err;
333}
334
335static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet,
336				    char *buf, size_t buf_len)
337{
338	u64 payload = packet->payload;
339	int err = 0;
340
341	switch (packet->index) {
342	case SPE_OP_PKT_HDR_CLASS_OTHER:
343		if (SPE_OP_PKT_OTHER_SUBCLASS_SVE(payload)) {
344			arm_spe_pkt_out_string(&err, &buf, &buf_len, "SVE-OTHER");
345
346			/* SVE effective vector length */
347			arm_spe_pkt_out_string(&err, &buf, &buf_len, " EVLEN %d",
348					       SPE_OP_PKG_SVE_EVL(payload));
349
350			if (payload & SPE_OP_PKT_SVE_FP)
351				arm_spe_pkt_out_string(&err, &buf, &buf_len, " FP");
352			if (payload & SPE_OP_PKT_SVE_PRED)
353				arm_spe_pkt_out_string(&err, &buf, &buf_len, " PRED");
354		} else if (SPE_OP_PKT_OTHER_SUBCLASS_SME(payload)) {
355			arm_spe_pkt_out_string(&err, &buf, &buf_len, "SME-OTHER");
356
357			/* SME effective vector length or tile size */
358			arm_spe_pkt_out_string(&err, &buf, &buf_len, " ETS %d",
359					       SPE_OP_PKG_SME_ETS(payload));
360
361			if (payload & SPE_OP_PKT_OTHER_FP)
362				arm_spe_pkt_out_string(&err, &buf, &buf_len, " FP");
363		} else if (SPE_OP_PKT_OTHER_SUBCLASS_OTHER(payload)) {
364			arm_spe_pkt_out_string(&err, &buf, &buf_len, "OTHER");
365			if (payload & SPE_OP_PKT_OTHER_ASE)
366				arm_spe_pkt_out_string(&err, &buf, &buf_len, " ASE");
367			if (payload & SPE_OP_PKT_OTHER_FP)
368				arm_spe_pkt_out_string(&err, &buf, &buf_len, " FP");
369			arm_spe_pkt_out_string(&err, &buf, &buf_len, " %s",
370					       payload & SPE_OP_PKT_COND ?
371					       "COND-SELECT" : "INSN-OTHER");
372		}
373		break;
374	case SPE_OP_PKT_HDR_CLASS_LD_ST_ATOMIC:
375		arm_spe_pkt_out_string(&err, &buf, &buf_len,
376				       payload & 0x1 ? "ST" : "LD");
377
378		if (SPE_OP_PKT_LDST_SUBCLASS_EXTENDED(payload)) {
379			if (payload & SPE_OP_PKT_AT)
380				arm_spe_pkt_out_string(&err, &buf, &buf_len, " AT");
381			if (payload & SPE_OP_PKT_EXCL)
382				arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCL");
383			if (payload & SPE_OP_PKT_AR)
384				arm_spe_pkt_out_string(&err, &buf, &buf_len, " AR");
385		} else if (SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP(payload)) {
386			arm_spe_pkt_out_string(&err, &buf, &buf_len, " SIMD-FP");
387		} else if (SPE_OP_PKT_LDST_SUBCLASS_GP_REG(payload)) {
388			arm_spe_pkt_out_string(&err, &buf, &buf_len, " GP-REG");
389		} else if (SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG(payload)) {
390			arm_spe_pkt_out_string(&err, &buf, &buf_len, " UNSPEC-REG");
391		} else if (SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG(payload)) {
392			arm_spe_pkt_out_string(&err, &buf, &buf_len, " NV-SYSREG");
393		} else if (SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG(payload)) {
394			arm_spe_pkt_out_string(&err, &buf, &buf_len, " MTE-TAG");
395		} else if (SPE_OP_PKT_LDST_SUBCLASS_MEMCPY(payload)) {
396			arm_spe_pkt_out_string(&err, &buf, &buf_len, " MEMCPY");
397		} else if (SPE_OP_PKT_LDST_SUBCLASS_MEMSET(payload)) {
398			arm_spe_pkt_out_string(&err, &buf, &buf_len, " MEMSET");
399		} else if (SPE_OP_PKT_LDST_SUBCLASS_SVE_SME_REG(payload)) {
400			arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-SME-REG");
401
402			/* SVE effective vector length */
403			arm_spe_pkt_out_string(&err, &buf, &buf_len, " EVLEN %d",
404					       SPE_OP_PKG_SVE_EVL(payload));
405
406			if (payload & SPE_OP_PKT_SVE_PRED)
407				arm_spe_pkt_out_string(&err, &buf, &buf_len, " PRED");
408			if (payload & SPE_OP_PKT_SVE_SG)
409				arm_spe_pkt_out_string(&err, &buf, &buf_len, " SG");
410		} else if (SPE_OP_PKT_LDST_SUBCLASS_GCS(payload)) {
411			arm_spe_pkt_out_string(&err, &buf, &buf_len, " GCS");
412			if (payload & SPE_OP_PKT_GCS_COMM)
413				arm_spe_pkt_out_string(&err, &buf, &buf_len, " COMM");
414		}
415		break;
416	case SPE_OP_PKT_HDR_CLASS_BR_ERET:
417		arm_spe_pkt_out_string(&err, &buf, &buf_len, "B");
418
419		if (payload & SPE_OP_PKT_COND)
420			arm_spe_pkt_out_string(&err, &buf, &buf_len, " COND");
421		if (payload & SPE_OP_PKT_INDIRECT_BRANCH)
422			arm_spe_pkt_out_string(&err, &buf, &buf_len, " IND");
423		if (payload & SPE_OP_PKT_GCS)
424			arm_spe_pkt_out_string(&err, &buf, &buf_len, " GCS");
425		if (SPE_OP_PKT_CR_BL(payload))
426			arm_spe_pkt_out_string(&err, &buf, &buf_len, " CR-BL");
427		if (SPE_OP_PKT_CR_RET(payload))
428			arm_spe_pkt_out_string(&err, &buf, &buf_len, " CR-RET");
429		if (SPE_OP_PKT_CR_NON_BL_RET(payload))
430			arm_spe_pkt_out_string(&err, &buf, &buf_len, " CR-NON-BL-RET");
431		break;
432	default:
433		/* Unknown index */
434		err = -1;
435		break;
436	}
437
438	return err;
439}
440
441static int arm_spe_pkt_desc_addr(const struct arm_spe_pkt *packet,
442				 char *buf, size_t buf_len)
443{
444	int ns, el, idx = packet->index;
445	int ch, pat;
446	u64 payload = packet->payload;
447	int err = 0;
448	static const char *idx_name[] = {"PC", "TGT", "VA", "PA", "PBT"};
449
450	switch (idx) {
451	case SPE_ADDR_PKT_HDR_INDEX_INS:
452	case SPE_ADDR_PKT_HDR_INDEX_BRANCH:
453	case SPE_ADDR_PKT_HDR_INDEX_PREV_BRANCH:
454		ns = !!SPE_ADDR_PKT_GET_NS(payload);
455		el = SPE_ADDR_PKT_GET_EL(payload);
456		payload = SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload);
457		arm_spe_pkt_out_string(&err, &buf, &buf_len,
458				"%s 0x%llx el%d ns=%d",
459				idx_name[idx], payload, el, ns);
460		break;
461	case SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT:
462		arm_spe_pkt_out_string(&err, &buf, &buf_len,
463				       "VA 0x%llx", payload);
464		break;
465	case SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS:
466		ns = !!SPE_ADDR_PKT_GET_NS(payload);
467		ch = !!SPE_ADDR_PKT_GET_CH(payload);
468		pat = SPE_ADDR_PKT_GET_PAT(payload);
469		payload = SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload);
470		arm_spe_pkt_out_string(&err, &buf, &buf_len,
471				       "PA 0x%llx ns=%d ch=%d pat=%x",
472				       payload, ns, ch, pat);
473		break;
474	default:
475		/* Unknown index */
476		err = -1;
477		break;
478	}
479
480	return err;
481}
482
483static int arm_spe_pkt_desc_counter(const struct arm_spe_pkt *packet,
484				    char *buf, size_t buf_len)
485{
486	u64 payload = packet->payload;
487	const char *name = arm_spe_pkt_name(packet->type);
488	int err = 0;
489
490	arm_spe_pkt_out_string(&err, &buf, &buf_len, "%s %d ", name,
491			       (unsigned short)payload);
492
493	switch (packet->index) {
494	case SPE_CNT_PKT_HDR_INDEX_TOTAL_LAT:
495		arm_spe_pkt_out_string(&err, &buf, &buf_len, "TOT");
496		break;
497	case SPE_CNT_PKT_HDR_INDEX_ISSUE_LAT:
498		arm_spe_pkt_out_string(&err, &buf, &buf_len, "ISSUE");
499		break;
500	case SPE_CNT_PKT_HDR_INDEX_TRANS_LAT:
501		arm_spe_pkt_out_string(&err, &buf, &buf_len, "XLAT");
502		break;
503	default:
504		break;
505	}
506
507	return err;
508}
509
510int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf,
511		     size_t buf_len)
512{
513	int idx = packet->index;
514	unsigned long long payload = packet->payload;
515	const char *name = arm_spe_pkt_name(packet->type);
516	char *buf_orig = buf;
517	size_t blen = buf_len;
518	int err = 0;
519
520	switch (packet->type) {
521	case ARM_SPE_BAD:
522	case ARM_SPE_PAD:
523	case ARM_SPE_END:
524		arm_spe_pkt_out_string(&err, &buf, &blen, "%s", name);
525		break;
526	case ARM_SPE_EVENTS:
527		err = arm_spe_pkt_desc_event(packet, buf, buf_len);
528		break;
529	case ARM_SPE_OP_TYPE:
530		err = arm_spe_pkt_desc_op_type(packet, buf, buf_len);
531		break;
532	case ARM_SPE_DATA_SOURCE:
533	case ARM_SPE_TIMESTAMP:
534		arm_spe_pkt_out_string(&err, &buf, &blen, "%s %lld", name, payload);
535		break;
536	case ARM_SPE_ADDRESS:
537		err = arm_spe_pkt_desc_addr(packet, buf, buf_len);
538		break;
539	case ARM_SPE_CONTEXT:
540		arm_spe_pkt_out_string(&err, &buf, &blen, "%s 0x%lx el%d",
541				       name, (unsigned long)payload, idx + 1);
542		break;
543	case ARM_SPE_COUNTER:
544		err = arm_spe_pkt_desc_counter(packet, buf, buf_len);
545		break;
546	default:
547		/* Unknown packet type */
548		err = -1;
549		break;
550	}
551
552	/* Output raw data if detect any error */
553	if (err) {
554		err = 0;
555		arm_spe_pkt_out_string(&err, &buf_orig, &buf_len, "%s 0x%llx (%d)",
556				       name, payload, packet->index);
557	}
558
559	return err;
560}
~/ Read-only file preview.