1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * arm_spe_decoder.c: ARM SPE support 4 */ 5 6 #ifndef _GNU_SOURCE 7 #define _GNU_SOURCE 8 #endif 9 #include <errno.h> 10 #include <inttypes.h> 11 #include <stdbool.h> 12 #include <string.h> 13 #include <stdint.h> 14 #include <stdlib.h> 15 #include <linux/compiler.h> 16 #include <linux/zalloc.h> 17 18 #include "../auxtrace.h" 19 #include "../debug.h" 20 #include "../util.h" 21 22 #include "arm-spe-decoder.h" 23 24 #ifndef BIT 25 #define BIT(n) (1UL << (n)) 26 #endif 27 28 static u64 arm_spe_calc_ip(int index, u64 payload) 29 { 30 u8 *addr = (u8 *)&payload; 31 int ns, el; 32 33 /* Instruction virtual address or Branch target address */ 34 if (index == SPE_ADDR_PKT_HDR_INDEX_INS || 35 index == SPE_ADDR_PKT_HDR_INDEX_BRANCH) { 36 ns = addr[7] & SPE_ADDR_PKT_NS; 37 el = (addr[7] & SPE_ADDR_PKT_EL_MASK) >> SPE_ADDR_PKT_EL_OFFSET; 38 39 /* Fill highest byte for EL1 or EL2 (VHE) mode */ 40 if (ns && (el == SPE_ADDR_PKT_EL1 || el == SPE_ADDR_PKT_EL2)) 41 addr[7] = 0xff; 42 /* Clean highest byte for other cases */ 43 else 44 addr[7] = 0x0; 45 46 /* Data access virtual address */ 47 } else if (index == SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT) { 48 49 /* Fill highest byte if bits [48..55] is 0xff */ 50 if (addr[6] == 0xff) 51 addr[7] = 0xff; 52 /* Otherwise, cleanup tags */ 53 else 54 addr[7] = 0x0; 55 56 /* Data access physical address */ 57 } else if (index == SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS) { 58 /* Cleanup byte 7 */ 59 addr[7] = 0x0; 60 } else { 61 pr_err("unsupported address packet index: 0x%x\n", index); 62 } 63 64 return payload; 65 } 66 67 struct arm_spe_decoder *arm_spe_decoder_new(struct arm_spe_params *params) 68 { 69 struct arm_spe_decoder *decoder; 70 71 if (!params->get_trace) 72 return NULL; 73 74 decoder = zalloc(sizeof(struct arm_spe_decoder)); 75 if (!decoder) 76 return NULL; 77 78 decoder->get_trace = params->get_trace; 79 decoder->data = params->data; 80 81 return decoder; 82 } 83 84 void arm_spe_decoder_free(struct arm_spe_decoder *decoder) 85 { 86 free(decoder); 87 } 88 89 static int arm_spe_get_data(struct arm_spe_decoder *decoder) 90 { 91 struct arm_spe_buffer buffer = { .buf = 0, }; 92 int ret; 93 94 pr_debug("Getting more data\n"); 95 ret = decoder->get_trace(&buffer, decoder->data); 96 if (ret < 0) 97 return ret; 98 99 decoder->buf = buffer.buf; 100 decoder->len = buffer.len; 101 102 if (!decoder->len) 103 pr_debug("No more data\n"); 104 105 return decoder->len; 106 } 107 108 static int arm_spe_get_next_packet(struct arm_spe_decoder *decoder) 109 { 110 int ret; 111 112 do { 113 if (!decoder->len) { 114 ret = arm_spe_get_data(decoder); 115 116 /* Failed to read out trace data */ 117 if (ret <= 0) 118 return ret; 119 } 120 121 ret = arm_spe_get_packet(decoder->buf, decoder->len, 122 &decoder->packet); 123 if (ret <= 0) { 124 /* Move forward for 1 byte */ 125 decoder->buf += 1; 126 decoder->len -= 1; 127 return -EBADMSG; 128 } 129 130 decoder->buf += ret; 131 decoder->len -= ret; 132 } while (decoder->packet.type == ARM_SPE_PAD); 133 134 return 1; 135 } 136 137 static int arm_spe_read_record(struct arm_spe_decoder *decoder) 138 { 139 int err; 140 int idx; 141 u64 payload, ip; 142 143 memset(&decoder->record, 0x0, sizeof(decoder->record)); 144 145 while (1) { 146 err = arm_spe_get_next_packet(decoder); 147 if (err <= 0) 148 return err; 149 150 idx = decoder->packet.index; 151 payload = decoder->packet.payload; 152 153 switch (decoder->packet.type) { 154 case ARM_SPE_TIMESTAMP: 155 decoder->record.timestamp = payload; 156 return 1; 157 case ARM_SPE_END: 158 return 1; 159 case ARM_SPE_ADDRESS: 160 ip = arm_spe_calc_ip(idx, payload); 161 if (idx == SPE_ADDR_PKT_HDR_INDEX_INS) 162 decoder->record.from_ip = ip; 163 else if (idx == SPE_ADDR_PKT_HDR_INDEX_BRANCH) 164 decoder->record.to_ip = ip; 165 break; 166 case ARM_SPE_COUNTER: 167 break; 168 case ARM_SPE_CONTEXT: 169 break; 170 case ARM_SPE_OP_TYPE: 171 break; 172 case ARM_SPE_EVENTS: 173 if (payload & BIT(EV_L1D_REFILL)) 174 decoder->record.type |= ARM_SPE_L1D_MISS; 175 176 if (payload & BIT(EV_L1D_ACCESS)) 177 decoder->record.type |= ARM_SPE_L1D_ACCESS; 178 179 if (payload & BIT(EV_TLB_WALK)) 180 decoder->record.type |= ARM_SPE_TLB_MISS; 181 182 if (payload & BIT(EV_TLB_ACCESS)) 183 decoder->record.type |= ARM_SPE_TLB_ACCESS; 184 185 if ((idx == 1 || idx == 2 || idx == 3) && 186 (payload & BIT(EV_LLC_MISS))) 187 decoder->record.type |= ARM_SPE_LLC_MISS; 188 189 if ((idx == 1 || idx == 2 || idx == 3) && 190 (payload & BIT(EV_LLC_ACCESS))) 191 decoder->record.type |= ARM_SPE_LLC_ACCESS; 192 193 if ((idx == 1 || idx == 2 || idx == 3) && 194 (payload & BIT(EV_REMOTE_ACCESS))) 195 decoder->record.type |= ARM_SPE_REMOTE_ACCESS; 196 197 if (payload & BIT(EV_MISPRED)) 198 decoder->record.type |= ARM_SPE_BRANCH_MISS; 199 200 break; 201 case ARM_SPE_DATA_SOURCE: 202 break; 203 case ARM_SPE_BAD: 204 break; 205 case ARM_SPE_PAD: 206 break; 207 default: 208 pr_err("Get packet error!\n"); 209 return -1; 210 } 211 } 212 213 return 0; 214 } 215 216 int arm_spe_decode(struct arm_spe_decoder *decoder) 217 { 218 return arm_spe_read_record(decoder); 219 } 220