cvmx-tra.c revision 210284
1/***********************license start*************** 2 * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights 3 * reserved. 4 * 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * 18 * * Neither the name of Cavium Networks nor the names of 19 * its contributors may be used to endorse or promote products 20 * derived from this software without specific prior written 21 * permission. 22 * 23 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 24 * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS 25 * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH 26 * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY 27 * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT 28 * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES 29 * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR 30 * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET 31 * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT 32 * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 33 * 34 * 35 * For any questions regarding licensing please contact marketing@caviumnetworks.com 36 * 37 ***********************license end**************************************/ 38 39 40 41 42 43/** 44 * @file 45 * 46 * Interface to the Trace buffer hardware. 47 * 48 * <hr>$Revision: 30644 $<hr> 49 */ 50#include "cvmx.h" 51#include "cvmx-tra.h" 52 53static const char *TYPE_ARRAY[] = { 54 "DWB - Don't write back", 55 "PL2 - Prefetch into L2", 56 "PSL1 - Dcache fill, skip L2", 57 "LDD - Dcache fill", 58 "LDI - Icache/IO fill", 59 "LDT - Icache/IO fill, skip L2", 60 "STF - Store full", 61 "STC - Store conditional", 62 "STP - Store partial", 63 "STT - Store full, skip L2", 64 "IOBLD8 - IOB 8bit load", 65 "IOBLD16 - IOB 16bit load", 66 "IOBLD32 - IOB 32bit load", 67 "IOBLD64 - IOB 64bit load", 68 "IOBST - IOB store", 69 "IOBDMA - Async IOB", 70 "SAA - Store atomic add", 71 "RSVD17", 72 "RSVD18", 73 "RSVD19", 74 "RSVD20", 75 "RSVD21", 76 "RSVD22", 77 "RSVD23", 78 "RSVD24", 79 "RSVD25", 80 "RSVD26", 81 "RSVD27", 82 "RSVD28", 83 "RSVD29", 84 "RSVD30", 85 "RSVD31" 86}; 87 88static const char *SOURCE_ARRAY[] = { 89 "PP0", 90 "PP1", 91 "PP2", 92 "PP3", 93 "PP4", 94 "PP5", 95 "PP6", 96 "PP7", 97 "PP8", 98 "PP9", 99 "PP10", 100 "PP11", 101 "PP12", 102 "PP13", 103 "PP14", 104 "PP15", 105 "PIP/IPD", 106 "PKO-R", 107 "FPA/TIM/DFA/PCI/ZIP/POW/PKO-W", 108 "DWB", 109 "RSVD20", 110 "RSVD21", 111 "RSVD22", 112 "RSVD23", 113 "RSVD24", 114 "RSVD25", 115 "RSVD26", 116 "RSVD27", 117 "RSVD28", 118 "RSVD29", 119 "RSVD30", 120 "RSVD31" 121}; 122 123static const char *DEST_ARRAY[] = { 124 "CIU/GPIO", 125 "RSVD1", 126 "RSVD2", 127 "PCI/PCIe", 128 "KEY", 129 "FPA", 130 "DFA", 131 "ZIP", 132 "RNG", 133 "IPD", 134 "PKO", 135 "RSVD11", 136 "POW", 137 "RSVD13", 138 "RSVD14", 139 "RSVD15", 140 "RSVD16", 141 "RSVD17", 142 "RSVD18", 143 "RSVD19", 144 "RSVD20", 145 "RSVD21", 146 "RSVD22", 147 "RSVD23", 148 "RSVD24", 149 "RSVD25", 150 "RSVD26", 151 "RSVD27", 152 "RSVD28", 153 "RSVD29", 154 "RSVD30", 155 "RSVD31" 156}; 157 158/** 159 * Setup the TRA buffer for use 160 * 161 * @param control TRA control setup 162 * @param filter Which events to log 163 * @param source_filter 164 * Source match 165 * @param dest_filter 166 * Destination match 167 * @param address Address compare 168 * @param address_mask 169 * Address mask 170 */ 171void cvmx_tra_setup(cvmx_tra_ctl_t control, cvmx_tra_filt_cmd_t filter, 172 cvmx_tra_filt_sid_t source_filter, cvmx_tra_filt_did_t dest_filter, 173 uint64_t address, uint64_t address_mask) 174{ 175 cvmx_write_csr(CVMX_TRA_CTL, control.u64); 176 cvmx_write_csr(CVMX_TRA_FILT_CMD, filter.u64); 177 cvmx_write_csr(CVMX_TRA_FILT_SID, source_filter.u64); 178 cvmx_write_csr(CVMX_TRA_FILT_DID, dest_filter.u64); 179 cvmx_write_csr(CVMX_TRA_FILT_ADR_ADR, address); 180 cvmx_write_csr(CVMX_TRA_FILT_ADR_MSK, address_mask); 181} 182 183 184/** 185 * Setup a TRA trigger. How the triggers are used should be 186 * setup using cvmx_tra_setup. 187 * 188 * @param trigger Trigger to setup (0 or 1) 189 * @param filter Which types of events to trigger on 190 * @param source_filter 191 * Source trigger match 192 * @param dest_filter 193 * Destination trigger match 194 * @param address Trigger address compare 195 * @param address_mask 196 * Trigger address mask 197 */ 198void cvmx_tra_trig_setup(uint64_t trigger, cvmx_tra_filt_cmd_t filter, 199 cvmx_tra_filt_sid_t source_filter, cvmx_tra_trig0_did_t dest_filter, 200 uint64_t address, uint64_t address_mask) 201{ 202 cvmx_write_csr(CVMX_TRA_TRIG0_CMD + trigger * 64, filter.u64); 203 cvmx_write_csr(CVMX_TRA_TRIG0_SID + trigger * 64, source_filter.u64); 204 cvmx_write_csr(CVMX_TRA_TRIG0_DID + trigger * 64, dest_filter.u64); 205 cvmx_write_csr(CVMX_TRA_TRIG0_ADR_ADR + trigger * 64, address); 206 cvmx_write_csr(CVMX_TRA_TRIG0_ADR_MSK + trigger * 64, address_mask); 207} 208 209 210/** 211 * Read an entry from the TRA buffer 212 * 213 * @return Value return. High bit will be zero if there wasn't any data 214 */ 215cvmx_tra_data_t cvmx_tra_read(void) 216{ 217 cvmx_tra_data_t result; 218 result.u64 = cvmx_read_csr(CVMX_TRA_READ_DAT); 219 return result; 220} 221 222 223/** 224 * Decode a TRA entry into human readable output 225 * 226 * @param tra_ctl Trace control setup 227 * @param data Data to decode 228 */ 229void cvmx_tra_decode_text(cvmx_tra_ctl_t tra_ctl, cvmx_tra_data_t data) 230{ 231 /* The type is a five bit field for some entries and 4 for other. The four 232 bit entries can be mis-typed if the top is set */ 233 int type = data.cmn.type; 234 if (type >= 0x1a) 235 type &= 0xf; 236 switch (type) 237 { 238 case CVMX_TRA_DATA_DWB: 239 case CVMX_TRA_DATA_PL2: 240 case CVMX_TRA_DATA_PSL1: 241 case CVMX_TRA_DATA_LDD: 242 case CVMX_TRA_DATA_LDI: 243 case CVMX_TRA_DATA_LDT: 244 cvmx_dprintf("0x%016llx %c%+10d %s %s 0x%016llx\n", 245 (unsigned long long)data.u64, 246 (data.cmn.discontinuity) ? 'D' : ' ', 247 data.cmn.timestamp << (tra_ctl.s.time_grn*3), 248 TYPE_ARRAY[type], 249 SOURCE_ARRAY[data.cmn.source], 250 (unsigned long long)data.cmn.address); 251 break; 252 case CVMX_TRA_DATA_STC: 253 case CVMX_TRA_DATA_STF: 254 case CVMX_TRA_DATA_STP: 255 case CVMX_TRA_DATA_STT: 256 case CVMX_TRA_DATA_SAA: 257 cvmx_dprintf("0x%016llx %c%+10d %s %s mask=0x%02x 0x%016llx\n", 258 (unsigned long long)data.u64, 259 (data.cmn.discontinuity) ? 'D' : ' ', 260 data.cmn.timestamp << (tra_ctl.s.time_grn*3), 261 TYPE_ARRAY[type], 262 SOURCE_ARRAY[data.store.source], 263 (unsigned int)data.store.mask, 264 (unsigned long long)data.store.address << 3); 265 break; 266 case CVMX_TRA_DATA_IOBLD8: 267 case CVMX_TRA_DATA_IOBLD16: 268 case CVMX_TRA_DATA_IOBLD32: 269 case CVMX_TRA_DATA_IOBLD64: 270 case CVMX_TRA_DATA_IOBST: 271 cvmx_dprintf("0x%016llx %c%+10d %s %s->%s subdid=0x%x 0x%016llx\n", 272 (unsigned long long)data.u64, 273 (data.cmn.discontinuity) ? 'D' : ' ', 274 data.cmn.timestamp << (tra_ctl.s.time_grn*3), 275 TYPE_ARRAY[type], 276 SOURCE_ARRAY[data.iobld.source], 277 DEST_ARRAY[data.iobld.dest], 278 (unsigned int)data.iobld.subid, 279 (unsigned long long)data.iobld.address); 280 break; 281 case CVMX_TRA_DATA_IOBDMA: 282 cvmx_dprintf("0x%016llx %c%+10d %s %s->%s len=0x%x 0x%016llx\n", 283 (unsigned long long)data.u64, 284 (data.cmn.discontinuity) ? 'D' : ' ', 285 data.cmn.timestamp << (tra_ctl.s.time_grn*3), 286 TYPE_ARRAY[type], 287 SOURCE_ARRAY[data.iob.source], 288 DEST_ARRAY[data.iob.dest], 289 (unsigned int)data.iob.mask, 290 (unsigned long long)data.iob.address << 3); 291 break; 292 default: 293 cvmx_dprintf("0x%016llx %c%+10d Unknown format\n", 294 (unsigned long long)data.u64, 295 (data.cmn.discontinuity) ? 'D' : ' ', 296 data.cmn.timestamp << (tra_ctl.s.time_grn*3)); 297 break; 298 } 299} 300 301 302/** 303 * Display the entire trace buffer. It is advised that you 304 * disable the trace buffer before calling this routine 305 * otherwise it could infinitely loop displaying trace data 306 * that it created. 307 */ 308void cvmx_tra_display(void) 309{ 310 cvmx_tra_ctl_t tra_ctl; 311 cvmx_tra_data_t data; 312 313 tra_ctl.u64 = cvmx_read_csr(CVMX_TRA_CTL); 314 315 do 316 { 317 data = cvmx_tra_read(); 318 if (data.cmn.valid) 319 cvmx_tra_decode_text(tra_ctl, data); 320 } while (data.cmn.valid); 321} 322 323