Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e30baad authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'acpi-tools' and 'pm-tools'

* acpi-tools:
  ACPI / tools: Introduce ec_access.c - tool to access the EC

* pm-tools:
  cpupower: Remove mc and smt power aware scheduler info/settings
  cpupower: cpupower info -b should return 0 on success, not the perf bias value
  cpupower: If root, try to load msr driver on x86 if /dev/cpu/0/msr is not available
  cpupower: Install recently added cpupower-idle-{set, info} manpages
  cpupower: Introduce idle state disable-by-latency and enable-all
  cpupower: Remove all manpages on make uninstall
  cpupower: Remove dead link to homepage, and update the targets built.
  cpupower: Rename cpufrequtils -> cpupower, and libcpufreq -> libcpupower.
  PM / tools: cpupower: add option to display values without round offs
  tools / power: turbostat: Drop temperature checks
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd)
$(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist))
endif

SUBDIRS = tools/ec

# --- CONFIGURATION BEGIN ---

# Set the following to `true' to make a unstripped, unoptimized
+22 −0
Original line number Diff line number Diff line
ec_access: ec_access.o
	$(ECHO) "  LD      " $@
	$(QUIET) $(LD) $(CFLAGS) $(LDFLAGS) $< -o $@
	$(QUIET) $(STRIPCMD) $@

%.o: %.c
	$(ECHO) "  CC      " $@
	$(QUIET) $(CC) -c $(CFLAGS) -o $@ $<

all: ec_access

install:
	$(INSTALL) -d $(DESTDIR)${sbindir}
	$(INSTALL_PROGRAM) ec_access $(DESTDIR)${sbindir}

uninstall:
	- rm -f $(DESTDIR)${sbindir}/ec_access

clean:
	-rm -f $(OUTPUT)ec_access

.PHONY: all install uninstall
+238 −0
Original line number Diff line number Diff line
/*
 * ec_access.c
 *
 * Copyright (C) 2010 SUSE Linux Products GmbH
 * Author:
 *      Thomas Renninger <trenn@suse.de>
 *
 * This work is licensed under the terms of the GNU GPL, version 2.
 */

#include <fcntl.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <unistd.h>
#include <getopt.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>


#define EC_SPACE_SIZE 256
#define SYSFS_PATH "/sys/kernel/debug/ec/ec0/io"

/* TBD/Enhancements:
   - Provide param for accessing different ECs (not supported by kernel yet)
*/

static int read_mode = -1;
static int sleep_time;
static int write_byte_offset = -1;
static int read_byte_offset = -1;
static uint8_t write_value = -1;

void usage(char progname[], int exit_status)
{
	printf("Usage:\n");
	printf("1) %s -r [-s sleep]\n", basename(progname));
	printf("2) %s -b byte_offset\n", basename(progname));
	printf("3) %s -w byte_offset -v value\n\n", basename(progname));

	puts("\t-r [-s sleep]      : Dump EC registers");
	puts("\t                     If sleep is given, sleep x seconds,");
	puts("\t                     re-read EC registers and show changes");
	puts("\t-b offset          : Read value at byte_offset (in hex)");
	puts("\t-w offset -v value : Write value at byte_offset");
	puts("\t-h                 : Print this help\n\n");
	puts("Offsets and values are in hexadecimal number sytem.");
	puts("The offset and value must be between 0 and 0xff.");
	exit(exit_status);
}

