Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * arm_spe_decoder.c: ARM SPE support
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     /* Instruction virtual address or Branch target address */
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         /* Clean highest byte */
0036         payload = SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload);
0037 
0038         /* Fill highest byte for EL1 or EL2 (VHE) mode */
0039         if (ns && (el == SPE_ADDR_PKT_EL1 || el == SPE_ADDR_PKT_EL2))
0040             payload |= 0xffULL << SPE_ADDR_PKT_ADDR_BYTE7_SHIFT;
0041 
0042     /* Data access virtual address */
0043     } else if (index == SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT) {
0044 
0045         /* Clean tags */
0046         payload = SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload);
0047 
0048         /*
0049          * Armv8 ARM (ARM DDI 0487F.c), chapter "D10.2.1 Address packet"
0050          * defines the data virtual address payload format, the top byte
0051          * (bits [63:56]) is assigned as top-byte tag; so we only can
0052          * retrieve address value from bits [55:0].
0053          *
0054          * According to Documentation/arm64/memory.rst, if detects the
0055          * specific pattern in bits [55:52] of payload which falls in
0056          * the kernel space, should fixup the top byte and this allows
0057          * perf tool to parse DSO symbol for data address correctly.
0058          *
0059          * For this reason, if detects the bits [55:52] is 0xf, will
0060          * fill 0xff into the top byte.
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     /* Data access physical address */
0067     } else if (index == SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS) {
0068         /* Clean highest byte */
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             /* Failed to read out trace data */
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             /* Move forward for 1 byte */
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 }