1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * arm_spe_decoder.h: Arm Statistical Profiling Extensions support |
4 | * Copyright (c) 2019-2020, Arm Ltd. |
5 | */ |
6 | |
7 | #ifndef INCLUDE__ARM_SPE_DECODER_H__ |
8 | #define INCLUDE__ARM_SPE_DECODER_H__ |
9 | |
10 | #include <stdbool.h> |
11 | #include <stddef.h> |
12 | #include <stdint.h> |
13 | |
14 | #include "arm-spe-pkt-decoder.h" |
15 | |
16 | enum arm_spe_sample_type { |
17 | ARM_SPE_L1D_ACCESS = 1 << 0, |
18 | ARM_SPE_L1D_MISS = 1 << 1, |
19 | ARM_SPE_LLC_ACCESS = 1 << 2, |
20 | ARM_SPE_LLC_MISS = 1 << 3, |
21 | ARM_SPE_TLB_ACCESS = 1 << 4, |
22 | ARM_SPE_TLB_MISS = 1 << 5, |
23 | ARM_SPE_BRANCH_MISS = 1 << 6, |
24 | ARM_SPE_REMOTE_ACCESS = 1 << 7, |
25 | ARM_SPE_SVE_PARTIAL_PRED = 1 << 8, |
26 | ARM_SPE_SVE_EMPTY_PRED = 1 << 9, |
27 | }; |
28 | |
29 | enum arm_spe_op_type { |
30 | /* First level operation type */ |
31 | ARM_SPE_OP_OTHER = 1 << 0, |
32 | ARM_SPE_OP_LDST = 1 << 1, |
33 | ARM_SPE_OP_BRANCH_ERET = 1 << 2, |
34 | |
35 | /* Second level operation type for OTHER */ |
36 | ARM_SPE_OP_SVE_OTHER = 1 << 16, |
37 | ARM_SPE_OP_SVE_FP = 1 << 17, |
38 | ARM_SPE_OP_SVE_PRED_OTHER = 1 << 18, |
39 | |
40 | /* Second level operation type for LDST */ |
41 | ARM_SPE_OP_LD = 1 << 16, |
42 | ARM_SPE_OP_ST = 1 << 17, |
43 | ARM_SPE_OP_ATOMIC = 1 << 18, |
44 | ARM_SPE_OP_EXCL = 1 << 19, |
45 | ARM_SPE_OP_AR = 1 << 20, |
46 | ARM_SPE_OP_SIMD_FP = 1 << 21, |
47 | ARM_SPE_OP_GP_REG = 1 << 22, |
48 | ARM_SPE_OP_UNSPEC_REG = 1 << 23, |
49 | ARM_SPE_OP_NV_SYSREG = 1 << 24, |
50 | ARM_SPE_OP_SVE_LDST = 1 << 25, |
51 | ARM_SPE_OP_SVE_PRED_LDST = 1 << 26, |
52 | ARM_SPE_OP_SVE_SG = 1 << 27, |
53 | |
54 | /* Second level operation type for BRANCH_ERET */ |
55 | ARM_SPE_OP_BR_COND = 1 << 16, |
56 | ARM_SPE_OP_BR_INDIRECT = 1 << 17, |
57 | }; |
58 | |
59 | enum arm_spe_neoverse_data_source { |
60 | ARM_SPE_NV_L1D = 0x0, |
61 | ARM_SPE_NV_L2 = 0x8, |
62 | ARM_SPE_NV_PEER_CORE = 0x9, |
63 | ARM_SPE_NV_LOCAL_CLUSTER = 0xa, |
64 | ARM_SPE_NV_SYS_CACHE = 0xb, |
65 | ARM_SPE_NV_PEER_CLUSTER = 0xc, |
66 | ARM_SPE_NV_REMOTE = 0xd, |
67 | ARM_SPE_NV_DRAM = 0xe, |
68 | }; |
69 | |
70 | struct arm_spe_record { |
71 | enum arm_spe_sample_type type; |
72 | int err; |
73 | u32 op; |
74 | u32 latency; |
75 | u64 from_ip; |
76 | u64 to_ip; |
77 | u64 timestamp; |
78 | u64 virt_addr; |
79 | u64 phys_addr; |
80 | u64 context_id; |
81 | u16 source; |
82 | }; |
83 | |
84 | struct arm_spe_insn; |
85 | |
86 | struct arm_spe_buffer { |
87 | const unsigned char *buf; |
88 | size_t len; |
89 | u64 offset; |
90 | u64 trace_nr; |
91 | }; |
92 | |
93 | struct arm_spe_params { |
94 | int (*get_trace)(struct arm_spe_buffer *buffer, void *data); |
95 | void *data; |
96 | }; |
97 | |
98 | struct arm_spe_decoder { |
99 | int (*get_trace)(struct arm_spe_buffer *buffer, void *data); |
100 | void *data; |
101 | struct arm_spe_record record; |
102 | |
103 | const unsigned char *buf; |
104 | size_t len; |
105 | |
106 | struct arm_spe_pkt packet; |
107 | }; |
108 | |
109 | struct arm_spe_decoder *arm_spe_decoder_new(struct arm_spe_params *params); |
110 | void arm_spe_decoder_free(struct arm_spe_decoder *decoder); |
111 | |
112 | int arm_spe_decode(struct arm_spe_decoder *decoder); |
113 | |
114 | #endif |
115 | |