aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.hgignore1
-rw-r--r--tools/misc/Makefile13
-rw-r--r--tools/misc/xenpm.c197
3 files changed, 207 insertions, 4 deletions
diff --git a/.hgignore b/.hgignore
index 13ced87e22..486f582fdd 100644
--- a/.hgignore
+++ b/.hgignore
@@ -183,6 +183,7 @@
^tools/misc/xen_cpuperf$
^tools/misc/xen-detect$
^tools/misc/xenperf$
+^tools/misc/xenpm$
^tools/pygrub/build/.*$
^tools/python/build/.*$
^tools/security/secpol_tool$
diff --git a/tools/misc/Makefile b/tools/misc/Makefile
index 04960ff101..97cec2e19a 100644
--- a/tools/misc/Makefile
+++ b/tools/misc/Makefile
@@ -11,15 +11,20 @@ CFLAGS += $(INCLUDES)
HDRS = $(wildcard *.h)
TARGETS-y := xenperf
-TARGETS-$(CONFIG_X86) += xen-detect
+TARGETS-$(CONFIG_X86) += xen-detect xenpm
TARGETS := $(TARGETS-y)
SUBDIRS-$(CONFIG_LOMOUNT) += lomount
SUBDIRS-$(CONFIG_MINITERM) += miniterm
SUBDIRS := $(SUBDIRS-y)
-INSTALL_BIN = $(TARGETS) xencons
-INSTALL_SBIN = netfix xm xen-bugtool xen-python-path xend xenperf xsview
+INSTALL_BIN-y := xencons
+INSTALL_BIN-$(CONFIG_X86) += xen-detect
+INSTALL_BIN := $(INSTALL_BIN-y)
+
+INSTALL_SBIN-y := netfix xm xen-bugtool xen-python-path xend xenperf xsview
+INSTALL_SBIN-$(CONFIG_X86) += xenpm
+INSTALL_SBIN := $(INSTALL_SBIN-y)
DEFAULT_PYTHON_PATH := $(shell $(XEN_ROOT)/tools/python/get-path)
PYTHON_PATH ?= $(DEFAULT_PYTHON_PATH)
@@ -49,5 +54,5 @@ clean:
%.o: %.c $(HDRS) Makefile
$(CC) -c $(CFLAGS) -o $@ $<
-xenperf: %: %.o Makefile
+xenperf xenpm: %: %.o Makefile
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LDFLAGS_libxenctrl)
diff --git a/tools/misc/xenpm.c b/tools/misc/xenpm.c
new file mode 100644
index 0000000000..b705f0a6fa
--- /dev/null
+++ b/tools/misc/xenpm.c
@@ -0,0 +1,197 @@
+/*
+ * xenpm.c: list the power information of the available processors
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <errno.h>
+
+#include <xenctrl.h>
+#include <inttypes.h>
+
+int main(int argc, char **argv)
+{
+ int xc_fd;
+ int i, j, ret = 0;
+ int cinfo = 0, pinfo = 0;
+ int ch;
+ xc_physinfo_t physinfo = { 0 };
+
+ while ( (ch = getopt(argc, argv, "cp")) != -1 )
+ {
+ switch ( ch )
+ {
+ case 'c':
+ cinfo = 1;
+ break;
+ case 'p':
+ pinfo = 1;
+ break;
+ default:
+ fprintf(stderr, "%s [-p] [-c]\n", argv[0]);
+ return -1;
+ }
+ }
+
+ if ( !cinfo && !pinfo )
+ {
+ cinfo = 1;
+ pinfo = 1;
+ }
+
+ xc_fd = xc_interface_open();
+ if ( xc_fd < 0 )
+ {
+ fprintf(stderr, "failed to get the handler\n");
+ return xc_fd;
+ }
+
+ ret = xc_physinfo(xc_fd, &physinfo);
+ if ( ret )
+ {
+ fprintf(stderr, "failed to get the processor information\n");
+ xc_interface_close(xc_fd);
+ return ret;
+ }
+
+ /* print out the C state information */
+ if ( cinfo )
+ {
+ int max_cx_num = 0;
+ struct xc_cx_stat cxstatinfo, *cxstat = &cxstatinfo;
+
+ for ( i = 0; i < physinfo.nr_cpus; i++ )
+ {
+ ret = xc_pm_get_max_cx(xc_fd, i, &max_cx_num);
+ if ( ret )
+ {
+ if ( errno == ENODEV )
+ fprintf(stderr, "Xen cpuidle is not enabled!\n");
+ else
+ fprintf(stderr, "failed to get max C-state\n");
+
+ break;
+ }
+
+ cxstat->triggers = malloc(max_cx_num * sizeof(uint64_t));
+ if ( !cxstat->triggers )
+ {
+ fprintf(stderr, "failed to malloc for C-states triggers\n");
+ break;
+ }
+ cxstat->residencies = malloc(max_cx_num * sizeof(uint64_t));
+ if ( !cxstat->residencies )
+ {
+ fprintf(stderr, "failed to malloc for C-states residencies\n");
+ free(cxstat->triggers);
+ break;
+ }
+
+ ret = xc_pm_get_cxstat(xc_fd, i, cxstat);
+ if( ret )
+ {
+ fprintf(stderr, "failed to get C-states statistics information\n");
+ free(cxstat->triggers);
+ free(cxstat->residencies);
+ break;
+ }
+
+ printf("cpu id : %d\n", i);
+ printf("total C-states : %d\n", cxstat->nr);
+ printf("idle time(ms) : %"PRIu64"\n", cxstat->idle_time/1000000UL);
+ for ( j = 0; j < cxstat->nr; j++ )
+ {
+ printf("C%d : transition [%020"PRIu64"]\n",
+ j, cxstat->triggers[j]);
+ printf(" residency [%020"PRIu64" ms]\n",
+ cxstat->residencies[j]*1000000UL/3579/1000000UL);
+ }
+
+ free(cxstat->triggers);
+ free(cxstat->residencies);
+
+ printf("\n");
+ }
+ }
+
+ /* print out P state information */
+ if ( pinfo )
+ {
+ int max_px_num = 0;
+ struct xc_px_stat pxstatinfo, *pxstat = &pxstatinfo;
+
+ for ( i = 0; i < physinfo.nr_cpus; i++ )
+ {
+ ret = xc_pm_get_max_px(xc_fd, i, &max_px_num);
+ if ( ret ) {
+ if ( errno == ENODEV )
+ printf("Xen cpufreq is not enabled!\n");
+ else
+ fprintf(stderr, "failed to get max P-state\n");
+
+ break;
+ }
+
+ pxstat->trans_pt = malloc(max_px_num * max_px_num * sizeof(uint64_t));
+ if ( !pxstat->trans_pt )
+ {
+ fprintf(stderr, "failed to malloc for P-states transition table\n");
+ break;
+ }
+ pxstat->pt = malloc(max_px_num * sizeof(struct xc_px_val));
+ if ( !pxstat->pt )
+ {
+ fprintf(stderr, "failed to malloc for P-states table\n");
+ free(pxstat->pt);
+ break;
+ }
+
+ ret = xc_pm_get_pxstat(xc_fd, 0, pxstat);
+ if( ret ) {
+ fprintf(stderr, "failed to get P-states statistics information\n");
+ free(pxstat->trans_pt);
+ free(pxstat->pt);
+ break;
+ }
+
+ printf("cpu id : %d\n", i);
+ printf("total P-states : %d\n", pxstat->total);
+ printf("usable P-states : %d\n", pxstat->usable);
+ printf("current frequency : %"PRIu64" MHz\n", pxstat->pt[pxstat->cur].freq);
+ for ( j = 0; j < pxstat->total; j++ )
+ {
+ if ( pxstat->cur == j )
+ printf("*P%d", j);
+ else
+ printf("P%d ", j);
+ printf(" : freq [%04"PRIu64" MHz]\n", pxstat->pt[j].freq);
+ printf(" transition [%020"PRIu64"]\n", pxstat->pt[j].count);
+ printf(" residency [%020"PRIu64" ms]\n", pxstat->pt[j].residency/1000000UL);
+ }
+
+ free(pxstat->trans_pt);
+ free(pxstat->pt);
+
+ printf("\n");
+ }
+ }
+
+ xc_interface_close(xc_fd);
+ return ret;
+}
+