Blame src/libpfm-3.y/examples_v3.x/showreginfo.c

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