void parse_opts(int argc, char *argv[])
{
	int c;

	while ((c = getopt(argc, argv, "rs:b:w:v:h")) != -1) {

		switch (c) {
		case 'r':
			if (read_mode != -1)
				usage(argv[0], EXIT_FAILURE);
			read_mode = 1;
			break;
		case 's':
			if (read_mode != -1 && read_mode != 1)
				usage(argv[0], EXIT_FAILURE);

			sleep_time = atoi(optarg);
			if (sleep_time <= 0) {
				sleep_time = 0;
				usage(argv[0], EXIT_FAILURE);
				printf("Bad sleep time: %s\n", optarg);
			}
			break;
		case 'b':
			if (read_mode != -1)
				usage(argv[0], EXIT_FAILURE);
			read_mode = 1;
			read_byte_offset = strtoul(optarg, NULL, 16);
			break;
		case 'w':
			if (read_mode != -1)
				usage(argv[0], EXIT_FAILURE);
			read_mode = 0;
			write_byte_offset = strtoul(optarg, NULL, 16);
			break;
		case 'v':
			write_value = strtoul(optarg, NULL, 16);
			break;
		case 'h':
			usage(argv[0], EXIT_SUCCESS);
		default:
			fprintf(stderr, "Unknown option!\n");
			usage(argv[0], EXIT_FAILURE);
		}
	}
	if (read_mode == 0) {
		if (write_byte_offset < 0 ||
		    write_byte_offset >= EC_SPACE_SIZE) {
			fprintf(stderr, "Wrong byte offset 0x%.2x, valid: "
				"[0-0x%.2x]\n",
				write_byte_offset, EC_SPACE_SIZE - 1);
			usage(argv[0], EXIT_FAILURE);
		}
		if (write_value < 0 ||
		    write_value >= 255) {
			fprintf(stderr, "Wrong byte offset 0x%.2x, valid:"
				"[0-0xff]\n", write_byte_offset);
			usage(argv[0], EXIT_FAILURE);
		}
	}
	if (read_mode == 1 && read_byte_offset != -1) {
		if (read_byte_offset < -1 ||
		    read_byte_offset >= EC_SPACE_SIZE) {
			fprintf(stderr, "Wrong byte offset 0x%.2x, valid: "
				"[0-0x%.2x]\n",
				read_byte_offset, EC_SPACE_SIZE - 1);
			usage(argv[0], EXIT_FAILURE);
		}
	}
	/* Add additional parameter checks here */
}

void dump_ec(int fd)
{
	char buf[EC_SPACE_SIZE];
	char buf2[EC_SPACE_SIZE];
	int byte_off, bytes_read;

	bytes_read = read(fd, buf, EC_SPACE_SIZE);

	if (bytes_read == -1)
		err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH);

	if (bytes_read != EC_SPACE_SIZE)
		fprintf(stderr, "Could only read %d bytes\n", bytes_read);

	printf("     00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F");
	for (byte_off = 0; byte_off < bytes_read; byte_off++) {
		if ((byte_off % 16) == 0)
			printf("\n%.2X: ", byte_off);
		printf(" %.2x ", (uint8_t)buf[byte_off]);
	}
	printf("\n");

	if (!sleep_time)
		return;

	printf("\n");
	lseek(fd, 0, SEEK_SET);
	sleep(sleep_time);

	bytes_read = read(fd, buf2, EC_SPACE_SIZE);

	if (bytes_read == -1)
		err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH);

	if (bytes_read != EC_SPACE_SIZE)
		fprintf(stderr, "Could only read %d bytes\n", bytes_read);

	printf("     00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F");
	for (byte_off = 0; byte_off < bytes_read; byte_off++) {
		if ((byte_off % 16) == 0)
			printf("\n%.2X: ", byte_off);

		if (buf[byte_off] == buf2[byte_off])
			printf(" %.2x ", (uint8_t)buf2[byte_off]);
		else
			printf("*%.2x ", (uint8_t)buf2[byte_off]);
	}
	printf("\n");
}

void read_ec_val(int fd, int byte_offset)
{
	uint8_t buf;
	int error;

	error = lseek(fd, byte_offset, SEEK_SET);
	if (error != byte_offset)
		err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset);

	error = read(fd, &buf, 1);
	if (error != 1)
		err(EXIT_FAILURE, "Could not read byte 0x%.2x from %s\n",
		    byte_offset, SYSFS_PATH);
	printf("0x%.2x\n", buf);
	return;
}

void write_ec_val(int fd, int byte_offset, uint8_t value)
{
	int error;

	error = lseek(fd, byte_offset, SEEK_SET);
	if (error != byte_offset)
		err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset);

	error = write(fd, &value, 1);
	if (error != 1)
		err(EXIT_FAILURE, "Cannot write value 0x%.2x to offset 0x%.2x",
		    value, byte_offset);
}

