|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* showreginfo.c - show PMU register information
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
|
|
Packit |
577717 |
* Contributed by Stephane Eranian <eranian@hpl.hp.com>
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
Packit |
577717 |
* of this software and associated documentation files (the "Software"), to deal
|
|
Packit |
577717 |
* in the Software without restriction, including without limitation the rights
|
|
Packit |
577717 |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
Packit |
577717 |
* of the Software, and to permit persons to whom the Software is furnished to do so,
|
|
Packit |
577717 |
* subject to the following conditions:
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* The above copyright notice and this permission notice shall be included in all
|
|
Packit |
577717 |
* copies or substantial portions of the Software.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
Packit |
577717 |
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
Packit |
577717 |
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
Packit |
577717 |
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
Packit |
577717 |
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
|
Packit |
577717 |
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* This file is part of libpfm, a performance monitoring support library for
|
|
Packit |
577717 |
* applications on Linux.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
#include <sys/types.h>
|
|
Packit |
577717 |
#include <stdio.h>
|
|
Packit |
577717 |
#include <fcntl.h>
|
|
Packit |
577717 |
#include <stdlib.h>
|
|
Packit |
577717 |
#include <inttypes.h>
|
|
Packit |
577717 |
#include <stdarg.h>
|
|
Packit |
577717 |
#include <errno.h>
|
|
Packit |
577717 |
#include <unistd.h>
|
|
Packit |
577717 |
#include <string.h>
|
|
Packit |
577717 |
#include <getopt.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include <perfmon/perfmon.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void fatal_error(char *fmt,...) __attribute__((noreturn));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void
|
|
Packit |
577717 |
fatal_error(char *fmt, ...)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
va_list ap;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
va_start(ap, fmt);
|
|
Packit |
577717 |
vfprintf(stderr, fmt, ap);
|
|
Packit |
577717 |
va_end(ap);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
exit(1);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
get_value(char *fn, char *buffer, size_t maxlen)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int fd;
|
|
Packit |
577717 |
ssize_t ret;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
fd = open(fn, O_RDONLY);
|
|
Packit |
577717 |
if (fd == -1)
|
|
Packit |
577717 |
return -1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ret = read(fd, buffer, maxlen-1);
|
|
Packit |
577717 |
if (ret == -1)
|
|
Packit |
577717 |
fatal_error("cannot read from %s\n", fn);
|
|
Packit |
577717 |
buffer[ret-1] = '\0';
|
|
Packit |
577717 |
close(fd);
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* This example shows how to retrieve the PMU register mapping information.
|
|
Packit |
577717 |
* It does not use the libpfm library.
|
|
Packit |
577717 |
* The mapping gives the translation between the logical register names,
|
|
Packit |
577717 |
* as exposed by the perfmon interface, and the actual hardware registers.
|
|
Packit |
577717 |
* Depending on the PMU and perfmon implementation, not all registers are
|
|
Packit |
577717 |
* necessarily PMU registers, some may correspond to software resources.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
main(int argc, char **argv)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned long long dfl, rsvd;
|
|
Packit |
577717 |
unsigned long hw_addr;
|
|
Packit |
577717 |
pfarg_ctx_t ctx;
|
|
Packit |
577717 |
char pname[64];
|
|
Packit |
577717 |
char name[64], buffer[32];
|
|
Packit |
577717 |
unsigned int i, num_pmcs = 0, num_pmds = 0;
|
|
Packit |
577717 |
int c, ret, ret2 = 0;
|
|
Packit |
577717 |
int use_html = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
while((c=getopt(argc, argv, "hH")) != -1) {
|
|
Packit |
577717 |
switch(c) {
|
|
Packit |
577717 |
case 'h':
|
|
Packit |
577717 |
printf("usage: showreginfo [-h] [-H]\n");
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
case 'H':
|
|
Packit |
577717 |
use_html = 1;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
default:
|
|
Packit |
577717 |
return -1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
try_again:
|
|
Packit |
577717 |
ret = get_value("/sys/kernel/perfmon/pmu_desc/model", buffer, sizeof(buffer));
|
|
Packit |
577717 |
if (ret == -1) {
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* try to trigger automatic PMU description loading
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
if (ret2 == 0) {
|
|
Packit |
577717 |
memset(&ctx, 0, sizeof(ctx));
|
|
Packit |
577717 |
ret2 = pfm_create_context(&ctx, NULL, NULL, 0);
|
|
Packit |
577717 |
if (ret2 > 0) {
|
|
Packit |
577717 |
close(ret2);
|
|
Packit |
577717 |
goto try_again;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
fatal_error("invalid or missing perfmon support for your CPU (need at least v2.3)\n");
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (use_html) {
|
|
Packit |
577717 |
puts("");
|
|
Packit |
577717 |
puts("<html>");
|
|
Packit |
577717 |
puts("<head>");
|
|
Packit |
577717 |
puts("<body>");
|
|
Packit |
577717 |
puts("");
|
|
Packit |
577717 |
printf("<caption>%s</caption>\n", buffer);
|
|
Packit |
577717 |
puts("");
|
|
Packit |
577717 |
puts("NameHW ADDRDescription");
|
|
Packit |
577717 |
puts("");
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
printf("model : %s\n", buffer);
|
|
Packit |
577717 |
puts( "----------------------------------------------------------------------------\n"
|
|
Packit |
577717 |
"name | default value | reserved mask | hw address | description\n"
|
|
Packit |
577717 |
"-------+--------------------+--------------------+------------+-------------");
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(i=0; i < PFM_MAX_PMCS; i++) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
sprintf(pname, "/sys/kernel/perfmon/pmu_desc/pmc%d/name", i);
|
|
Packit |
577717 |
ret = get_value(pname, name, sizeof(name));
|
|
Packit |
577717 |
if (ret)
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
num_pmcs++;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
sprintf(pname, "/sys/kernel/perfmon/pmu_desc/pmc%d/dfl_val", i);
|
|
Packit |
577717 |
get_value(pname, buffer, sizeof(buffer));
|
|
Packit |
577717 |
dfl = strtoull(buffer, NULL, 16);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
sprintf(pname, "/sys/kernel/perfmon/pmu_desc/pmc%d/rsvd_msk", i);
|
|
Packit |
577717 |
get_value(pname, buffer, sizeof(buffer));
|
|
Packit |
577717 |
rsvd = strtoull(buffer, NULL, 16);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
sprintf(pname, "/sys/kernel/perfmon/pmu_desc/pmc%d/addr", i);
|
|
Packit |
577717 |
get_value(pname, buffer, sizeof(buffer));
|
|
Packit |
577717 |
hw_addr = strtoul(buffer, NULL, 0);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (use_html) {
|
|
Packit |
577717 |
printf(" PMC%d0x%lx%s\n",
|
|
Packit |
577717 |
i,
|
|
Packit |
577717 |
hw_addr,
|
|
Packit |
577717 |
name);
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
printf("pmc%-3d | 0x%016llx | 0x%016llx | 0x%-8lx | %s\n",
|
|
Packit |
577717 |
i,
|
|
Packit |
577717 |
dfl,
|
|
Packit |
577717 |
rsvd,
|
|
Packit |
577717 |
hw_addr,
|
|
Packit |
577717 |
name);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (use_html)
|
|
Packit |
577717 |
puts("");
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
puts("-------+--------------------+--------------------+------------+-------------");
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(i=0; i < PFM_MAX_PMDS; i++) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
sprintf(pname, "/sys/kernel/perfmon/pmu_desc/pmd%d/name", i);
|
|
Packit |
577717 |
ret = get_value(pname, name, sizeof(name));
|
|
Packit |
577717 |
if (ret)
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
num_pmds++;
|
|
Packit |
577717 |
sprintf(pname, "/sys/kernel/perfmon/pmu_desc/pmd%d/dfl_val", i);
|
|
Packit |
577717 |
get_value(pname, buffer, sizeof(buffer));
|
|
Packit |
577717 |
dfl = strtoull(buffer, NULL, 16);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
sprintf(pname, "/sys/kernel/perfmon/pmu_desc/pmd%d/rsvd_msk", i);
|
|
Packit |
577717 |
get_value(pname, buffer, sizeof(buffer));
|
|
Packit |
577717 |
rsvd = strtoull(buffer, NULL, 16);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
sprintf(pname, "/sys/kernel/perfmon/pmu_desc/pmd%d/addr", i);
|
|
Packit |
577717 |
get_value(pname, buffer, sizeof(buffer));
|
|
Packit |
577717 |
hw_addr = strtoul(buffer, NULL, 0);
|
|
Packit |
577717 |
if (use_html) {
|
|
Packit |
577717 |
printf(" PMC%d0x%lx%s\n",
|
|
Packit |
577717 |
i,
|
|
Packit |
577717 |
hw_addr,
|
|
Packit |
577717 |
name);
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
printf("pmd%-3d | 0x%016llx | 0x%016llx | 0x%-8lx | %s\n",
|
|
Packit |
577717 |
i,
|
|
Packit |
577717 |
dfl,
|
|
Packit |
577717 |
rsvd,
|
|
Packit |
577717 |
hw_addr,
|
|
Packit |
577717 |
name);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (use_html) {
|
|
Packit |
577717 |
puts("");
|
|
Packit |
577717 |
puts("</body>");
|
|
Packit |
577717 |
puts("</html>");
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
puts("----------------------------------------------------------------------------");
|
|
Packit |
577717 |
printf("%u PMC registers, %u PMD registers\n", num_pmcs, num_pmds);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|