1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * Trace commands File: cfe_trace.c
6 * A minimal interface for running the SB-1250 trace buffer under CFE
8 *********************************************************************
10 * Copyright 2000,2001,2002,2003
11 * Broadcom Corporation. All rights reserved.
13 * This software is furnished under license and may be used and
14 * copied only in accordance with the following terms and
15 * conditions. Subject to these conditions, you may download,
16 * copy, install, use, modify and distribute modified or unmodified
17 * copies of this software in source and/or binary form. No title
18 * or ownership is transferred hereby.
20 * 1) Any source code used, modified or distributed must reproduce
21 * and retain this copyright notice and list of conditions
22 * as they appear in the source file.
24 * 2) No right is granted to use any trade name, trademark, or
25 * logo of Broadcom Corporation. The "Broadcom Corporation"
26 * name may not be used to endorse or promote products derived
27 * from this software without the prior written permission of
28 * Broadcom Corporation.
30 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
31 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
32 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
33 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
34 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
35 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
36 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
38 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
39 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
40 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
41 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
42 * THE POSSIBILITY OF SUCH DAMAGE.
43 ********************************************************************* */
47 #include "sb1250_regs.h"
48 #include "sb1250_scd.h"
50 #include "lib_types.h"
51 #include "lib_string.h"
52 #include "lib_malloc.h"
53 #include "lib_printf.h"
55 #include "ui_command.h"
57 int ui_init_tracecmds(void);
58 static int ui_cmd_tracestart(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
59 static int ui_cmd_tracestop(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
60 static int ui_cmd_tracefreeze(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
61 static int ui_cmd_traceread(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
64 int ui_init_tracecmds(void)
67 cmd_addcmd("trace start",
70 "Start trace buffer data collection",
71 "trace start [n [agent]]\n\n"
72 "Start tracing ZBbus transactions, using the n-th canned\n"
73 "trigger/filter condition\n"
74 " n = 0: <agent>-mastered transactions\n"
75 " n = 1: CPU0 accesses to LDT dual-hosted region\n",
77 cmd_addcmd("trace stop",
80 "Stop trace buffer data collection",
82 "Stop tracing ZBbus transactions",
84 cmd_addcmd("trace freeze",
87 "Freeze trace buffer",
89 "Freeze the trace buffer",
91 cmd_addcmd("trace read",
94 "Read trace buffer into memory",
96 "Allocate a block of memory, copy the unprocessed contents\n"
97 "of the trace buffer into it, and generate a command template\n"
98 "for writing it to a file via TFTP.",
104 #define TB_SIZE (256*48) /* 256 entries, 384 bits/entry */
105 #define ZB_AGENT_CPU0 0
106 #define ZB_AGENT_CPU1 1
107 #define ZB_AGENT_IOB0 2
108 #define ZB_AGENT_IOB1 3
109 #define ZB_AGENT_SCD 4
110 #define ZB_AGENT_L2C 6
111 #define ZB_AGENT_MC 7
113 static const struct {
117 { "cpu0", ZB_AGENT_CPU0
},
118 { "cpu1", ZB_AGENT_CPU1
},
119 { "iob0", ZB_AGENT_IOB0
},
120 { "iob1", ZB_AGENT_IOB1
},
121 { "scd", ZB_AGENT_SCD
},
122 { "l2c", ZB_AGENT_L2C
},
123 { "mc", ZB_AGENT_MC
},
128 getagentarg (const char *id
, int *agent
)
132 for (i
= 0; agent_id
[i
].id
!= NULL
; i
++) {
133 if (strcmp(id
, agent_id
[i
].id
) == 0) {
134 *agent
= agent_id
[i
].code
;
142 getaddrarg (const char *x
, long *addr
)
151 * Following gdb, we make 64-bit addresses expressed as
152 * 8-digit numbers sign extend automagically. Saves
153 * typing, but is very gross.
157 longaddr
= strlen(x
);
158 if (memcmp(x
,"0x",2) == 0) longaddr
-= 2;
160 *addr
= (longaddr
> 8) ? (long) xtoq(x
) : (long) xtoi(x
);
168 static int ui_cmd_tracestart(ui_cmdline_t
*cmd
, int argc
, char *argv
[])
170 volatile uint64_t *tb_cfg
;
172 tb_cfg
= (volatile uint64_t *) PHYS_TO_K1(A_SCD_TRACE_CFG
);
175 volatile uint64_t *at_down_0
, *at_up_0
, *at_cfg_0
;
176 volatile uint64_t *tb_evt_0
, *tb_evt_4
;
177 volatile uint64_t *tb_seq_0
, *tb_seq_4
;
182 /* Place holder: parse new trace spec (select an option for now) */
184 n
= atoi(cmd_getarg(cmd
,0));
186 at_down_0
= (volatile uint64_t *) PHYS_TO_K1(A_ADDR_TRAP_DOWN_0
);
187 at_up_0
= (volatile uint64_t *) PHYS_TO_K1(A_ADDR_TRAP_UP_0
);
188 at_cfg_0
= (volatile uint64_t *) PHYS_TO_K1(A_ADDR_TRAP_CFG_0
);
190 tb_evt_0
= (volatile uint64_t *) PHYS_TO_K1(A_SCD_TRACE_EVENT_0
);
191 tb_evt_4
= (volatile uint64_t *) PHYS_TO_K1(A_SCD_TRACE_EVENT_4
);
192 tb_seq_0
= (volatile uint64_t *) PHYS_TO_K1(A_SCD_TRACE_SEQUENCE_0
);
193 tb_seq_4
= (volatile uint64_t *) PHYS_TO_K1(A_SCD_TRACE_SEQUENCE_4
);
195 /* Reset everything */
196 *tb_cfg
= M_SCD_TRACE_CFG_RESET
;
197 __asm__
__volatile__ ("sync" : : : "memory");
199 for (i
= 0; i
< 4; i
++) {
200 tb_evt_0
[i
] = 0; tb_evt_4
[i
] = 0;
201 tb_seq_0
[i
] = 0; tb_seq_4
[i
] = 0;
203 __asm__
__volatile__ ("sync" : : : "memory");
207 /* Filter on agent request or response */
209 found
= getagentarg(cmd_getarg(cmd
,1), &agent
);
213 agent
= ZB_AGENT_IOB0
; /* temporary, for backward compat */
215 tb_evt_0
[0] = M_SCD_TREVT_REQID_MATCH
216 | (M_SCD_TREVT_READ
| M_SCD_TREVT_WRITE
)
217 | V_SCD_TREVT_REQID(agent
);
218 tb_evt_0
[1] = M_SCD_TREVT_DATAID_MATCH
219 | V_SCD_TREVT_DATAID(agent
);
222 | M_SCD_TRSEQ_ASAMPLE
;
224 | M_SCD_TRSEQ_DSAMPLE
;
227 /* Filter on CPU accesses in LDT mirror region. */
230 at_down_0
[0] = 0xe000000000;
231 at_up_0
[0] = 0xefffffffff;
232 at_cfg_0
[0] = M_ATRAP_CFG_ALL
;
234 tb_evt_0
[0] = M_SCD_TREVT_REQID_MATCH
235 | V_SCD_TREVT_ADDR_MATCH(0x1) /* addr trap 0 */
236 | (M_SCD_TREVT_READ
| M_SCD_TREVT_WRITE
)
237 | V_SCD_TREVT_REQID(ZB_AGENT_CPU0
);
238 tb_evt_0
[1] = M_SCD_TREVT_RESPID_MATCH
239 | V_SCD_TREVT_RESPID(ZB_AGENT_IOB0
);
242 | M_SCD_TRSEQ_ASAMPLE
;
244 | M_SCD_TRSEQ_DSAMPLE
;
250 __asm__
__volatile__ ("sync" : : : "memory");
251 printf("trace start: trace 0: %llx 1: %llx\n", tb_evt_0
[0], tb_evt_0
[1]);
252 printf(" seq 0: %llx 1: %llx\n", tb_seq_0
[0], tb_seq_0
[1]);
255 *tb_cfg
= M_SCD_TRACE_CFG_START
;
256 __asm__
__volatile__ ("sync" : : : "memory");
258 printf("trace start: cfg %llx\n", *tb_cfg
);
262 static int ui_cmd_tracestop(ui_cmdline_t
*cmd
, int argc
, char *argv
[])
264 volatile uint64_t *tb_cfg
;
266 tb_cfg
= (volatile uint64_t *) PHYS_TO_K1(A_SCD_TRACE_CFG
);
267 *tb_cfg
= M_SCD_TRACE_CFG_STOP
;
268 __asm__
__volatile__ ("sync" : : : "memory");
270 printf("trace stop: cfg %llx\n", *tb_cfg
);
274 static int ui_cmd_tracefreeze(ui_cmdline_t
*cmd
, int argc
, char *argv
[])
276 volatile uint64_t *tb_cfg
;
278 tb_cfg
= (volatile uint64_t *) PHYS_TO_K1(A_SCD_TRACE_CFG
);
279 *tb_cfg
= M_SCD_TRACE_CFG_FREEZE
;
280 __asm__
__volatile__ ("sync" : : : "memory");
282 printf("trace freeze: cfg %llx\n", *tb_cfg
);
286 /* read out trace buffer to dump to a file */
288 static int ui_cmd_traceread(ui_cmdline_t
*cmd
, int argc
, char *argv
[])
291 volatile uint64_t *tb_cfg
;
292 volatile uint64_t *tb_read
;
295 p
= KMALLOC(TB_SIZE
, 0);
297 printf("trace read: buffer allocation failed\n");
301 tb_cfg
= (volatile uint64_t *) PHYS_TO_K1(A_SCD_TRACE_CFG
);
302 tb_read
= (volatile uint64_t *) PHYS_TO_K1(A_SCD_TRACE_READ
);
304 while ((*tb_cfg
& M_SCD_TRACE_CFG_FREEZE
) == 0) {
305 *tb_cfg
= M_SCD_TRACE_CFG_FREEZE
;
306 __asm__
__volatile__ ("sync" : : : "memory");
309 *tb_cfg
= M_SCD_TRACE_CFG_START_READ
;
310 __asm__
__volatile__ ("sync" : : : "memory");
312 /* Loop runs backward because bundles are read out in reverse order. */
313 for (i
= 256*6; i
> 0; i
-= 6) {
314 /* Subscripts decrease to put bundle in order. */
315 p
[i
-1] = *tb_read
; /* t2 hi */
316 p
[i
-2] = *tb_read
; /* t2 lo */
317 p
[i
-3] = *tb_read
; /* t1 hi */
318 p
[i
-4] = *tb_read
; /* t1 lo */
319 p
[i
-5] = *tb_read
; /* t0 hi */
320 p
[i
-6] = *tb_read
; /* t0 lo */
323 printf("save hardy:ehs/sample.trace %p 0x%lx\n", p
, TB_SIZE
);