int main(int argc, char *argv[])
{
	int file_mode = O_RDONLY;
	int fd;

	parse_opts(argc, argv);

	if (read_mode == 0)
		file_mode = O_WRONLY;
	else if (read_mode == 1)
		file_mode = O_RDONLY;
	else
		usage(argv[0], EXIT_FAILURE);

	fd = open(SYSFS_PATH, file_mode);
	if (fd == -1)
		err(EXIT_FAILURE, "%s", SYSFS_PATH);

	if (read_mode)
		if (read_byte_offset == -1)
			dump_ec(fd);
		else if (read_byte_offset < 0 ||
			 read_byte_offset >= EC_SPACE_SIZE)
			usage(argv[0], EXIT_FAILURE);
		else
			read_ec_val(fd, read_byte_offset);
	else
		write_ec_val(fd, write_byte_offset, write_value);
	close(fd);

	exit(EXIT_SUCCESS);
}
+8 −2
Original line number Diff line number Diff line
@@ -274,6 +274,8 @@ install-man:
	$(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1
	$(INSTALL_DATA) -D man/cpupower-frequency-set.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-set.1
	$(INSTALL_DATA) -D man/cpupower-frequency-info.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-info.1
	$(INSTALL_DATA) -D man/cpupower-idle-set.1 $(DESTDIR)${mandir}/man1/cpupower-idle-set.1
	$(INSTALL_DATA) -D man/cpupower-idle-info.1 $(DESTDIR)${mandir}/man1/cpupower-idle-info.1
	$(INSTALL_DATA) -D man/cpupower-set.1 $(DESTDIR)${mandir}/man1/cpupower-set.1
	$(INSTALL_DATA) -D man/cpupower-info.1 $(DESTDIR)${mandir}/man1/cpupower-info.1
	$(INSTALL_DATA) -D man/cpupower-monitor.1 $(DESTDIR)${mandir}/man1/cpupower-monitor.1
@@ -295,8 +297,12 @@ uninstall:
	- rm -f $(DESTDIR)${libdir}/libcpupower.*
	- rm -f $(DESTDIR)${includedir}/cpufreq.h
	- rm -f $(DESTDIR)${bindir}/utils/cpupower
	- rm -f $(DESTDIR)${mandir}/man1/cpufreq-set.1
	- rm -f $(DESTDIR)${mandir}/man1/cpufreq-info.1
	- rm -f $(DESTDIR)${mandir}/man1/cpupower.1
	- rm -f $(DESTDIR)${mandir}/man1/cpupower-frequency-set.1
	- rm -f $(DESTDIR)${mandir}/man1/cpupower-frequency-info.1
	- rm -f $(DESTDIR)${mandir}/man1/cpupower-set.1
	- rm -f $(DESTDIR)${mandir}/man1/cpupower-info.1
	- rm -f $(DESTDIR)${mandir}/man1/cpupower-monitor.1
	- for HLANG in $(LANGUAGES); do \
		rm -f $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \
	  done;
+11 −13
Original line number Diff line number Diff line
The cpufrequtils package (homepage: 
http://www.kernel.org/pub/linux/utils/kernel/cpufreq/cpufrequtils.html ) 
consists of the following elements:
The cpupower package consists of the following elements:

requirements
------------
@@ -11,10 +9,10 @@ providing cpuid.h is needed.
For both it's not explicitly checked for (yet).


libcpufreq
libcpupower
----------

"libcpufreq" is a library which offers a unified access method for userspace
"libcpupower" is a library which offers a unified access method for userspace
tools and programs to the cpufreq core and drivers in the Linux kernel. This
allows for code reduction in userspace tools, a clean implementation of
the interaction to the cpufreq core, and support for both the sysfs and proc
@@ -28,22 +26,22 @@ make
su
make install

should suffice on most systems. It builds default libcpufreq,
cpufreq-set and cpufreq-info files and installs them in /usr/lib and
/usr/bin, respectively. If you want to set up the paths differently and/or
want to configure the package to your specific needs, you need to open
"Makefile" with an editor of your choice and edit the block marked
CONFIGURATION.
should suffice on most systems. It builds libcpupower to put in
/usr/lib; cpupower, cpufreq-bench_plot.sh to put in /usr/bin; and
cpufreq-bench to put in /usr/sbin. If you want to set up the paths
differently and/or want to configure the package to your specific
needs, you need to open "Makefile" with an editor of your choice and
edit the block marked CONFIGURATION.


THANKS
------
Many thanks to Mattia Dongili who wrote the autotoolization and
libtoolization, the manpages and the italian language file for cpufrequtils;
libtoolization, the manpages and the italian language file for cpupower;
to Dave Jones for his feedback and his dump_psb tool; to Bruno Ducrot for his
powernow-k8-decode and intel_gsic tools as well as the french language file;
and to various others commenting on the previous (pre-)releases of 
cpufrequtils.
cpupower.


        Dominik Brodowski
Loading