1210284Sjmallett/***********************license start***************
2215990Sjmallett * Copyright (c) 2003-2010  Cavium Networks (support@cavium.com). All rights
3215990Sjmallett * reserved.
4210284Sjmallett *
5210284Sjmallett *
6215990Sjmallett * Redistribution and use in source and binary forms, with or without
7215990Sjmallett * modification, are permitted provided that the following conditions are
8215990Sjmallett * met:
9210284Sjmallett *
10215990Sjmallett *   * Redistributions of source code must retain the above copyright
11215990Sjmallett *     notice, this list of conditions and the following disclaimer.
12210284Sjmallett *
13215990Sjmallett *   * Redistributions in binary form must reproduce the above
14215990Sjmallett *     copyright notice, this list of conditions and the following
15215990Sjmallett *     disclaimer in the documentation and/or other materials provided
16215990Sjmallett *     with the distribution.
17215990Sjmallett
18215990Sjmallett *   * Neither the name of Cavium Networks nor the names of
19215990Sjmallett *     its contributors may be used to endorse or promote products
20215990Sjmallett *     derived from this software without specific prior written
21215990Sjmallett *     permission.
22215990Sjmallett
23215990Sjmallett * This Software, including technical data, may be subject to U.S. export  control
24215990Sjmallett * laws, including the U.S. Export Administration Act and its  associated
25215990Sjmallett * regulations, and may be subject to export or import  regulations in other
26215990Sjmallett * countries.
27215990Sjmallett
28215990Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29215990Sjmallett * AND WITH ALL FAULTS AND CAVIUM  NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
30215990Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31215990Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32215990Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33215990Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34215990Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35215990Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36215990Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
37215990Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38210284Sjmallett ***********************license end**************************************/
39210284Sjmallett
40210284Sjmallett
41210284Sjmallett
42210284Sjmallett
43210284Sjmallett
44215990Sjmallett
45210284Sjmallett/**
46210284Sjmallett * @file
47210284Sjmallett *
48210284Sjmallett * Interface to the Trace buffer hardware.
49210284Sjmallett *
50210284Sjmallett * <hr>$Revision: 30644 $<hr>
51210284Sjmallett */
52215990Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
53215990Sjmallett#include <linux/module.h>
54215990Sjmallett#include <asm/octeon/cvmx.h>
55215990Sjmallett#include <asm/octeon/cvmx-tra.h>
56215990Sjmallett#else
57210284Sjmallett#include "cvmx.h"
58210284Sjmallett#include "cvmx-tra.h"
59215990Sjmallett#endif
60210284Sjmallett
61210284Sjmallettstatic const char *TYPE_ARRAY[] = {
62210284Sjmallett    "DWB - Don't write back",
63210284Sjmallett    "PL2 - Prefetch into L2",
64210284Sjmallett    "PSL1 - Dcache fill, skip L2",
65210284Sjmallett    "LDD - Dcache fill",
66210284Sjmallett    "LDI - Icache/IO fill",
67210284Sjmallett    "LDT - Icache/IO fill, skip L2",
68210284Sjmallett    "STF - Store full",
69210284Sjmallett    "STC - Store conditional",
70210284Sjmallett    "STP - Store partial",
71210284Sjmallett    "STT - Store full, skip L2",
72210284Sjmallett    "IOBLD8 - IOB 8bit load",
73210284Sjmallett    "IOBLD16 - IOB 16bit load",
74210284Sjmallett    "IOBLD32 - IOB 32bit load",
75210284Sjmallett    "IOBLD64 - IOB 64bit load",
76210284Sjmallett    "IOBST - IOB store",
77210284Sjmallett    "IOBDMA - Async IOB",
78210284Sjmallett    "SAA - Store atomic add",
79210284Sjmallett    "RSVD17",
80210284Sjmallett    "RSVD18",
81210284Sjmallett    "RSVD19",
82210284Sjmallett    "RSVD20",
83210284Sjmallett    "RSVD21",
84210284Sjmallett    "RSVD22",
85210284Sjmallett    "RSVD23",
86210284Sjmallett    "RSVD24",
87210284Sjmallett    "RSVD25",
88210284Sjmallett    "RSVD26",
89210284Sjmallett    "RSVD27",
90210284Sjmallett    "RSVD28",
91210284Sjmallett    "RSVD29",
92210284Sjmallett    "RSVD30",
93210284Sjmallett    "RSVD31"
94210284Sjmallett};
95210284Sjmallett
96215990Sjmallettstatic const char *TYPE_ARRAY2[] = {
97215990Sjmallett    "NOP - None",
98215990Sjmallett    "LDT - Icache/IO fill, skip L2",
99215990Sjmallett    "LDI - Icache/IO fill",
100215990Sjmallett    "PL2 - Prefetch into L2",
101215990Sjmallett    "RPL2 - Mark for replacement in L2",
102215990Sjmallett    "DWB - Don't write back",
103215990Sjmallett    "RSVD6",
104215990Sjmallett    "RSVD7",
105215990Sjmallett    "LDD - Dcache fill",
106215990Sjmallett    "PSL1 - Prefetch L1, skip L2",
107215990Sjmallett    "RSVD10",
108215990Sjmallett    "RSVD11",
109215990Sjmallett    "RSVD12",
110215990Sjmallett    "RSVD13",
111215990Sjmallett    "RSVD14",
112215990Sjmallett    "IOBDMA - Async IOB",
113215990Sjmallett    "STF - Store full",
114215990Sjmallett    "STT - Store full, skip L2",
115215990Sjmallett    "STP - Store partial",
116215990Sjmallett    "STC - Store conditional",
117215990Sjmallett    "STFIL1 - Store full, invalidate L1",
118215990Sjmallett    "STTIL1 - Store full, skip L2, invalidate L1",
119215990Sjmallett    "FAS32 - Atomic 32bit swap",
120215990Sjmallett    "FAS64 - Atomic 64bit swap",
121215990Sjmallett    "WBIL2i - Writeback, invalidate, by index/way",
122215990Sjmallett    "LTGL2i - Read tag@index/way",
123215990Sjmallett    "STGL2i - Write tag@index/way",
124215990Sjmallett    "RSVD27",
125215990Sjmallett    "INVL2 - Invalidate, by address",
126215990Sjmallett    "WBIL2 - Writeback, invalidate, by address",
127215990Sjmallett    "WBL2 - Writeback, by address",
128215990Sjmallett    "LCKL2 - Allocate, lock, by address",
129215990Sjmallett    "IOBLD8 - IOB 8bit load",
130215990Sjmallett    "IOBLD16 - IOB 16bit load",
131215990Sjmallett    "IOBLD32 - IOB 32bit load",
132215990Sjmallett    "IOBLD64 - IOB 64bit load",
133215990Sjmallett    "IOBST8 - IOB 8bit store",
134215990Sjmallett    "IOBST16 - IOB 16bit store",
135215990Sjmallett    "IOBST32 - IOB 32bit store",
136215990Sjmallett    "IOBST64 - IOB 64bit store",
137215990Sjmallett    "SET8 - 8bit Atomic swap with 1's",
138215990Sjmallett    "SET16 - 16bit Atomic swap with 1's",
139215990Sjmallett    "SET32 - 32bit Atomic swap with 1's",
140215990Sjmallett    "SET64 - 64bit Atomic swap with 1's",
141215990Sjmallett    "CLR8 - 8bit Atomic swap with 0's",
142215990Sjmallett    "CLR16 - 16bit Atomic swap with 0's",
143215990Sjmallett    "CLR32 - 32bit Atomic swap with 0's",
144215990Sjmallett    "CLR64 - 64bit Atomic swap with 0's",
145215990Sjmallett    "INCR8 - 8bit Atomic fetch & add by 1",
146215990Sjmallett    "INCR16 - 16bit Atomic fetch & add by 1",
147215990Sjmallett    "INCR32 - 32bit Atomic fetch & add by 1",
148215990Sjmallett    "INCR64 - 64bit Atomic fetch & add by 1",
149215990Sjmallett    "DECR8 - 8bit Atomic fetch & add by -1",
150215990Sjmallett    "DECR16 - 16bit Atomic fetch & add by -1",
151215990Sjmallett    "DECR32 - 32bit Atomic fetch & add by -1",
152215990Sjmallett    "DECR64 - 64bit Atomic fetch & add by -1",
153215990Sjmallett    "RSVD56",
154215990Sjmallett    "RSVD57",
155215990Sjmallett    "FAA32 - 32bit Atomic fetch and add",
156215990Sjmallett    "FAA64 - 64bit Atomic fetch and add",
157215990Sjmallett    "RSVD60",
158215990Sjmallett    "RSVD61",
159215990Sjmallett    "SAA32 - 32bit Atomic add",
160215990Sjmallett    "SAA64 - 64bit Atomic add"
161215990Sjmallett};
162215990Sjmallett
163210284Sjmallettstatic const char *SOURCE_ARRAY[] = {
164210284Sjmallett    "PP0",
165210284Sjmallett    "PP1",
166210284Sjmallett    "PP2",
167210284Sjmallett    "PP3",
168210284Sjmallett    "PP4",
169210284Sjmallett    "PP5",
170210284Sjmallett    "PP6",
171210284Sjmallett    "PP7",
172210284Sjmallett    "PP8",
173210284Sjmallett    "PP9",
174210284Sjmallett    "PP10",
175210284Sjmallett    "PP11",
176210284Sjmallett    "PP12",
177210284Sjmallett    "PP13",
178210284Sjmallett    "PP14",
179210284Sjmallett    "PP15",
180210284Sjmallett    "PIP/IPD",
181210284Sjmallett    "PKO-R",
182210284Sjmallett    "FPA/TIM/DFA/PCI/ZIP/POW/PKO-W",
183210284Sjmallett    "DWB",
184210284Sjmallett    "RSVD20",
185210284Sjmallett    "RSVD21",
186210284Sjmallett    "RSVD22",
187210284Sjmallett    "RSVD23",
188210284Sjmallett    "RSVD24",
189210284Sjmallett    "RSVD25",
190210284Sjmallett    "RSVD26",
191210284Sjmallett    "RSVD27",
192210284Sjmallett    "RSVD28",
193210284Sjmallett    "RSVD29",
194210284Sjmallett    "RSVD30",
195210284Sjmallett    "RSVD31"
196210284Sjmallett};
197210284Sjmallett
198210284Sjmallettstatic const char *DEST_ARRAY[] = {
199210284Sjmallett    "CIU/GPIO",
200210284Sjmallett    "RSVD1",
201210284Sjmallett    "RSVD2",
202215990Sjmallett    "PCI/PCIe/SLI",
203210284Sjmallett    "KEY",
204210284Sjmallett    "FPA",
205210284Sjmallett    "DFA",
206210284Sjmallett    "ZIP",
207210284Sjmallett    "RNG",
208210284Sjmallett    "IPD",
209210284Sjmallett    "PKO",
210210284Sjmallett    "RSVD11",
211210284Sjmallett    "POW",
212215990Sjmallett    "USB0",
213215990Sjmallett    "RAD",
214210284Sjmallett    "RSVD15",
215210284Sjmallett    "RSVD16",
216210284Sjmallett    "RSVD17",
217210284Sjmallett    "RSVD18",
218210284Sjmallett    "RSVD19",
219210284Sjmallett    "RSVD20",
220210284Sjmallett    "RSVD21",
221210284Sjmallett    "RSVD22",
222210284Sjmallett    "RSVD23",
223210284Sjmallett    "RSVD24",
224210284Sjmallett    "RSVD25",
225210284Sjmallett    "RSVD26",
226215990Sjmallett    "DPI",
227210284Sjmallett    "RSVD28",
228210284Sjmallett    "RSVD29",
229215990Sjmallett    "FAU",
230210284Sjmallett    "RSVD31"
231210284Sjmallett};
232210284Sjmallett
233215990Sjmallett#define CVMX_TRA_SOURCE_MASK       (OCTEON_IS_MODEL(OCTEON_CN63XX) ? 0xf00ff : 0xfffff)
234215990Sjmallett#define CVMX_TRA_DESTINATION_MASK  0xfffffffful
235215990Sjmallett
236210284Sjmallett/**
237215990Sjmallett * @INTERNAL
238215990Sjmallett * Setup the trace buffer filter command mask. The bit position of filter commands
239215990Sjmallett * are different for each Octeon model.
240215990Sjmallett *
241215990Sjmallett * @param filter    Which event to log
242215990Sjmallett * @return          Bitmask of filter command based on the event.
243215990Sjmallett */
244215990Sjmallettstatic uint64_t __cvmx_tra_set_filter_cmd_mask(cvmx_tra_filt_t filter)
245215990Sjmallett{
246215990Sjmallett    cvmx_tra_filt_cmd_t filter_command;
247215990Sjmallett
248215990Sjmallett    if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN5XXX))
249215990Sjmallett    {
250215990Sjmallett        /* Bit positions of filter commands are different, map it accordingly */
251215990Sjmallett        uint64_t cmd = 0;
252215990Sjmallett        if ((filter & CVMX_TRA_FILT_ALL) == -1ull)
253215990Sjmallett        {
254215990Sjmallett            if (OCTEON_IS_MODEL(OCTEON_CN5XXX))
255215990Sjmallett                cmd = 0x1ffff;
256215990Sjmallett            else
257215990Sjmallett                cmd = 0xffff;
258215990Sjmallett        }
259215990Sjmallett        if (filter & CVMX_TRA_FILT_DWB)
260215990Sjmallett            cmd |= 1ull<<0;
261215990Sjmallett        if (filter & CVMX_TRA_FILT_PL2)
262215990Sjmallett            cmd |= 1ull<<1;
263215990Sjmallett        if (filter & CVMX_TRA_FILT_PSL1)
264215990Sjmallett            cmd |= 1ull<<2;
265215990Sjmallett        if (filter & CVMX_TRA_FILT_LDD)
266215990Sjmallett            cmd |= 1ull<<3;
267215990Sjmallett        if (filter & CVMX_TRA_FILT_LDI)
268215990Sjmallett            cmd |= 1ull<<4;
269215990Sjmallett        if (filter & CVMX_TRA_FILT_LDT)
270215990Sjmallett            cmd |= 1ull<<5;
271215990Sjmallett        if (filter & CVMX_TRA_FILT_STF)
272215990Sjmallett            cmd |= 1ull<<6;
273215990Sjmallett        if (filter & CVMX_TRA_FILT_STC)
274215990Sjmallett            cmd |= 1ull<<7;
275215990Sjmallett        if (filter & CVMX_TRA_FILT_STP)
276215990Sjmallett            cmd |= 1ull<<8;
277215990Sjmallett        if (filter & CVMX_TRA_FILT_STT)
278215990Sjmallett            cmd |= 1ull<<9;
279215990Sjmallett        if (filter & CVMX_TRA_FILT_IOBLD8)
280215990Sjmallett            cmd |= 1ull<<10;
281215990Sjmallett        if (filter & CVMX_TRA_FILT_IOBLD16)
282215990Sjmallett            cmd |= 1ull<<11;
283215990Sjmallett        if (filter & CVMX_TRA_FILT_IOBLD32)
284215990Sjmallett            cmd |= 1ull<<12;
285215990Sjmallett        if (filter & CVMX_TRA_FILT_IOBLD64)
286215990Sjmallett            cmd |= 1ull<<13;
287215990Sjmallett        if (filter & CVMX_TRA_FILT_IOBST)
288215990Sjmallett            cmd |= 1ull<<14;
289215990Sjmallett        if (filter & CVMX_TRA_FILT_IOBDMA)
290215990Sjmallett            cmd |= 1ull<<15;
291215990Sjmallett        if (OCTEON_IS_MODEL(OCTEON_CN5XXX) && (filter & CVMX_TRA_FILT_SAA))
292215990Sjmallett            cmd |= 1ull<<16;
293215990Sjmallett
294215990Sjmallett        filter_command.u64 = cmd;
295215990Sjmallett    }
296215990Sjmallett    else
297215990Sjmallett    {
298215990Sjmallett        if ((filter & CVMX_TRA_FILT_ALL) == -1ull)
299215990Sjmallett            filter_command.u64 = CVMX_TRA_FILT_ALL;
300215990Sjmallett        else
301215990Sjmallett            filter_command.u64 = filter;
302215990Sjmallett
303215990Sjmallett        filter_command.cn63xx.reserved_60_61 = 0;
304215990Sjmallett        filter_command.cn63xx.reserved_56_57 = 0;
305215990Sjmallett        filter_command.cn63xx.reserved_10_14 = 0;
306215990Sjmallett        filter_command.cn63xx.reserved_6_7 = 0;
307215990Sjmallett    }
308215990Sjmallett    return filter_command.u64;
309215990Sjmallett}
310215990Sjmallett
311215990Sjmallett
312215990Sjmallett/**
313210284Sjmallett * Setup the TRA buffer for use
314210284Sjmallett *
315210284Sjmallett * @param control TRA control setup
316210284Sjmallett * @param filter  Which events to log
317210284Sjmallett * @param source_filter
318210284Sjmallett *                Source match
319210284Sjmallett * @param dest_filter
320210284Sjmallett *                Destination match
321210284Sjmallett * @param address Address compare
322210284Sjmallett * @param address_mask
323210284Sjmallett *                Address mask
324210284Sjmallett */
325215990Sjmallettvoid cvmx_tra_setup(cvmx_tra_ctl_t control, cvmx_tra_filt_t filter,
326215990Sjmallett                    cvmx_tra_sid_t source_filter, cvmx_tra_did_t dest_filter,
327210284Sjmallett                    uint64_t address, uint64_t address_mask)
328210284Sjmallett{
329215990Sjmallett    cvmx_tra_filt_cmd_t filt_cmd;
330215990Sjmallett    cvmx_tra_filt_sid_t filt_sid;
331215990Sjmallett    cvmx_tra_filt_did_t filt_did;
332215990Sjmallett
333215990Sjmallett    filt_cmd.u64 = __cvmx_tra_set_filter_cmd_mask(filter);
334215990Sjmallett    filt_sid.u64 = source_filter & CVMX_TRA_SOURCE_MASK;
335215990Sjmallett    filt_did.u64 = dest_filter & CVMX_TRA_DESTINATION_MASK;
336215990Sjmallett
337210284Sjmallett    cvmx_write_csr(CVMX_TRA_CTL,            control.u64);
338215990Sjmallett    cvmx_write_csr(CVMX_TRA_FILT_CMD,       filt_cmd.u64);
339215990Sjmallett    cvmx_write_csr(CVMX_TRA_FILT_SID,       filt_sid.u64);
340215990Sjmallett    cvmx_write_csr(CVMX_TRA_FILT_DID,       filt_did.u64);
341210284Sjmallett    cvmx_write_csr(CVMX_TRA_FILT_ADR_ADR,   address);
342210284Sjmallett    cvmx_write_csr(CVMX_TRA_FILT_ADR_MSK,   address_mask);
343210284Sjmallett}
344215990Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
345215990SjmallettEXPORT_SYMBOL(cvmx_tra_setup);
346215990Sjmallett#endif
347210284Sjmallett
348210284Sjmallett
349210284Sjmallett/**
350210284Sjmallett * Setup a TRA trigger. How the triggers are used should be
351210284Sjmallett * setup using cvmx_tra_setup.
352210284Sjmallett *
353210284Sjmallett * @param trigger Trigger to setup (0 or 1)
354210284Sjmallett * @param filter  Which types of events to trigger on
355210284Sjmallett * @param source_filter
356210284Sjmallett *                Source trigger match
357210284Sjmallett * @param dest_filter
358210284Sjmallett *                Destination trigger match
359210284Sjmallett * @param address Trigger address compare
360210284Sjmallett * @param address_mask
361210284Sjmallett *                Trigger address mask
362210284Sjmallett */
363215990Sjmallettvoid cvmx_tra_trig_setup(uint64_t trigger, cvmx_tra_filt_t filter,
364215990Sjmallett                         cvmx_tra_sid_t source_filter, cvmx_tra_did_t dest_filter,
365210284Sjmallett                         uint64_t address, uint64_t address_mask)
366210284Sjmallett{
367215990Sjmallett    cvmx_tra_filt_cmd_t tra_filt_cmd;
368215990Sjmallett    cvmx_tra_filt_sid_t tra_filt_sid;
369215990Sjmallett    cvmx_tra_filt_did_t tra_filt_did;
370215990Sjmallett
371215990Sjmallett    tra_filt_cmd.u64 = __cvmx_tra_set_filter_cmd_mask(filter);
372215990Sjmallett    tra_filt_sid.u64 = source_filter & CVMX_TRA_SOURCE_MASK;
373215990Sjmallett    tra_filt_did.u64 = dest_filter & CVMX_TRA_DESTINATION_MASK;
374215990Sjmallett
375215990Sjmallett    cvmx_write_csr(CVMX_TRA_TRIG0_CMD + trigger * 64,       tra_filt_cmd.u64);
376215990Sjmallett    cvmx_write_csr(CVMX_TRA_TRIG0_SID + trigger * 64,       tra_filt_sid.u64);
377215990Sjmallett    cvmx_write_csr(CVMX_TRA_TRIG0_DID + trigger * 64,       tra_filt_did.u64);
378210284Sjmallett    cvmx_write_csr(CVMX_TRA_TRIG0_ADR_ADR + trigger * 64,   address);
379210284Sjmallett    cvmx_write_csr(CVMX_TRA_TRIG0_ADR_MSK + trigger * 64,   address_mask);
380210284Sjmallett}
381215990Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
382215990SjmallettEXPORT_SYMBOL(cvmx_tra_trig_setup);
383215990Sjmallett#endif
384210284Sjmallett
385210284Sjmallett
386210284Sjmallett/**
387210284Sjmallett * Read an entry from the TRA buffer
388210284Sjmallett *
389210284Sjmallett * @return Value return. High bit will be zero if there wasn't any data
390210284Sjmallett */
391210284Sjmallettcvmx_tra_data_t cvmx_tra_read(void)
392210284Sjmallett{
393215990Sjmallett    uint64_t address = CVMX_TRA_READ_DAT;
394210284Sjmallett    cvmx_tra_data_t result;
395215990Sjmallett
396215990Sjmallett    /* The trace buffer format is wider than 64-bits in Octeon2 model,
397215990Sjmallett       read the register again to get the second part of the data. */
398215990Sjmallett    if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) && !OCTEON_IS_MODEL(OCTEON_CN5XXX))
399215990Sjmallett    {
400215990Sjmallett        /* These reads need to be as close as possible to each other */
401215990Sjmallett        result.u128.data = cvmx_read_csr(address);
402215990Sjmallett        result.u128.datahi = cvmx_read_csr(address);
403215990Sjmallett    }
404215990Sjmallett    else
405215990Sjmallett    {
406215990Sjmallett        result.u128.data = cvmx_read_csr(address);
407215990Sjmallett        result.u128.datahi = 0;
408215990Sjmallett    }
409215990Sjmallett
410210284Sjmallett    return result;
411210284Sjmallett}
412210284Sjmallett
413210284Sjmallett/**
414210284Sjmallett * Decode a TRA entry into human readable output
415210284Sjmallett *
416210284Sjmallett * @param tra_ctl Trace control setup
417210284Sjmallett * @param data    Data to decode
418210284Sjmallett */
419210284Sjmallettvoid cvmx_tra_decode_text(cvmx_tra_ctl_t tra_ctl, cvmx_tra_data_t data)
420210284Sjmallett{
421215990Sjmallett    if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN5XXX))
422210284Sjmallett    {
423215990Sjmallett        /* The type is a five bit field for some entries and 4 for other. The four
424215990Sjmallett           bit entries can be mis-typed if the top is set */
425215990Sjmallett        int type = data.cmn.type;
426215990Sjmallett
427215990Sjmallett        if (type >= 0x1a)
428215990Sjmallett            type &= 0xf;
429215990Sjmallett
430215990Sjmallett        switch (type)
431215990Sjmallett        {
432215990Sjmallett            case 0:  /* DWB */
433215990Sjmallett            case 1:  /* PL2 */
434215990Sjmallett            case 2:  /* PSL1 */
435215990Sjmallett            case 3:  /* LDD */
436215990Sjmallett            case 4:  /* LDI */
437215990Sjmallett            case 5:  /* LDT */
438215990Sjmallett                cvmx_dprintf("0x%016llx %c%+10d %s %s 0x%016llx\n",
439215990Sjmallett                    (unsigned long long)data.u128.data,
440215990Sjmallett                    (data.cmn.discontinuity) ? 'D' : ' ',
441215990Sjmallett                    data.cmn.timestamp << (tra_ctl.s.time_grn*3),
442215990Sjmallett                    TYPE_ARRAY[type],
443215990Sjmallett                    SOURCE_ARRAY[data.cmn.source],
444215990Sjmallett                    (unsigned long long)data.cmn.address);
445215990Sjmallett                break;
446215990Sjmallett            case 6:  /* STF */
447215990Sjmallett            case 7:  /* STC */
448215990Sjmallett            case 8:  /* STP */
449215990Sjmallett            case 9:  /* STT */
450215990Sjmallett            case 16: /* SAA */
451215990Sjmallett                cvmx_dprintf("0x%016llx %c%+10d %s %s mask=0x%02x 0x%016llx\n",
452215990Sjmallett                   (unsigned long long)data.u128.data,
453210284Sjmallett                   (data.cmn.discontinuity) ? 'D' : ' ',
454210284Sjmallett                   data.cmn.timestamp << (tra_ctl.s.time_grn*3),
455210284Sjmallett                   TYPE_ARRAY[type],
456210284Sjmallett                   SOURCE_ARRAY[data.store.source],
457210284Sjmallett                   (unsigned int)data.store.mask,
458210284Sjmallett                   (unsigned long long)data.store.address << 3);
459215990Sjmallett                break;
460215990Sjmallett            case 10:  /* IOBLD8 */
461215990Sjmallett            case 11:  /* IOBLD16 */
462215990Sjmallett            case 12:  /* IOBLD32 */
463215990Sjmallett            case 13:  /* IOBLD64 */
464215990Sjmallett            case 14:  /* IOBST */
465215990Sjmallett                cvmx_dprintf("0x%016llx %c%+10d %s %s->%s subdid=0x%x 0x%016llx\n",
466215990Sjmallett                   (unsigned long long)data.u128.data,
467210284Sjmallett                   (data.cmn.discontinuity) ? 'D' : ' ',
468210284Sjmallett                   data.cmn.timestamp << (tra_ctl.s.time_grn*3),
469210284Sjmallett                   TYPE_ARRAY[type],
470210284Sjmallett                   SOURCE_ARRAY[data.iobld.source],
471210284Sjmallett                   DEST_ARRAY[data.iobld.dest],
472210284Sjmallett                   (unsigned int)data.iobld.subid,
473210284Sjmallett                   (unsigned long long)data.iobld.address);
474215990Sjmallett                break;
475215990Sjmallett            case 15:  /* IOBDMA */
476215990Sjmallett                cvmx_dprintf("0x%016llx %c%+10d %s %s->%s len=0x%x 0x%016llx\n",
477215990Sjmallett                   (unsigned long long)data.u128.data,
478210284Sjmallett                   (data.cmn.discontinuity) ? 'D' : ' ',
479210284Sjmallett                   data.cmn.timestamp << (tra_ctl.s.time_grn*3),
480210284Sjmallett                   TYPE_ARRAY[type],
481210284Sjmallett                   SOURCE_ARRAY[data.iob.source],
482210284Sjmallett                   DEST_ARRAY[data.iob.dest],
483210284Sjmallett                   (unsigned int)data.iob.mask,
484210284Sjmallett                   (unsigned long long)data.iob.address << 3);
485215990Sjmallett                break;
486215990Sjmallett            default:
487215990Sjmallett                cvmx_dprintf("0x%016llx %c%+10d Unknown format\n",
488215990Sjmallett                   (unsigned long long)data.u128.data,
489210284Sjmallett                   (data.cmn.discontinuity) ? 'D' : ' ',
490210284Sjmallett                   data.cmn.timestamp << (tra_ctl.s.time_grn*3));
491215990Sjmallett                break;
492215990Sjmallett        }
493210284Sjmallett    }
494215990Sjmallett    else
495215990Sjmallett    {
496215990Sjmallett        int type;
497215990Sjmallett
498215990Sjmallett        type = data.cmn2.type;
499215990Sjmallett
500215990Sjmallett        switch (1ull<<type)
501215990Sjmallett        {
502215990Sjmallett            case CVMX_TRA_FILT_DECR64:
503215990Sjmallett            case CVMX_TRA_FILT_DECR32:
504215990Sjmallett            case CVMX_TRA_FILT_DECR16:
505215990Sjmallett            case CVMX_TRA_FILT_DECR8:
506215990Sjmallett            case CVMX_TRA_FILT_INCR64:
507215990Sjmallett            case CVMX_TRA_FILT_INCR32:
508215990Sjmallett            case CVMX_TRA_FILT_INCR16:
509215990Sjmallett            case CVMX_TRA_FILT_INCR8:
510215990Sjmallett            case CVMX_TRA_FILT_CLR64:
511215990Sjmallett            case CVMX_TRA_FILT_CLR32:
512215990Sjmallett            case CVMX_TRA_FILT_CLR16:
513215990Sjmallett            case CVMX_TRA_FILT_CLR8:
514215990Sjmallett            case CVMX_TRA_FILT_SET64:
515215990Sjmallett            case CVMX_TRA_FILT_SET32:
516215990Sjmallett            case CVMX_TRA_FILT_SET16:
517215990Sjmallett            case CVMX_TRA_FILT_SET8:
518215990Sjmallett            case CVMX_TRA_FILT_WBL2:
519215990Sjmallett            case CVMX_TRA_FILT_DWB:
520215990Sjmallett            case CVMX_TRA_FILT_RPL2:
521215990Sjmallett            case CVMX_TRA_FILT_PL2:
522215990Sjmallett            case CVMX_TRA_FILT_LDI:
523215990Sjmallett            case CVMX_TRA_FILT_LDT:
524215990Sjmallett                cvmx_dprintf("0x%016llx%016llx %c%+10d %s %s 0x%016llx%llx\n",
525215990Sjmallett                   (unsigned long long)data.u128.datahi, (unsigned long long)data.u128.data,
526215990Sjmallett                   (data.cmn2.discontinuity) ? 'D' : ' ',
527215990Sjmallett                   data.cmn2.timestamp << (tra_ctl.s.time_grn*3),
528215990Sjmallett                   TYPE_ARRAY2[type],
529215990Sjmallett                   SOURCE_ARRAY[data.cmn2.source],
530215990Sjmallett                   (unsigned long long)data.cmn2.addresshi,
531215990Sjmallett                   (unsigned long long)data.cmn2.addresslo);
532215990Sjmallett                break;
533215990Sjmallett            case CVMX_TRA_FILT_PSL1:
534215990Sjmallett            case CVMX_TRA_FILT_LDD:
535215990Sjmallett            case CVMX_TRA_FILT_FAS64:
536215990Sjmallett            case CVMX_TRA_FILT_FAS32:
537215990Sjmallett            case CVMX_TRA_FILT_FAA64:
538215990Sjmallett            case CVMX_TRA_FILT_FAA32:
539215990Sjmallett            case CVMX_TRA_FILT_SAA64:
540215990Sjmallett            case CVMX_TRA_FILT_SAA32:
541215990Sjmallett            case CVMX_TRA_FILT_STC:
542215990Sjmallett            case CVMX_TRA_FILT_STF:
543215990Sjmallett            case CVMX_TRA_FILT_STP:
544215990Sjmallett            case CVMX_TRA_FILT_STT:
545215990Sjmallett                cvmx_dprintf("0x%016llx%016llx %c%+10d %s %s mask=0x%02x 0x%016llx%llx\n",
546215990Sjmallett                   (unsigned long long)data.u128.datahi, (unsigned long long)data.u128.data,
547215990Sjmallett                   (data.cmn2.discontinuity) ? 'D' : ' ',
548215990Sjmallett                   data.cmn2.timestamp << (tra_ctl.s.time_grn*3),
549215990Sjmallett                   TYPE_ARRAY2[type],
550215990Sjmallett                   SOURCE_ARRAY[data.store2.source],
551215990Sjmallett                   (unsigned int)data.store2.mask,
552215990Sjmallett                   (unsigned long long)data.store2.addresshi,
553215990Sjmallett                   (unsigned long long)data.store2.addresslo);
554215990Sjmallett                break;
555215990Sjmallett            case CVMX_TRA_FILT_IOBST64:
556215990Sjmallett            case CVMX_TRA_FILT_IOBST32:
557215990Sjmallett            case CVMX_TRA_FILT_IOBST16:
558215990Sjmallett            case CVMX_TRA_FILT_IOBST8:
559215990Sjmallett            case CVMX_TRA_FILT_IOBLD64:
560215990Sjmallett            case CVMX_TRA_FILT_IOBLD32:
561215990Sjmallett            case CVMX_TRA_FILT_IOBLD16:
562215990Sjmallett            case CVMX_TRA_FILT_IOBLD8:
563215990Sjmallett                cvmx_dprintf("0x%016llx%016llx %c%+10d %s %s->%s subdid=0x%x 0x%016llx%llx\n",
564215990Sjmallett                   (unsigned long long)data.u128.datahi, (unsigned long long)data.u128.data,
565215990Sjmallett                   (data.cmn2.discontinuity) ? 'D' : ' ',
566215990Sjmallett                   data.cmn2.timestamp << (tra_ctl.s.time_grn*3),
567215990Sjmallett                   TYPE_ARRAY2[type],
568215990Sjmallett                   SOURCE_ARRAY[data.iobld2.source],
569215990Sjmallett                   DEST_ARRAY[data.iobld2.dest],
570215990Sjmallett                   (unsigned int)data.iobld2.subid,
571215990Sjmallett                   (unsigned long long)data.iobld2.addresshi,
572215990Sjmallett                   (unsigned long long)data.iobld2.addresslo);
573215990Sjmallett                break;
574215990Sjmallett            case CVMX_TRA_FILT_IOBDMA:
575215990Sjmallett                cvmx_dprintf("0x%016llx%016llx %c%+10d %s %s->%s len=0x%x 0x%016llx%llx\n",
576215990Sjmallett                   (unsigned long long)data.u128.datahi, (unsigned long long)data.u128.data,
577215990Sjmallett                   (data.iob2.discontinuity) ? 'D' : ' ',
578215990Sjmallett                   data.iob2.timestamp << (tra_ctl.s.time_grn*3),
579215990Sjmallett                   TYPE_ARRAY2[type],
580215990Sjmallett                   SOURCE_ARRAY[data.iob2.source],
581215990Sjmallett                   DEST_ARRAY[data.iob2.dest],
582215990Sjmallett                   (unsigned int)data.iob2.mask,
583215990Sjmallett                   (unsigned long long)data.iob2.addresshi << 3,
584215990Sjmallett                   (unsigned long long)data.iob2.addresslo << 3);
585215990Sjmallett                break;
586215990Sjmallett            default:
587215990Sjmallett                cvmx_dprintf("0x%016llx%016llx %c%+10d Unknown format\n",
588215990Sjmallett                   (unsigned long long)data.u128.datahi, (unsigned long long)data.u128.data,
589215990Sjmallett                   (data.cmn2.discontinuity) ? 'D' : ' ',
590215990Sjmallett                   data.cmn2.timestamp << (tra_ctl.s.time_grn*3));
591215990Sjmallett                break;
592215990Sjmallett        }
593215990Sjmallett    }
594210284Sjmallett}
595210284Sjmallett
596210284Sjmallett/**
597210284Sjmallett * Display the entire trace buffer. It is advised that you
598210284Sjmallett * disable the trace buffer before calling this routine
599210284Sjmallett * otherwise it could infinitely loop displaying trace data
600210284Sjmallett * that it created.
601210284Sjmallett */
602210284Sjmallettvoid cvmx_tra_display(void)
603210284Sjmallett{
604210284Sjmallett    cvmx_tra_ctl_t tra_ctl;
605210284Sjmallett    cvmx_tra_data_t data;
606215990Sjmallett    int valid = 0;
607210284Sjmallett
608210284Sjmallett    tra_ctl.u64 = cvmx_read_csr(CVMX_TRA_CTL);
609210284Sjmallett
610210284Sjmallett    do
611210284Sjmallett    {
612210284Sjmallett        data = cvmx_tra_read();
613215990Sjmallett        if ((OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN5XXX)) && data.cmn.valid)
614215990Sjmallett            valid = 1;
615215990Sjmallett        else if (data.cmn2.valid)
616215990Sjmallett            valid = 1;
617215990Sjmallett        else
618215990Sjmallett            valid = 0;
619215990Sjmallett
620215990Sjmallett        if (valid)
621210284Sjmallett            cvmx_tra_decode_text(tra_ctl, data);
622215990Sjmallett
623215990Sjmallett    } while (valid);
624210284Sjmallett}
625215990Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
626215990SjmallettEXPORT_SYMBOL(cvmx_tra_display);
627215990Sjmallett#endif
628