0001
0002
0003
0004
0005
0006 #ifndef _GNU_SOURCE
0007 #define _GNU_SOURCE
0008 #endif
0009 #include <errno.h>
0010 #include <inttypes.h>
0011 #include <stdbool.h>
0012 #include <string.h>
0013 #include <stdint.h>
0014 #include <stdlib.h>
0015 #include <linux/bitops.h>
0016 #include <linux/compiler.h>
0017 #include <linux/zalloc.h>
0018
0019 #include "../auxtrace.h"
0020 #include "../debug.h"
0021 #include "../util.h"
0022
0023 #include "arm-spe-decoder.h"
0024
0025 static u64 arm_spe_calc_ip(int index, u64 payload)
0026 {
0027 u64 ns, el, val;
0028
0029
0030 if (index == SPE_ADDR_PKT_HDR_INDEX_INS ||
0031 index == SPE_ADDR_PKT_HDR_INDEX_BRANCH) {
0032 ns = SPE_ADDR_PKT_GET_NS(payload);
0033 el = SPE_ADDR_PKT_GET_EL(payload);
0034
0035
0036 payload = SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload);
0037
0038
0039 if (ns && (el == SPE_ADDR_PKT_EL1 || el == SPE_ADDR_PKT_EL2))
0040 payload |= 0xffULL << SPE_ADDR_PKT_ADDR_BYTE7_SHIFT;
0041
0042
0043 } else if (index == SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT) {
0044
0045
0046 payload = SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload);
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 val = SPE_ADDR_PKT_ADDR_GET_BYTE_6(payload);
0063 if ((val & 0xf0ULL) == 0xf0ULL)
0064 payload |= 0xffULL << SPE_ADDR_PKT_ADDR_BYTE7_SHIFT;
0065
0066
0067 } else if (index == SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS) {
0068
0069 payload = SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload);
0070 } else {
0071 pr_err("unsupported address packet index: 0x%x\n", index);
0072 }
0073
0074 return payload;
0075 }
0076
0077 struct arm_spe_decoder *arm_spe_decoder_new(struct arm_spe_params *params)
0078 {
0079 struct arm_spe_decoder *decoder;
0080
0081 if (!params->get_trace)
0082 return NULL;
0083
0084 decoder = zalloc(sizeof(struct arm_spe_decoder));
0085 if (!decoder)
0086 return NULL;
0087
0088 decoder->get_trace = params->get_trace;
0089 decoder->data = params->data;
0090
0091 return decoder;
0092 }
0093
0094 void arm_spe_decoder_free(struct arm_spe_decoder *decoder)
0095 {
0096 free(decoder);
0097 }
0098
0099 static int arm_spe_get_data(struct arm_spe_decoder *decoder)
0100 {
0101 struct arm_spe_buffer buffer = { .buf = 0, };
0102 int ret;
0103
0104 pr_debug("Getting more data\n");
0105 ret = decoder->get_trace(&buffer, decoder->data);
0106 if (ret < 0)
0107 return ret;
0108
0109 decoder->buf = buffer.buf;
0110 decoder->len = buffer.len;
0111
0112 if (!decoder->len)
0113 pr_debug("No more data\n");
0114
0115 return decoder->len;
0116 }
0117
0118 static int arm_spe_get_next_packet(struct arm_spe_decoder *decoder)
0119 {
0120 int ret;
0121
0122 do {
0123 if (!decoder->len) {
0124 ret = arm_spe_get_data(decoder);
0125
0126
0127 if (ret <= 0)
0128 return ret;
0129 }
0130
0131 ret = arm_spe_get_packet(decoder->buf, decoder->len,
0132 &decoder->packet);
0133 if (ret <= 0) {
0134
0135 decoder->buf += 1;
0136 decoder->len -= 1;
0137 return -EBADMSG;
0138 }
0139
0140 decoder->buf += ret;
0141 decoder->len -= ret;
0142 } while (decoder->packet.type == ARM_SPE_PAD);
0143
0144 return 1;
0145 }
0146
0147 static int arm_spe_read_record(struct arm_spe_decoder *decoder)
0148 {
0149 int err;
0150 int idx;
0151 u64 payload, ip;
0152
0153 memset(&decoder->record, 0x0, sizeof(decoder->record));
0154 decoder->record.context_id = (u64)-1;
0155
0156 while (1) {
0157 err = arm_spe_get_next_packet(decoder);
0158 if (err <= 0)
0159 return err;
0160
0161 idx = decoder->packet.index;
0162 payload = decoder->packet.payload;
0163
0164 switch (decoder->packet.type) {
0165 case ARM_SPE_TIMESTAMP:
0166 decoder->record.timestamp = payload;
0167 return 1;
0168 case ARM_SPE_END:
0169 return 1;
0170 case ARM_SPE_ADDRESS:
0171 ip = arm_spe_calc_ip(idx, payload);
0172 if (idx == SPE_ADDR_PKT_HDR_INDEX_INS)
0173 decoder->record.from_ip = ip;
0174 else if (idx == SPE_ADDR_PKT_HDR_INDEX_BRANCH)
0175 decoder->record.to_ip = ip;
0176 else if (idx == SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT)
0177 decoder->record.virt_addr = ip;
0178 else if (idx == SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS)
0179 decoder->record.phys_addr = ip;
0180 break;
0181 case ARM_SPE_COUNTER:
0182 if (idx == SPE_CNT_PKT_HDR_INDEX_TOTAL_LAT)
0183 decoder->record.latency = payload;
0184 break;
0185 case ARM_SPE_CONTEXT:
0186 decoder->record.context_id = payload;
0187 break;
0188 case ARM_SPE_OP_TYPE:
0189 if (idx == SPE_OP_PKT_HDR_CLASS_LD_ST_ATOMIC) {
0190 if (payload & 0x1)
0191 decoder->record.op = ARM_SPE_ST;
0192 else
0193 decoder->record.op = ARM_SPE_LD;
0194 }
0195 break;
0196 case ARM_SPE_EVENTS:
0197 if (payload & BIT(EV_L1D_REFILL))
0198 decoder->record.type |= ARM_SPE_L1D_MISS;
0199
0200 if (payload & BIT(EV_L1D_ACCESS))
0201 decoder->record.type |= ARM_SPE_L1D_ACCESS;
0202
0203 if (payload & BIT(EV_TLB_WALK))
0204 decoder->record.type |= ARM_SPE_TLB_MISS;
0205
0206 if (payload & BIT(EV_TLB_ACCESS))
0207 decoder->record.type |= ARM_SPE_TLB_ACCESS;
0208
0209 if (payload & BIT(EV_LLC_MISS))
0210 decoder->record.type |= ARM_SPE_LLC_MISS;
0211
0212 if (payload & BIT(EV_LLC_ACCESS))
0213 decoder->record.type |= ARM_SPE_LLC_ACCESS;
0214
0215 if (payload & BIT(EV_REMOTE_ACCESS))
0216 decoder->record.type |= ARM_SPE_REMOTE_ACCESS;
0217
0218 if (payload & BIT(EV_MISPRED))
0219 decoder->record.type |= ARM_SPE_BRANCH_MISS;
0220
0221 break;
0222 case ARM_SPE_DATA_SOURCE:
0223 decoder->record.source = payload;
0224 break;
0225 case ARM_SPE_BAD:
0226 break;
0227 case ARM_SPE_PAD:
0228 break;
0229 default:
0230 pr_err("Get packet error!\n");
0231 return -1;
0232 }
0233 }
0234
0235 return 0;
0236 }
0237
0238 int arm_spe_decode(struct arm_spe_decoder *decoder)
0239 {
0240 return arm_spe_read_record(decoder);
0241 }