* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: coverage_dump.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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
#pragma ident "@(#)coverage_dump.c 1.6 06/10/25 SMI"
#define DBGP(s) do { s } while (0)
printf("\nUsage: coverage_dump [- a] [-z] [-c num_samples] "\
"[-r] [-v] [-t] filename" \
"\n - dump all samples (zero and non-zero)" \
"\n - dump only zero samples (%%pc never hit)" \
"\n [-c | --count num_of_samples]" \
"\n - dump first num_of_samples %%pc samples" \
"\n - if this option is not given, all non-zero "\
"\n - don't increment the ref count for each "\
"\n instead print 0x1 (if it was ever executed) "\
"\n or a 0x0 (if it was never executed) "\
"\n - decode and display the raw instns" \
"\n by default, only the raw instn gets dumped" \
"\n - print titles and footer " \
"\n The name of file with legion coverage data" \
"\n When run with no options, dump all non-zero samples" \
"\n This tool is meant to work with the debug_hook feature" \
"\n for gathering coverage data. You need to" \
"\n specify a range of %%pc addresses in the conf file " \
"\n under the cpu directive as follows:" \
"\n debug_hook coverage 0x100000 0x800000;" \
return (strcmp(a
, b
) == 0);
* Attach to shared memory created by legion and
* dump out coverage statistics from the running
main(int argc
, char ** argv
)
bool_t dump_all_samples
= false;
bool_t dump_zero_samples
= false;
coverage_info_t coverage_buf
;
for (i
= 1; i
< argc
&& argv
[i
][0] == '-'; i
++) {
if (streq(p
, "a") || streq(p
, "-all")) {
printf("\nERROR: Cannot use both -a and -z");
if (streq(p
, "z") || streq(p
, "-zero")) {
printf("\nERROR: Cannot use both -a and -z");
dump_zero_samples
= true;
if (streq(p
, "c") || streq(p
, "-count")) {
dump_count
= atol(argv
[i
]);
printf("\nERROR: Invalid value for count");
if (streq(p
, "r") || streq(p
, "-ref")) {
if (streq(p
, "v") || streq(p
, "-verbose")) {
if (streq(p
, "t") || streq(p
, "-titles")) {
printf("\nERROR: Illegal option %s", p
);
* Assume any non option provided is the name of the coverage
strcpy(filename
, argv
[i
]);
printf("\nERROR: no filename specified");
* Open the dump_file and get it's size.
* In order to figure out how many samples are in this file
* we divide the file size by the size of this struct.
* We can then then either dump them all, or dump just the first n
* if the -c flag is specified.
if (stat(filename
, &sb
) == -1)
fatal("Error: dump_file %s does not exist.", filename
);
sample_count
= (sb
.st_size
/ (sizeof (coverage_info_t
)));
if ((fd
= open(filename
, O_RDONLY
)) == -1)
fatal("Could not open dump_file %s\n", filename
);
* Depending on whether a specific number of samples was
* given at the command line or not, we either dump them
* all or just the first n samples.
* The -a flag determines whether we print the zero samples.
* The -z flag determines whether we only print the zero samples.
num_of_pcs
= dump_count
; /* value from command line */
num_of_pcs
= sample_count
;
printf("\nOpened data file : [%s] ", filename
);
printf("\nSize of file in bytes : [0x%llx] ", sb
.st_size
);
printf("\nNumber of %%pc samples : [0x%llx] ", sample_count
);
printf("\nIndx:%%pc:Ref_Cnt:Raw_Instn Decoded_Inst\n");
for (i
= 0; i
< num_of_pcs
; i
++) {
if (read(fd
, &coverage_buf
, sizeof (coverage_info_t
)) !=
sizeof (coverage_info_t
)) {
fatal("Error reading from file %s\n", filename
);
/* Gather stats for the end */
if (coverage_buf
.count
!= 0) {
/* save the last non-zero count %pc */
high_pc
= coverage_buf
.pc
;
/* save the first non-zero count %pc */
low_pc
= coverage_buf
.pc
;
/* Figure out whether to print this sample or not */
} else if (dump_zero_samples
) {
if (coverage_buf
.count
== 0)
} else if (coverage_buf
.count
!= 0) {
if (coverage_buf
.count
> 0x1)
coverage_buf
.count
= 0x1; /* reset to 0x1 */
printf("0x%llx:0x%llx:0x%x:0x%08x",
i
, coverage_buf
.pc
, coverage_buf
.count
,
if (coverage_buf
.count
!= 0) {
sparcv9_idis(instn_buf
, sizeof (instn_buf
),
coverage_buf
.rawi
, coverage_buf
.pc
);
sprintf(instn_buf
, ":N/A", "%s");
printf(":%s", instn_buf
);
printf("\nLoweset/Highest %%pc : [0x%llx] [0x%llx]\n",