* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: trace.c
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
* ========== Copyright Header End ============================================
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
#pragma ident "@(#)trace.c 1.8 07/01/09 SMI"
#define DBGP(s) do { s } while (0)
void dbg_trace(simcpu_t
*sp
, uint32_t rawi
);
void dbg_trace_parse(void);
void dbg_trace_dump(void);
static void dump_intregs(uint64_t *data
);
* ALL = trace all instns for all values of %pc
* PC = start trace when "start" %pc is encountered
* stop when 'end' %pc is encountered.
* INSTN = only trace when instn count is within start-end range
enum trace_modes
{ ALL
, PC
, INSTN
};
/* start/end for pc,instn tracing */
uint64_t start_trace
= 0x0;
uint64_t end_trace
= 0x0;
bool_t dump_regs
= false;
* This will be called while parsing the conf file
* to allow this hook to parse specific options from
* Format of trace directive is:
* debug_hook [trace] [mode] [regs] [start] [end];
* [trace] - we've already parsed this. That's how we got here.
* [mode] - is one of [all, pc, instn]
* all : traces all instns (no start, end values)
* pc : just trace when %pc is withing start-end range
* instn : just trace when instn count is within start-end
* [regs] - if defined, we dump the %g,%o,%l,%i regs with each sample.
* [end] - only trace when %pc or inst_cnt is within [start]-[end]
* trace pc regs 0x123 0x456;
* trace instn 0x123 0x456;
* trace instn regs 0x123 0x456;
DBGP(printf("\nInside dbg_trace_parse()"););
tok
= lex_get_token(); /* trace mode */
strcpy(trace_mode_str
, lex
.strp
);
if (streq(lex
.strp
, "all"))
else if (streq(lex
.strp
, "pc"))
else if (streq(lex
.strp
, "instn"))
lex_fatal("unknown trace_mode [%s] parsing config", lex
.strp
);
/* parse optional regs token */
if (streq(lex
.strp
, "regs")) {
lex_unget(); /* no regs option, continue */
* continue parsing conf file
break; /* no more parsing for 'all' mode */
lex_get(T_Number
); /* start pc/instn */
lex_get(T_Number
); /* end pc/instn */
DBGP(printf("\ndbg_trace_parse: mode=%s, start=0x%llx, end=0x%llx",
trace_mode_str
, start_trace
, end_trace
););
* return to parse_debug_hook() which will take care
* of parsing the last semi colon.
* This function will get called before each instruction
* gets executed. For performance reasons, we may want to
* store the data in a buffer and post-process it later.
dbg_trace(simcpu_t
*sp
, uint32_t rawi
)
static bool_t first_time
= true;
* If a trace range is given, we only trace within that
break; /* trace everything */
if ((sp
->pc
< start_trace
) || (sp
->pc
> end_trace
)) {
return; /* only trace when %pc is in range */
if ((sp
->cycle
< start_trace
) ||
(sp
->cycle
> end_trace
)) {
return; /* only trace when instn count is in range */
v9p
= (sparcv9_cpu_t
*)sp
->specificp
;
sparcv9_idis(trace_buf
, sizeof (trace_buf
),
printf("\n[cpu] Instn_# tl:tt/gl state %%pc [raw_instn]"
* When printing registers, we print them in their state prior to
* executing the instruction in question.
dump_intregs(sp
->intreg
);
printf("\n[0x%llx] 0x%llx %x:%x/%x 0x%x 0x%llx [0x%08x]\t%s",
(v9p
->tl
== 0) ? 0 : N_TT(v9p
, v9p
->tl
),
dump_intregs(uint64_t *intreg
)
for (i
= 0; i
< 8; i
++) {
printf("\ng%d=0x%016llx o%d=0x%016llx l%d=0x%016llx i%d=0x%016llx",
printf("\ndbg_trace_dump: caled with mode=%s, start=0x%llx, "\
"end=0x%llx\n", trace_mode_str
, start_trace
, end_trace
);