1 /***********************license start***************
2 * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
18 * * Neither the name of Cavium Inc. nor the names of
19 * its contributors may be used to endorse or promote products
20 * derived from this software without specific prior written
23 * This Software, including technical data, may be subject to U.S. export control
24 * laws, including the U.S. Export Administration Act and its associated
25 * regulations, and may be subject to export or import regulations in other
28 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29 * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31 * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32 * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33 * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34 * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35 * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36 * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
37 * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38 ***********************license end**************************************/
48 * Interface to the Trace buffer hardware.
50 * <hr>$Revision: 30644 $<hr>
52 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
53 #include <linux/module.h>
54 #include <asm/octeon/cvmx.h>
55 #include <asm/octeon/cvmx-tra.h>
56 #include <asm/octeon/cvmx-l2c.h>
63 static const char *TYPE_ARRAY[] = {
64 "DWB - Don't write back",
65 "PL2 - Prefetch into L2",
66 "PSL1 - Dcache fill, skip L2",
68 "LDI - Icache/IO fill",
69 "LDT - Icache/IO fill, skip L2",
71 "STC - Store conditional",
72 "STP - Store partial",
73 "STT - Store full, skip L2",
74 "IOBLD8 - IOB 8bit load",
75 "IOBLD16 - IOB 16bit load",
76 "IOBLD32 - IOB 32bit load",
77 "IOBLD64 - IOB 64bit load",
80 "SAA - Store atomic add",
98 static const char *TYPE_ARRAY2[] = {
100 "LDT - Icache/IO fill, skip L2",
101 "LDI - Icache/IO fill",
102 "PL2 - Prefetch into L2",
103 "RPL2 - Mark for replacement in L2",
104 "DWB - Don't write back",
108 "PSL1 - Prefetch L1, skip L2",
114 "IOBDMA - Async IOB",
116 "STT - Store full, skip L2",
117 "STP - Store partial",
118 "STC - Store conditional",
119 "STFIL1 - Store full, invalidate L1",
120 "STTIL1 - Store full, skip L2, invalidate L1",
121 "FAS32 - Atomic 32bit swap",
122 "FAS64 - Atomic 64bit swap",
123 "WBIL2i - Writeback, invalidate, by index/way",
124 "LTGL2i - Read tag@index/way",
125 "STGL2i - Write tag@index/way",
127 "INVL2 - Invalidate, by address",
128 "WBIL2 - Writeback, invalidate, by address",
129 "WBL2 - Writeback, by address",
130 "LCKL2 - Allocate, lock, by address",
131 "IOBLD8 - IOB 8bit load",
132 "IOBLD16 - IOB 16bit load",
133 "IOBLD32 - IOB 32bit load",
134 "IOBLD64 - IOB 64bit load",
135 "IOBST8 - IOB 8bit store",
136 "IOBST16 - IOB 16bit store",
137 "IOBST32 - IOB 32bit store",
138 "IOBST64 - IOB 64bit store",
139 "SET8 - 8bit Atomic swap with 1's",
140 "SET16 - 16bit Atomic swap with 1's",
141 "SET32 - 32bit Atomic swap with 1's",
142 "SET64 - 64bit Atomic swap with 1's",
143 "CLR8 - 8bit Atomic swap with 0's",
144 "CLR16 - 16bit Atomic swap with 0's",
145 "CLR32 - 32bit Atomic swap with 0's",
146 "CLR64 - 64bit Atomic swap with 0's",
147 "INCR8 - 8bit Atomic fetch & add by 1",
148 "INCR16 - 16bit Atomic fetch & add by 1",
149 "INCR32 - 32bit Atomic fetch & add by 1",
150 "INCR64 - 64bit Atomic fetch & add by 1",
151 "DECR8 - 8bit Atomic fetch & add by -1",
152 "DECR16 - 16bit Atomic fetch & add by -1",
153 "DECR32 - 32bit Atomic fetch & add by -1",
154 "DECR64 - 64bit Atomic fetch & add by -1",
157 "FAA32 - 32bit Atomic fetch and add",
158 "FAA64 - 64bit Atomic fetch and add",
161 "SAA32 - 32bit Atomic add",
162 "SAA64 - 64bit Atomic add"
165 static const char *SOURCE_ARRAY[] = {
184 "FPA/TIM/DFA/PCI/ZIP/POW/PKO-W",
216 static const char *DEST_ARRAY[] = {
251 int _cvmx_tra_unit = 0;
253 #define CVMX_TRA_SOURCE_MASK (OCTEON_IS_MODEL(OCTEON_CN63XX) ? 0xf00ff : 0xfffff)
254 #define CVMX_TRA_DESTINATION_MASK 0xfffffffful
258 * Setup the trace buffer filter command mask. The bit position of filter commands
259 * are different for each Octeon model.
261 * @param filter Which event to log
262 * @return Bitmask of filter command based on the event.
264 static uint64_t __cvmx_tra_set_filter_cmd_mask(cvmx_tra_filt_t filter)
266 cvmx_tra_filt_cmd_t filter_command;
268 if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN5XXX))
270 /* Bit positions of filter commands are different, map it accordingly */
272 if ((filter & CVMX_TRA_FILT_ALL) == -1ull)
274 if (OCTEON_IS_MODEL(OCTEON_CN5XXX))
279 if (filter & CVMX_TRA_FILT_DWB)
281 if (filter & CVMX_TRA_FILT_PL2)
283 if (filter & CVMX_TRA_FILT_PSL1)
285 if (filter & CVMX_TRA_FILT_LDD)
287 if (filter & CVMX_TRA_FILT_LDI)
289 if (filter & CVMX_TRA_FILT_LDT)
291 if (filter & CVMX_TRA_FILT_STF)
293 if (filter & CVMX_TRA_FILT_STC)
295 if (filter & CVMX_TRA_FILT_STP)
297 if (filter & CVMX_TRA_FILT_STT)
299 if (filter & CVMX_TRA_FILT_IOBLD8)
301 if (filter & CVMX_TRA_FILT_IOBLD16)
303 if (filter & CVMX_TRA_FILT_IOBLD32)
305 if (filter & CVMX_TRA_FILT_IOBLD64)
307 if (filter & CVMX_TRA_FILT_IOBST)
309 if (filter & CVMX_TRA_FILT_IOBDMA)
311 if (OCTEON_IS_MODEL(OCTEON_CN5XXX) && (filter & CVMX_TRA_FILT_SAA))
314 filter_command.u64 = cmd;
318 if ((filter & CVMX_TRA_FILT_ALL) == -1ull)
319 filter_command.u64 = CVMX_TRA_FILT_ALL;
321 filter_command.u64 = filter;
323 filter_command.cn63xx.reserved_60_61 = 0;
324 filter_command.cn63xx.reserved_56_57 = 0;
325 filter_command.cn63xx.reserved_27_27 = 0;
326 filter_command.cn63xx.reserved_10_14 = 0;
327 filter_command.cn63xx.reserved_6_7 = 0;
329 return filter_command.u64;
334 * Setup the TRA buffer for use
336 * @param control TRA control setup
337 * @param filter Which events to log
338 * @param source_filter
342 * @param address Address compare
343 * @param address_mask
346 void cvmx_tra_setup(cvmx_tra_ctl_t control, cvmx_tra_filt_t filter,
347 cvmx_tra_sid_t source_filter, cvmx_tra_did_t dest_filter,
348 uint64_t address, uint64_t address_mask)
350 cvmx_tra_filt_cmd_t filt_cmd;
351 cvmx_tra_filt_sid_t filt_sid;
352 cvmx_tra_filt_did_t filt_did;
355 filt_cmd.u64 = __cvmx_tra_set_filter_cmd_mask(filter);
356 filt_sid.u64 = source_filter & CVMX_TRA_SOURCE_MASK;
357 filt_did.u64 = dest_filter & CVMX_TRA_DESTINATION_MASK;
359 /* Address filtering does not work when IOBDMA filter command is enabled
360 because of some caveats. Disable the IOBDMA filter command. */
361 if ((OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF7XXX))
362 && ((filt_cmd.u64 & CVMX_TRA_FILT_IOBDMA) == CVMX_TRA_FILT_IOBDMA)
363 && address_mask != 0)
365 cvmx_dprintf("The address-based filtering does not work with IOBDMAs, disabling the filter command.\n");
366 filt_cmd.u64 &= ~(CVMX_TRA_FILT_IOBDMA);
369 /* In OcteonII pass2, the mode bit is added to enable reading the trace
370 buffer data from different registers for lower and upper 64-bit value.
371 This bit is reserved in other Octeon models. */
372 control.s.rdat_md = 1;
374 for (tad = 0; tad < CVMX_L2C_TADS; tad++)
376 cvmx_write_csr(CVMX_TRAX_CTL(tad), control.u64);
377 cvmx_write_csr(CVMX_TRAX_FILT_CMD(tad), filt_cmd.u64);
378 cvmx_write_csr(CVMX_TRAX_FILT_SID(tad), filt_sid.u64);
379 cvmx_write_csr(CVMX_TRAX_FILT_DID(tad), filt_did.u64);
380 cvmx_write_csr(CVMX_TRAX_FILT_ADR_ADR(tad), address);
381 cvmx_write_csr(CVMX_TRAX_FILT_ADR_MSK(tad), address_mask);
384 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
385 EXPORT_SYMBOL(cvmx_tra_setup);
389 * Setup each TRA buffer for use
391 * @param tra Which TRA buffer to use (0-3)
392 * @param control TRA control setup
393 * @param filter Which events to log
394 * @param source_filter
398 * @param address Address compare
399 * @param address_mask
402 void cvmx_tra_setup_v2(int tra, cvmx_tra_ctl_t control, cvmx_tra_filt_t filter,
403 cvmx_tra_sid_t source_filter, cvmx_tra_did_t dest_filter,
404 uint64_t address, uint64_t address_mask)
406 cvmx_tra_filt_cmd_t filt_cmd;
407 cvmx_tra_filt_sid_t filt_sid;
408 cvmx_tra_filt_did_t filt_did;
410 if ((tra + 1) > CVMX_L2C_TADS)
412 cvmx_dprintf("cvmx_tra_setup_per_tra: Invalid tra(%d), max allowed (%d)\n", tra, CVMX_L2C_TADS - 1);
416 filt_cmd.u64 = __cvmx_tra_set_filter_cmd_mask(filter);
417 filt_sid.u64 = source_filter & CVMX_TRA_SOURCE_MASK;
418 filt_did.u64 = dest_filter & CVMX_TRA_DESTINATION_MASK;
420 /* Address filtering does not work when IOBDMA filter command is enabled
421 because of some caveats. Disable the IOBDMA filter command. */
422 if ((OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF7XXX))
423 && ((filt_cmd.u64 & CVMX_TRA_FILT_IOBDMA) == CVMX_TRA_FILT_IOBDMA)
424 && address_mask != 0)
426 cvmx_dprintf("The address-based filtering does not work with IOBDMAs, disabling the filter command.\n");
427 filt_cmd.u64 &= ~(CVMX_TRA_FILT_IOBDMA);
430 /* In OcteonII pass2, the mode bit is added to enable reading the trace
431 buffer data from different registers for lower and upper 64-bit value.
432 This bit is reserved in other Octeon models. */
433 control.s.rdat_md = 1;
435 cvmx_write_csr(CVMX_TRAX_CTL(tra), control.u64);
436 cvmx_write_csr(CVMX_TRAX_FILT_CMD(tra), filt_cmd.u64);
437 cvmx_write_csr(CVMX_TRAX_FILT_SID(tra), filt_sid.u64);
438 cvmx_write_csr(CVMX_TRAX_FILT_DID(tra), filt_did.u64);
439 cvmx_write_csr(CVMX_TRAX_FILT_ADR_ADR(tra), address);
440 cvmx_write_csr(CVMX_TRAX_FILT_ADR_MSK(tra), address_mask);
442 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
443 EXPORT_SYMBOL(cvmx_tra_setup_v2);
447 * Setup a TRA trigger. How the triggers are used should be
448 * setup using cvmx_tra_setup.
450 * @param trigger Trigger to setup (0 or 1)
451 * @param filter Which types of events to trigger on
452 * @param source_filter
453 * Source trigger match
455 * Destination trigger match
456 * @param address Trigger address compare
457 * @param address_mask
458 * Trigger address mask
460 void cvmx_tra_trig_setup(uint64_t trigger, cvmx_tra_filt_t filter,
461 cvmx_tra_sid_t source_filter, cvmx_tra_did_t dest_filter,
462 uint64_t address, uint64_t address_mask)
464 cvmx_tra_filt_cmd_t tra_filt_cmd;
465 cvmx_tra_filt_sid_t tra_filt_sid;
466 cvmx_tra_filt_did_t tra_filt_did;
469 tra_filt_cmd.u64 = __cvmx_tra_set_filter_cmd_mask(filter);
470 tra_filt_sid.u64 = source_filter & CVMX_TRA_SOURCE_MASK;
471 tra_filt_did.u64 = dest_filter & CVMX_TRA_DESTINATION_MASK;
473 /* Address filtering does not work when IOBDMA filter command is enabled
474 because of some caveats. Disable the IOBDMA filter command. */
475 if ((OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF7XXX))
476 && ((tra_filt_cmd.u64 & CVMX_TRA_FILT_IOBDMA) == CVMX_TRA_FILT_IOBDMA)
477 && address_mask != 0)
479 cvmx_dprintf("The address-based filtering does not work with IOBDMAs, disabling the filter command.\n");
480 tra_filt_cmd.u64 &= ~(CVMX_TRA_FILT_IOBDMA);
483 for (tad = 0; tad < CVMX_L2C_TADS; tad++)
485 cvmx_write_csr(CVMX_TRAX_TRIG0_CMD(tad) + trigger * 64, tra_filt_cmd.u64);
486 cvmx_write_csr(CVMX_TRAX_TRIG0_SID(tad) + trigger * 64, tra_filt_sid.u64);
487 cvmx_write_csr(CVMX_TRAX_TRIG0_DID(tad) + trigger * 64, tra_filt_did.u64);
488 cvmx_write_csr(CVMX_TRAX_TRIG0_ADR_ADR(tad) + trigger * 64, address);
489 cvmx_write_csr(CVMX_TRAX_TRIG0_ADR_MSK(tad) + trigger * 64, address_mask);
492 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
493 EXPORT_SYMBOL(cvmx_tra_trig_setup);
497 * Setup each TRA trigger. How the triggers are used should be
498 * setup using cvmx_tra_setup.
500 * @param tra Which TRA buffer to use (0-3)
501 * @param trigger Trigger to setup (0 or 1)
502 * @param filter Which types of events to trigger on
503 * @param source_filter
504 * Source trigger match
506 * Destination trigger match
507 * @param address Trigger address compare
508 * @param address_mask
509 * Trigger address mask
511 void cvmx_tra_trig_setup_v2(int tra, uint64_t trigger, cvmx_tra_filt_t filter,
512 cvmx_tra_sid_t source_filter, cvmx_tra_did_t dest_filter,
513 uint64_t address, uint64_t address_mask)
515 cvmx_tra_filt_cmd_t tra_filt_cmd;
516 cvmx_tra_filt_sid_t tra_filt_sid;
517 cvmx_tra_filt_did_t tra_filt_did;
519 tra_filt_cmd.u64 = __cvmx_tra_set_filter_cmd_mask(filter);
520 tra_filt_sid.u64 = source_filter & CVMX_TRA_SOURCE_MASK;
521 tra_filt_did.u64 = dest_filter & CVMX_TRA_DESTINATION_MASK;
523 /* Address filtering does not work when IOBDMA filter command is enabled
524 because of some caveats. Disable the IOBDMA filter command. */
525 if ((OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF7XXX))
526 && ((tra_filt_cmd.u64 & CVMX_TRA_FILT_IOBDMA) == CVMX_TRA_FILT_IOBDMA)
527 && address_mask != 0)
529 cvmx_dprintf("The address-based filtering does not work with IOBDMAs, disabling the filter command.\n");
530 tra_filt_cmd.u64 &= ~(CVMX_TRA_FILT_IOBDMA);
533 cvmx_write_csr(CVMX_TRAX_TRIG0_CMD(tra) + trigger * 64, tra_filt_cmd.u64);
534 cvmx_write_csr(CVMX_TRAX_TRIG0_SID(tra) + trigger * 64, tra_filt_sid.u64);
535 cvmx_write_csr(CVMX_TRAX_TRIG0_DID(tra) + trigger * 64, tra_filt_did.u64);
536 cvmx_write_csr(CVMX_TRAX_TRIG0_ADR_ADR(tra) + trigger * 64, address);
537 cvmx_write_csr(CVMX_TRAX_TRIG0_ADR_MSK(tra) + trigger * 64, address_mask);
539 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
540 EXPORT_SYMBOL(cvmx_tra_trig_setup_v2);
544 * Read an entry from the TRA buffer
546 * @return Value return. High bit will be zero if there wasn't any data
548 cvmx_tra_data_t cvmx_tra_read(void)
550 uint64_t address = CVMX_TRA_READ_DAT;
551 cvmx_tra_data_t result;
553 /* The trace buffer format is wider than 64-bits in OcteonII model,
554 read the register again to get the second part of the data. */
555 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
557 /* These reads need to be as close as possible to each other */
558 result.u128.data = cvmx_read_csr(address);
559 result.u128.datahi = cvmx_read_csr(address);
561 else if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) && !OCTEON_IS_MODEL(OCTEON_CN5XXX))
563 /* OcteonII pass2 uses different trace buffer data register for reading
564 lower and upper 64-bit values */
565 result.u128.data = cvmx_read_csr(address);
566 result.u128.datahi = cvmx_read_csr(CVMX_TRA_READ_DAT_HI);
570 result.u128.data = cvmx_read_csr(address);
571 result.u128.datahi = 0;
578 * Read an entry from the TRA buffer from a given TRA unit.
580 * @param tra_unit Trace buffer unit to read
582 * @return Value return. High bit will be zero if there wasn't any data
584 cvmx_tra_data_t cvmx_tra_read_v2(int tra_unit)
586 cvmx_tra_data_t result;
588 result.u128.data = cvmx_read_csr(CVMX_TRAX_READ_DAT(tra_unit));
589 result.u128.datahi = cvmx_read_csr(CVMX_TRAX_READ_DAT_HI(tra_unit));
595 * Decode a TRA entry into human readable output
597 * @param tra_ctl Trace control setup
598 * @param data Data to decode
600 void cvmx_tra_decode_text(cvmx_tra_ctl_t tra_ctl, cvmx_tra_data_t data)
602 if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN5XXX))
604 /* The type is a five bit field for some entries and 4 for other. The four
605 bit entries can be mis-typed if the top is set */
606 int type = data.cmn.type;
619 cvmx_dprintf("0x%016llx %c%+10d %s %s 0x%016llx\n",
620 (unsigned long long)data.u128.data,
621 (data.cmn.discontinuity) ? 'D' : ' ',
622 data.cmn.timestamp << (tra_ctl.s.time_grn*3),
624 SOURCE_ARRAY[data.cmn.source],
625 (unsigned long long)data.cmn.address);
632 cvmx_dprintf("0x%016llx %c%+10d %s %s mask=0x%02x 0x%016llx\n",
633 (unsigned long long)data.u128.data,
634 (data.cmn.discontinuity) ? 'D' : ' ',
635 data.cmn.timestamp << (tra_ctl.s.time_grn*3),
637 SOURCE_ARRAY[data.store.source],
638 (unsigned int)data.store.mask,
639 (unsigned long long)data.store.address << 3);
641 case 10: /* IOBLD8 */
642 case 11: /* IOBLD16 */
643 case 12: /* IOBLD32 */
644 case 13: /* IOBLD64 */
646 cvmx_dprintf("0x%016llx %c%+10d %s %s->%s subdid=0x%x 0x%016llx\n",
647 (unsigned long long)data.u128.data,
648 (data.cmn.discontinuity) ? 'D' : ' ',
649 data.cmn.timestamp << (tra_ctl.s.time_grn*3),
651 SOURCE_ARRAY[data.iobld.source],
652 DEST_ARRAY[data.iobld.dest],
653 (unsigned int)data.iobld.subid,
654 (unsigned long long)data.iobld.address);
656 case 15: /* IOBDMA */
657 cvmx_dprintf("0x%016llx %c%+10d %s %s->%s len=0x%x 0x%016llx\n",
658 (unsigned long long)data.u128.data,
659 (data.cmn.discontinuity) ? 'D' : ' ',
660 data.cmn.timestamp << (tra_ctl.s.time_grn*3),
662 SOURCE_ARRAY[data.iob.source],
663 DEST_ARRAY[data.iob.dest],
664 (unsigned int)data.iob.mask,
665 (unsigned long long)data.iob.address << 3);
668 cvmx_dprintf("0x%016llx %c%+10d Unknown format\n",
669 (unsigned long long)data.u128.data,
670 (data.cmn.discontinuity) ? 'D' : ' ',
671 data.cmn.timestamp << (tra_ctl.s.time_grn*3));
680 type = data.cmn2.type;
684 case CVMX_TRA_FILT_DECR64:
685 case CVMX_TRA_FILT_DECR32:
686 case CVMX_TRA_FILT_DECR16:
687 case CVMX_TRA_FILT_DECR8:
688 case CVMX_TRA_FILT_INCR64:
689 case CVMX_TRA_FILT_INCR32:
690 case CVMX_TRA_FILT_INCR16:
691 case CVMX_TRA_FILT_INCR8:
692 case CVMX_TRA_FILT_CLR64:
693 case CVMX_TRA_FILT_CLR32:
694 case CVMX_TRA_FILT_CLR16:
695 case CVMX_TRA_FILT_CLR8:
696 case CVMX_TRA_FILT_SET64:
697 case CVMX_TRA_FILT_SET32:
698 case CVMX_TRA_FILT_SET16:
699 case CVMX_TRA_FILT_SET8:
700 case CVMX_TRA_FILT_LCKL2:
701 case CVMX_TRA_FILT_WBIL2:
702 case CVMX_TRA_FILT_INVL2:
703 case CVMX_TRA_FILT_STGL2I:
704 case CVMX_TRA_FILT_LTGL2I:
705 case CVMX_TRA_FILT_WBIL2I:
706 case CVMX_TRA_FILT_WBL2:
707 case CVMX_TRA_FILT_DWB:
708 case CVMX_TRA_FILT_RPL2:
709 case CVMX_TRA_FILT_PL2:
710 case CVMX_TRA_FILT_LDI:
711 case CVMX_TRA_FILT_LDT:
712 /* CN68XX has 32 cores which are distributed to use different
713 trace buffers, decode the core that has data */
714 if (OCTEON_IS_MODEL(OCTEON_CN68XX))
716 if (data.cmn2.source <= 7)
718 srcId = _cvmx_tra_unit + (data.cmn2.source * 4);
723 srcId = (data.cmn2.source);
726 srcId = (data.cmn2.source);
728 cvmx_dprintf("0x%016llx%016llx %c%+10d %s %s 0x%016llx%llx\n",
729 (unsigned long long)data.u128.datahi, (unsigned long long)data.u128.data,
730 (data.cmn2.discontinuity) ? 'D' : ' ',
731 data.cmn2.timestamp << (tra_ctl.s.time_grn*3),
734 (unsigned long long)data.cmn2.addresshi,
735 (unsigned long long)data.cmn2.addresslo);
737 case CVMX_TRA_FILT_PSL1:
738 case CVMX_TRA_FILT_LDD:
739 case CVMX_TRA_FILT_FAS64:
740 case CVMX_TRA_FILT_FAS32:
741 case CVMX_TRA_FILT_FAA64:
742 case CVMX_TRA_FILT_FAA32:
743 case CVMX_TRA_FILT_SAA64:
744 case CVMX_TRA_FILT_SAA32:
745 case CVMX_TRA_FILT_STC:
746 case CVMX_TRA_FILT_STF:
747 case CVMX_TRA_FILT_STP:
748 case CVMX_TRA_FILT_STT:
749 case CVMX_TRA_FILT_STTIL1:
750 case CVMX_TRA_FILT_STFIL1:
751 /* CN68XX has 32 cores which are distributed to use different
752 trace buffers, decode the core that has data */
753 if (OCTEON_IS_MODEL(OCTEON_CN68XX))
755 if (data.store2.source <= 7)
757 srcId = _cvmx_tra_unit + (data.store2.source * 4);
762 srcId = data.store2.source;
765 srcId = data.store2.source;
767 cvmx_dprintf("0x%016llx%016llx %c%+10d %s %s mask=0x%02x 0x%016llx%llx\n",
768 (unsigned long long)data.u128.datahi, (unsigned long long)data.u128.data,
769 (data.cmn2.discontinuity) ? 'D' : ' ',
770 data.cmn2.timestamp << (tra_ctl.s.time_grn*3),
773 (unsigned int)data.store2.mask,
774 (unsigned long long)data.store2.addresshi,
775 (unsigned long long)data.store2.addresslo);
777 case CVMX_TRA_FILT_IOBST64:
778 case CVMX_TRA_FILT_IOBST32:
779 case CVMX_TRA_FILT_IOBST16:
780 case CVMX_TRA_FILT_IOBST8:
781 case CVMX_TRA_FILT_IOBLD64:
782 case CVMX_TRA_FILT_IOBLD32:
783 case CVMX_TRA_FILT_IOBLD16:
784 case CVMX_TRA_FILT_IOBLD8:
785 /* CN68XX has 32 cores which are distributed to use different
786 trace buffers, decode the core that has data */
787 if (OCTEON_IS_MODEL(OCTEON_CN68XX))
789 if (data.iobld2.source <= 7)
791 srcId = _cvmx_tra_unit + (data.iobld2.source * 4);
796 srcId = data.iobld2.source;
799 srcId = data.iobld2.source;
801 cvmx_dprintf("0x%016llx%016llx %c%+10d %s %s->%s subdid=0x%x 0x%016llx%llx\n",
802 (unsigned long long)data.u128.datahi, (unsigned long long)data.u128.data,
803 (data.cmn2.discontinuity) ? 'D' : ' ',
804 data.cmn2.timestamp << (tra_ctl.s.time_grn*3),
807 DEST_ARRAY[data.iobld2.dest],
808 (unsigned int)data.iobld2.subid,
809 (unsigned long long)data.iobld2.addresshi,
810 (unsigned long long)data.iobld2.addresslo);
812 case CVMX_TRA_FILT_IOBDMA:
813 /* CN68XX has 32 cores which are distributed to use different
814 trace buffers, decode the core that has data */
815 if (OCTEON_IS_MODEL(OCTEON_CN68XX))
817 if (data.iob2.source <= 7)
819 srcId = _cvmx_tra_unit + (data.iob2.source * 4);
824 srcId = data.iob2.source;
827 srcId = data.iob2.source;
829 cvmx_dprintf("0x%016llx%016llx %c%+10d %s %s->%s len=0x%x 0x%016llx%llx\n",
830 (unsigned long long)data.u128.datahi, (unsigned long long)data.u128.data,
831 (data.iob2.discontinuity) ? 'D' : ' ',
832 data.iob2.timestamp << (tra_ctl.s.time_grn*3),
835 DEST_ARRAY[data.iob2.dest],
836 (unsigned int)data.iob2.mask,
837 (unsigned long long)data.iob2.addresshi << 3,
838 (unsigned long long)data.iob2.addresslo << 3);
841 cvmx_dprintf("0x%016llx%016llx %c%+10d Unknown format\n",
842 (unsigned long long)data.u128.datahi, (unsigned long long)data.u128.data,
843 (data.cmn2.discontinuity) ? 'D' : ' ',
844 data.cmn2.timestamp << (tra_ctl.s.time_grn*3));
851 * Display the entire trace buffer. It is advised that you
852 * disable the trace buffer before calling this routine
853 * otherwise it could infinitely loop displaying trace data
856 void cvmx_tra_display(void)
860 /* Collect data from each TRA unit for decoding */
861 if (CVMX_L2C_TADS > 1)
863 cvmx_trax_ctl_t tra_ctl;
864 cvmx_tra_data_t data[4];
869 for (tad = 0; tad < CVMX_L2C_TADS; tad++)
870 data[tad] = cvmx_tra_read_v2(tad);
872 for (tad = 0; tad < CVMX_L2C_TADS; tad++)
874 tra_ctl.u64 = cvmx_read_csr(CVMX_TRAX_CTL(tad));
876 if (data[tad].cmn2.valid)
878 _cvmx_tra_unit = tad;
879 cvmx_tra_decode_text(tra_ctl, data[tad]);
887 cvmx_tra_ctl_t tra_ctl;
888 cvmx_tra_data_t data;
890 tra_ctl.u64 = cvmx_read_csr(CVMX_TRA_CTL);
894 data = cvmx_tra_read();
895 if ((OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN5XXX)) && data.cmn.valid)
897 else if (data.cmn2.valid)
903 cvmx_tra_decode_text(tra_ctl, data);
908 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
909 EXPORT_SYMBOL(cvmx_tra_display);
913 * Display the entire trace buffer. It is advised that you
914 * disable the trace buffer before calling this routine
915 * otherwise it could infinitely loop displaying trace data
918 * @param tra_unit Which TRA buffer to use.
920 void cvmx_tra_display_v2(int tra_unit)
924 cvmx_trax_ctl_t tra_ctl;
925 cvmx_tra_data_t data;
928 tra_ctl.u64 = cvmx_read_csr(CVMX_TRAX_CTL(tra_unit));
932 data = cvmx_tra_read_v2(tra_unit);
935 _cvmx_tra_unit = tra_unit;
936 cvmx_tra_decode_text(tra_ctl, data);
941 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
942 EXPORT_SYMBOL(cvmx_tra_display_v2);