summaryrefslogtreecommitdiffstats
path: root/usr.sbin/cpucontrol
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2014-06-19 21:54:41 +0000
committerattilio <attilio@FreeBSD.org>2014-06-19 21:54:41 +0000
commite1ad5f01a6f69b9c7b819712142aec0f82faa8fe (patch)
tree429567dc0768822de4253cd98cbc123c22fd4a08 /usr.sbin/cpucontrol
parent2cd5489f2cdba4185c209ef5cd12f49e3f2113d9 (diff)
downloadFreeBSD-src-e1ad5f01a6f69b9c7b819712142aec0f82faa8fe.zip
FreeBSD-src-e1ad5f01a6f69b9c7b819712142aec0f82faa8fe.tar.gz
Following comments in r242565 add the possibility to specify ecx when
performing cpuid calls. Add also a new way to specify the level type to cpucontrol(8) as reported in the manpage. Sponsored by: EMC / Isilon storage division Reviewed by: bdrewery, gcooper Testerd by: bdrewery
Diffstat (limited to 'usr.sbin/cpucontrol')
-rw-r--r--usr.sbin/cpucontrol/cpucontrol.89
-rw-r--r--usr.sbin/cpucontrol/cpucontrol.c59
2 files changed, 66 insertions, 2 deletions
diff --git a/usr.sbin/cpucontrol/cpucontrol.8 b/usr.sbin/cpucontrol/cpucontrol.8
index 0998b20..cb1a29e 100644
--- a/usr.sbin/cpucontrol/cpucontrol.8
+++ b/usr.sbin/cpucontrol/cpucontrol.8
@@ -65,6 +65,12 @@ device
.Ek
.Nm
.Op Fl vh
+.Fl i Ar level,level_type
+.Bk
+.Ar device
+.Ek
+.Nm
+.Op Fl vh
.Op Fl d Ar datadir
.Fl u
.Bk
@@ -114,6 +120,9 @@ In this case the inverted value of mask will be used.
.It Fl i Ar level
Retrieve CPUID info.
Level should be given as a hex number.
+.It Fl i Ar level,level_type
+Retrieve CPUID info.
+Level and level_type should be given as hex numbers.
.It Fl u
Apply CPU firmware updates.
The
diff --git a/usr.sbin/cpucontrol/cpucontrol.c b/usr.sbin/cpucontrol/cpucontrol.c
index c0d5a31..9832d9f 100644
--- a/usr.sbin/cpucontrol/cpucontrol.c
+++ b/usr.sbin/cpucontrol/cpucontrol.c
@@ -99,6 +99,7 @@ static struct ucode_handler {
static void usage(void);
static int isdir(const char *path);
static int do_cpuid(const char *cmdarg, const char *dev);
+static int do_cpuid_count(const char *cmdarg, const char *dev);
static int do_msr(const char *cmdarg, const char *dev);
static int do_update(const char *dev);
static void datadir_add(const char *path);
@@ -112,7 +113,7 @@ usage(void)
if (name == NULL)
name = "cpuctl";
fprintf(stderr, "Usage: %s [-vh] [-d datadir] [-m msr[=value] | "
- "-i level | -u] device\n", name);
+ "-i level | -i level,level_type | -u] device\n", name);
exit(EX_USAGE);
}
@@ -170,6 +171,57 @@ do_cpuid(const char *cmdarg, const char *dev)
}
static int
+do_cpuid_count(const char *cmdarg, const char *dev)
+{
+ char *cmdarg1, *endptr, *endptr1;
+ unsigned int level, level_type;
+ cpuctl_cpuid_args_t args;
+ int fd, error;
+
+ assert(cmdarg != NULL);
+ assert(dev != NULL);
+
+ level = strtoul(cmdarg, &endptr, 16);
+ if (*cmdarg == '\0' || *endptr == '\0') {
+ WARNX(0, "incorrect or missing operand: %s", cmdarg);
+ usage();
+ /* NOTREACHED */
+ }
+ /* Locate the comma... */
+ cmdarg1 = strstr(endptr, ",");
+ /* ... and skip past it */
+ cmdarg1 += 1;
+ level_type = strtoul(cmdarg1, &endptr1, 16);
+ if (*cmdarg1 == '\0' || *endptr1 != '\0') {
+ WARNX(0, "incorrect or missing operand: %s", cmdarg);
+ usage();
+ /* NOTREACHED */
+ }
+
+ /*
+ * Fill ioctl argument structure.
+ */
+ args.level = level;
+ args.level_type = level_type;
+ fd = open(dev, O_RDONLY);
+ if (fd < 0) {
+ WARN(0, "error opening %s for reading", dev);
+ return (1);
+ }
+ error = ioctl(fd, CPUCTL_CPUID_COUNT, &args);
+ if (error < 0) {
+ WARN(0, "ioctl(%s, CPUCTL_CPUID_COUNT)", dev);
+ close(fd);
+ return (error);
+ }
+ fprintf(stdout, "cpuid level 0x%x, level_type 0x%x: 0x%.8x 0x%.8x "
+ "0x%.8x 0x%.8x\n", level, level_type, args.data[0], args.data[1],
+ args.data[2], args.data[3]);
+ close(fd);
+ return (0);
+}
+
+static int
do_msr(const char *cmdarg, const char *dev)
{
unsigned int msr;
@@ -414,7 +466,10 @@ main(int argc, char *argv[])
c = flags & (FLAG_I | FLAG_M | FLAG_U);
switch (c) {
case FLAG_I:
- error = do_cpuid(cmdarg, dev);
+ if (strstr(cmdarg, ",") != NULL)
+ error = do_cpuid_count(cmdarg, dev);
+ else
+ error = do_cpuid(cmdarg, dev);
break;
case FLAG_M:
error = do_msr(cmdarg, dev);
OpenPOWER on IntegriCloud