BCM WL 6.30.102.9 (r366174)
[tomato.git] / release / src-rt / cfe / cfe / arch / mips / cpu / sb1250 / src / cfe_trace.c
blob922a8a6847897443026758db36b788c0752bb478
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * Trace commands File: cfe_trace.c
5 *
6 * A minimal interface for running the SB-1250 trace buffer under CFE
7 *
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 ********************************************************************* */
46 #include "sbmips.h"
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",
68 ui_cmd_tracestart,
69 NULL,
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",
76 "");
77 cmd_addcmd("trace stop",
78 ui_cmd_tracestop,
79 NULL,
80 "Stop trace buffer data collection",
81 "trace stop\n\n"
82 "Stop tracing ZBbus transactions",
83 "");
84 cmd_addcmd("trace freeze",
85 ui_cmd_tracefreeze,
86 NULL,
87 "Freeze trace buffer",
88 "trace freeze\n\n"
89 "Freeze the trace buffer",
90 "");
91 cmd_addcmd("trace read",
92 ui_cmd_traceread,
93 NULL,
94 "Read trace buffer into memory",
95 "trace read\n\n"
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.",
99 "");
101 return 0;
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 {
114 const char *id;
115 int code;
116 } agent_id[] = {
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 },
124 { NULL, 0 }
127 static int
128 getagentarg (const char *id, int *agent)
130 int i;
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;
135 return 1;
138 return 0;
141 static int
142 getaddrarg (const char *x, long *addr)
144 int res;
146 res = 0;
147 *addr = 0;
149 if (x) {
151 * Following gdb, we make 64-bit addresses expressed as
152 * 8-digit numbers sign extend automagically. Saves
153 * typing, but is very gross.
155 int longaddr;
157 longaddr = strlen(x);
158 if (memcmp(x,"0x",2) == 0) longaddr -= 2;
160 *addr = (longaddr > 8) ? (long) xtoq(x) : (long) xtoi(x);
161 res = 1;
164 return res;
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);
174 if (argc != 0) {
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;
178 int i, n;
179 int found;
180 int agent;
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");
205 switch (n) {
206 case 0:
207 /* Filter on agent request or response */
208 if (argc > 1)
209 found = getagentarg(cmd_getarg(cmd,1), &agent);
210 else
211 found = 0;
212 if (!found)
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);
221 tb_seq_0[0] = 0x0fff
222 | M_SCD_TRSEQ_ASAMPLE;
223 tb_seq_0[1] = 0x1fff
224 | M_SCD_TRSEQ_DSAMPLE;
225 break;
226 case 1:
227 /* Filter on CPU accesses in LDT mirror region. */
228 (void)getaddrarg;
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);
241 tb_seq_0[0] = 0x0fff
242 | M_SCD_TRSEQ_ASAMPLE;
243 tb_seq_0[1] = 0x1fff
244 | M_SCD_TRSEQ_DSAMPLE;
245 break;
246 default:
247 break;
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);
259 return 0;
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);
271 return 0;
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);
283 return 0;
286 /* read out trace buffer to dump to a file */
288 static int ui_cmd_traceread(ui_cmdline_t *cmd, int argc, char *argv[])
290 uint64_t *p;
291 volatile uint64_t *tb_cfg;
292 volatile uint64_t *tb_read;
293 int i;
295 p = KMALLOC(TB_SIZE, 0);
296 if (!p) {
297 printf("trace read: buffer allocation failed\n");
298 return -1;
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);
325 return 0;