diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/power/acpi/Makefile | 16 | ||||
-rw-r--r-- | tools/power/acpi/common/getopt.c | 2 | ||||
-rw-r--r-- | tools/power/acpi/os_specific/service_layers/oslibcfs.c | 3 | ||||
-rw-r--r-- | tools/power/acpi/tools/acpidbg/Makefile | 27 | ||||
-rw-r--r-- | tools/power/acpi/tools/acpidbg/acpidbg.c | 438 | ||||
-rw-r--r-- | tools/power/acpi/tools/acpidump/apfiles.c | 13 | ||||
-rw-r--r-- | tools/power/cpupower/Makefile | 19 | ||||
-rw-r--r-- | tools/power/cpupower/bench/Makefile | 8 | ||||
-rw-r--r-- | tools/power/cpupower/utils/cpufreq-info.c | 246 | ||||
-rw-r--r-- | tools/power/cpupower/utils/cpuidle-info.c | 16 | ||||
-rw-r--r-- | tools/power/cpupower/utils/cpupower-info.c | 9 | ||||
-rw-r--r-- | tools/power/cpupower/utils/cpupower-set.c | 10 | ||||
-rw-r--r-- | tools/power/cpupower/utils/helpers/topology.c | 2 |
13 files changed, 637 insertions, 172 deletions
diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile index e882c8320135..a8bf9081512b 100644 --- a/tools/power/acpi/Makefile +++ b/tools/power/acpi/Makefile @@ -10,18 +10,18 @@ include ../../scripts/Makefile.include -all: acpidump ec -clean: acpidump_clean ec_clean -install: acpidump_install ec_install -uninstall: acpidump_uninstall ec_uninstall +all: acpidbg acpidump ec +clean: acpidbg_clean acpidump_clean ec_clean +install: acpidbg_install acpidump_install ec_install +uninstall: acpidbg_uninstall acpidump_uninstall ec_uninstall -acpidump ec: FORCE +acpidbg acpidump ec: FORCE $(call descend,tools/$@,all) -acpidump_clean ec_clean: +acpidbg_clean acpidump_clean ec_clean: $(call descend,tools/$(@:_clean=),clean) -acpidump_install ec_install: +acpidbg_install acpidump_install ec_install: $(call descend,tools/$(@:_install=),install) -acpidump_uninstall ec_uninstall: +acpidbg_uninstall acpidump_uninstall ec_uninstall: $(call descend,tools/$(@:_uninstall=),uninstall) .PHONY: FORCE diff --git a/tools/power/acpi/common/getopt.c b/tools/power/acpi/common/getopt.c index 326e826a5d20..efefe309367a 100644 --- a/tools/power/acpi/common/getopt.c +++ b/tools/power/acpi/common/getopt.c @@ -47,6 +47,7 @@ * Option strings: * "f" - Option has no arguments * "f:" - Option requires an argument + * "f+" - Option has an optional argument * "f^" - Option has optional single-char sub-options * "f|" - Option has required single-char sub-options */ @@ -85,6 +86,7 @@ static int current_char_ptr = 1; int acpi_getopt_argument(int argc, char **argv) { + acpi_gbl_optind--; current_char_ptr++; diff --git a/tools/power/acpi/os_specific/service_layers/oslibcfs.c b/tools/power/acpi/os_specific/service_layers/oslibcfs.c index b51e40a9a120..6df758302604 100644 --- a/tools/power/acpi/os_specific/service_layers/oslibcfs.c +++ b/tools/power/acpi/os_specific/service_layers/oslibcfs.c @@ -73,6 +73,7 @@ ACPI_FILE acpi_os_open_file(const char *path, u8 modes) if (modes & ACPI_FILE_WRITING) { modes_str[i++] = 'w'; } + if (modes & ACPI_FILE_BINARY) { modes_str[i++] = 'b'; } @@ -101,6 +102,7 @@ ACPI_FILE acpi_os_open_file(const char *path, u8 modes) void acpi_os_close_file(ACPI_FILE file) { + fclose(file); } @@ -202,6 +204,7 @@ acpi_status acpi_os_set_file_offset(ACPI_FILE file, long offset, u8 from) if (from == ACPI_FILE_BEGIN) { ret = fseek(file, offset, SEEK_SET); } + if (from == ACPI_FILE_END) { ret = fseek(file, offset, SEEK_END); } diff --git a/tools/power/acpi/tools/acpidbg/Makefile b/tools/power/acpi/tools/acpidbg/Makefile new file mode 100644 index 000000000000..352df4b41ae9 --- /dev/null +++ b/tools/power/acpi/tools/acpidbg/Makefile @@ -0,0 +1,27 @@ +# tools/power/acpi/tools/acpidbg/Makefile - ACPI tool Makefile +# +# Copyright (c) 2015, Intel Corporation +# Author: Lv Zheng <lv.zheng@intel.com> +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; version 2 +# of the License. + +include ../../Makefile.config + +TOOL = acpidbg +vpath %.c \ + ../../../../../drivers/acpi/acpica\ + ../../common\ + ../../os_specific/service_layers\ + . +CFLAGS += -DACPI_APPLICATION -DACPI_SINGLE_THREAD -DACPI_DEBUGGER\ + -I.\ + -I../../../../../drivers/acpi/acpica\ + -I../../../../../include +LDFLAGS += -lpthread +TOOL_OBJS = \ + acpidbg.o + +include ../../Makefile.rules diff --git a/tools/power/acpi/tools/acpidbg/acpidbg.c b/tools/power/acpi/tools/acpidbg/acpidbg.c new file mode 100644 index 000000000000..d070fccdba6d --- /dev/null +++ b/tools/power/acpi/tools/acpidbg/acpidbg.c @@ -0,0 +1,438 @@ +/* + * ACPI AML interfacing userspace utility + * + * Copyright (C) 2015, Intel Corporation + * Authors: Lv Zheng <lv.zheng@intel.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <acpi/acpi.h> + +/* Headers not included by include/acpi/platform/aclinux.h */ +#include <stdbool.h> +#include <fcntl.h> +#include <assert.h> +#include <linux/circ_buf.h> + +#define ACPI_AML_FILE "/sys/kernel/debug/acpi/acpidbg" +#define ACPI_AML_SEC_TICK 1 +#define ACPI_AML_USEC_PEEK 200 +#define ACPI_AML_BUF_SIZE 4096 + +#define ACPI_AML_BATCH_WRITE_CMD 0x00 /* Write command to kernel */ +#define ACPI_AML_BATCH_READ_LOG 0x01 /* Read log from kernel */ +#define ACPI_AML_BATCH_WRITE_LOG 0x02 /* Write log to console */ + +#define ACPI_AML_LOG_START 0x00 +#define ACPI_AML_PROMPT_START 0x01 +#define ACPI_AML_PROMPT_STOP 0x02 +#define ACPI_AML_LOG_STOP 0x03 +#define ACPI_AML_PROMPT_ROLL 0x04 + +#define ACPI_AML_INTERACTIVE 0x00 +#define ACPI_AML_BATCH 0x01 + +#define circ_count(circ) \ + (CIRC_CNT((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE)) +#define circ_count_to_end(circ) \ + (CIRC_CNT_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE)) +#define circ_space(circ) \ + (CIRC_SPACE((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE)) +#define circ_space_to_end(circ) \ + (CIRC_SPACE_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE)) + +#define acpi_aml_cmd_count() circ_count(&acpi_aml_cmd_crc) +#define acpi_aml_log_count() circ_count(&acpi_aml_log_crc) +#define acpi_aml_cmd_space() circ_space(&acpi_aml_cmd_crc) +#define acpi_aml_log_space() circ_space(&acpi_aml_log_crc) + +#define ACPI_AML_DO(_fd, _op, _buf, _ret) \ + do { \ + _ret = acpi_aml_##_op(_fd, &acpi_aml_##_buf##_crc); \ + if (_ret == 0) { \ + fprintf(stderr, \ + "%s %s pipe closed.\n", #_buf, #_op); \ + return; \ + } \ + } while (0) +#define ACPI_AML_BATCH_DO(_fd, _op, _buf, _ret) \ + do { \ + _ret = acpi_aml_##_op##_batch_##_buf(_fd, \ + &acpi_aml_##_buf##_crc); \ + if (_ret == 0) \ + return; \ + } while (0) + + +static char acpi_aml_cmd_buf[ACPI_AML_BUF_SIZE]; +static char acpi_aml_log_buf[ACPI_AML_BUF_SIZE]; +static struct circ_buf acpi_aml_cmd_crc = { + .buf = acpi_aml_cmd_buf, + .head = 0, + .tail = 0, +}; +static struct circ_buf acpi_aml_log_crc = { + .buf = acpi_aml_log_buf, + .head = 0, + .tail = 0, +}; +static const char *acpi_aml_file_path = ACPI_AML_FILE; +static unsigned long acpi_aml_mode = ACPI_AML_INTERACTIVE; +static bool acpi_aml_exit; + +static bool acpi_aml_batch_drain; +static unsigned long acpi_aml_batch_state; +static char acpi_aml_batch_prompt; +static char acpi_aml_batch_roll; +static unsigned long acpi_aml_log_state; +static char *acpi_aml_batch_cmd = NULL; +static char *acpi_aml_batch_pos = NULL; + +static int acpi_aml_set_fl(int fd, int flags) +{ + int ret; + + ret = fcntl(fd, F_GETFL, 0); + if (ret < 0) { + perror("fcntl(F_GETFL)"); + return ret; + } + flags |= ret; + ret = fcntl(fd, F_SETFL, flags); + if (ret < 0) { + perror("fcntl(F_SETFL)"); + return ret; + } + return ret; +} + +static int acpi_aml_set_fd(int fd, int maxfd, fd_set *set) +{ + if (fd > maxfd) + maxfd = fd; + FD_SET(fd, set); + return maxfd; +} + +static int acpi_aml_read(int fd, struct circ_buf *crc) +{ + char *p; + int len; + + p = &crc->buf[crc->head]; + len = circ_space_to_end(crc); + len = read(fd, p, len); + if (len < 0) + perror("read"); + else if (len > 0) + crc->head = (crc->head + len) & (ACPI_AML_BUF_SIZE - 1); + return len; +} + +static int acpi_aml_read_batch_cmd(int unused, struct circ_buf *crc) +{ + char *p; + int len; + int remained = strlen(acpi_aml_batch_pos); + + p = &crc->buf[crc->head]; + len = circ_space_to_end(crc); + if (len > remained) { + memcpy(p, acpi_aml_batch_pos, remained); + acpi_aml_batch_pos += remained; + len = remained; + } else { + memcpy(p, acpi_aml_batch_pos, len); + acpi_aml_batch_pos += len; + } + if (len > 0) + crc->head = (crc->head + len) & (ACPI_AML_BUF_SIZE - 1); + return len; +} + +static int acpi_aml_read_batch_log(int fd, struct circ_buf *crc) +{ + char *p; + int len; + int ret = 0; + + p = &crc->buf[crc->head]; + len = circ_space_to_end(crc); + while (ret < len && acpi_aml_log_state != ACPI_AML_LOG_STOP) { + if (acpi_aml_log_state == ACPI_AML_PROMPT_ROLL) { + *p = acpi_aml_batch_roll; + len = 1; + crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); + ret += 1; + acpi_aml_log_state = ACPI_AML_LOG_START; + } else { + len = read(fd, p, 1); + if (len <= 0) { + if (len < 0) + perror("read"); + ret = len; + break; + } + } + switch (acpi_aml_log_state) { + case ACPI_AML_LOG_START: + if (*p == '\n') + acpi_aml_log_state = ACPI_AML_PROMPT_START; + crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); + ret += 1; + break; + case ACPI_AML_PROMPT_START: + if (*p == ACPI_DEBUGGER_COMMAND_PROMPT || + *p == ACPI_DEBUGGER_EXECUTE_PROMPT) { + acpi_aml_batch_prompt = *p; + acpi_aml_log_state = ACPI_AML_PROMPT_STOP; + } else { + if (*p != '\n') + acpi_aml_log_state = ACPI_AML_LOG_START; + crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); + ret += 1; + } + break; + case ACPI_AML_PROMPT_STOP: + if (*p == ' ') { + acpi_aml_log_state = ACPI_AML_LOG_STOP; + acpi_aml_exit = true; + } else { + /* Roll back */ + acpi_aml_log_state = ACPI_AML_PROMPT_ROLL; + acpi_aml_batch_roll = *p; + *p = acpi_aml_batch_prompt; + crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); + ret += 1; + } + break; + default: + assert(0); + break; + } + } + return ret; +} + +static int acpi_aml_write(int fd, struct circ_buf *crc) +{ + char *p; + int len; + + p = &crc->buf[crc->tail]; + len = circ_count_to_end(crc); + len = write(fd, p, len); + if (len < 0) + perror("write"); + else if (len > 0) + crc->tail = (crc->tail + len) & (ACPI_AML_BUF_SIZE - 1); + return len; +} + +static int acpi_aml_write_batch_log(int fd, struct circ_buf *crc) +{ + char *p; + int len; + + p = &crc->buf[crc->tail]; + len = circ_count_to_end(crc); + if (!acpi_aml_batch_drain) { + len = write(fd, p, len); + if (len < 0) + perror("write"); + } + if (len > 0) + crc->tail = (crc->tail + len) & (ACPI_AML_BUF_SIZE - 1); + return len; +} + +static int acpi_aml_write_batch_cmd(int fd, struct circ_buf *crc) +{ + int len; + + len = acpi_aml_write(fd, crc); + if (circ_count_to_end(crc) == 0) + acpi_aml_batch_state = ACPI_AML_BATCH_READ_LOG; + return len; +} + +static void acpi_aml_loop(int fd) +{ + fd_set rfds; + fd_set wfds; + struct timeval tv; + int ret; + int maxfd = 0; + + if (acpi_aml_mode == ACPI_AML_BATCH) { + acpi_aml_log_state = ACPI_AML_LOG_START; + acpi_aml_batch_pos = acpi_aml_batch_cmd; + if (acpi_aml_batch_drain) + acpi_aml_batch_state = ACPI_AML_BATCH_READ_LOG; + else + acpi_aml_batch_state = ACPI_AML_BATCH_WRITE_CMD; + } + acpi_aml_exit = false; + while (!acpi_aml_exit) { + tv.tv_sec = ACPI_AML_SEC_TICK; + tv.tv_usec = 0; + FD_ZERO(&rfds); + FD_ZERO(&wfds); + + if (acpi_aml_cmd_space()) { + if (acpi_aml_mode == ACPI_AML_INTERACTIVE) + maxfd = acpi_aml_set_fd(STDIN_FILENO, maxfd, &rfds); + else if (strlen(acpi_aml_batch_pos) && + acpi_aml_batch_state == ACPI_AML_BATCH_WRITE_CMD) + ACPI_AML_BATCH_DO(STDIN_FILENO, read, cmd, ret); + } + if (acpi_aml_cmd_count() && + (acpi_aml_mode == ACPI_AML_INTERACTIVE || + acpi_aml_batch_state == ACPI_AML_BATCH_WRITE_CMD)) + maxfd = acpi_aml_set_fd(fd, maxfd, &wfds); + if (acpi_aml_log_space() && + (acpi_aml_mode == ACPI_AML_INTERACTIVE || + acpi_aml_batch_state == ACPI_AML_BATCH_READ_LOG)) + maxfd = acpi_aml_set_fd(fd, maxfd, &rfds); + if (acpi_aml_log_count()) + maxfd = acpi_aml_set_fd(STDOUT_FILENO, maxfd, &wfds); + + ret = select(maxfd+1, &rfds, &wfds, NULL, &tv); + if (ret < 0) { + perror("select"); + break; + } + if (ret > 0) { + if (FD_ISSET(STDIN_FILENO, &rfds)) + ACPI_AML_DO(STDIN_FILENO, read, cmd, ret); + if (FD_ISSET(fd, &wfds)) { + if (acpi_aml_mode == ACPI_AML_BATCH) + ACPI_AML_BATCH_DO(fd, write, cmd, ret); + else + ACPI_AML_DO(fd, write, cmd, ret); + } + if (FD_ISSET(fd, &rfds)) { + if (acpi_aml_mode == ACPI_AML_BATCH) + ACPI_AML_BATCH_DO(fd, read, log, ret); + else + ACPI_AML_DO(fd, read, log, ret); + } + if (FD_ISSET(STDOUT_FILENO, &wfds)) { + if (acpi_aml_mode == ACPI_AML_BATCH) + ACPI_AML_BATCH_DO(STDOUT_FILENO, write, log, ret); + else + ACPI_AML_DO(STDOUT_FILENO, write, log, ret); + } + } + } +} + +static bool acpi_aml_readable(int fd) +{ + fd_set rfds; + struct timeval tv; + int ret; + int maxfd = 0; + + tv.tv_sec = 0; + tv.tv_usec = ACPI_AML_USEC_PEEK; + FD_ZERO(&rfds); + maxfd = acpi_aml_set_fd(fd, maxfd, &rfds); + ret = select(maxfd+1, &rfds, NULL, NULL, &tv); + if (ret < 0) + perror("select"); + if (ret > 0 && FD_ISSET(fd, &rfds)) + return true; + return false; +} + +/* + * This is a userspace IO flush implementation, replying on the prompt + * characters and can be turned into a flush() call after kernel implements + * .flush() filesystem operation. + */ +static void acpi_aml_flush(int fd) +{ + while (acpi_aml_readable(fd)) { + acpi_aml_batch_drain = true; + acpi_aml_loop(fd); + acpi_aml_batch_drain = false; + } +} + +void usage(FILE *file, char *progname) +{ + fprintf(file, "usage: %s [-b cmd] [-f file] [-h]\n", progname); + fprintf(file, "\nOptions:\n"); + fprintf(file, " -b Specify command to be executed in batch mode\n"); + fprintf(file, " -f Specify interface file other than"); + fprintf(file, " /sys/kernel/debug/acpi/acpidbg\n"); + fprintf(file, " -h Print this help message\n"); +} + +int main(int argc, char **argv) +{ + int fd = 0; + int ch; + int len; + int ret = EXIT_SUCCESS; + + while ((ch = getopt(argc, argv, "b:f:h")) != -1) { + switch (ch) { + case 'b': + if (acpi_aml_batch_cmd) { + fprintf(stderr, "Already specify %s\n", + acpi_aml_batch_cmd); + ret = EXIT_FAILURE; + goto exit; + } + len = strlen(optarg); + acpi_aml_batch_cmd = calloc(len + 2, 1); + if (!acpi_aml_batch_cmd) { + perror("calloc"); + ret = EXIT_FAILURE; + goto exit; + } + memcpy(acpi_aml_batch_cmd, optarg, len); + acpi_aml_batch_cmd[len] = '\n'; + acpi_aml_mode = ACPI_AML_BATCH; + break; + case 'f': + acpi_aml_file_path = optarg; + break; + case 'h': + usage(stdout, argv[0]); + goto exit; + break; + case '?': + default: + usage(stderr, argv[0]); + ret = EXIT_FAILURE; + goto exit; + break; + } + } + + fd = open(acpi_aml_file_path, O_RDWR | O_NONBLOCK); + if (fd < 0) { + perror("open"); + ret = EXIT_FAILURE; + goto exit; + } + acpi_aml_set_fl(STDIN_FILENO, O_NONBLOCK); + acpi_aml_set_fl(STDOUT_FILENO, O_NONBLOCK); + + if (acpi_aml_mode == ACPI_AML_BATCH) + acpi_aml_flush(fd); + acpi_aml_loop(fd); + +exit: + if (fd < 0) + close(fd); + if (acpi_aml_batch_cmd) + free(acpi_aml_batch_cmd); + return ret; +} diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c index a1c62de42a3b..bbdf9e8e25bc 100644 --- a/tools/power/acpi/tools/acpidump/apfiles.c +++ b/tools/power/acpi/tools/acpidump/apfiles.c @@ -48,6 +48,18 @@ static int ap_is_existing_file(char *pathname); +/****************************************************************************** + * + * FUNCTION: ap_is_existing_file + * + * PARAMETERS: pathname - Output filename + * + * RETURN: 0 on success + * + * DESCRIPTION: Query for file overwrite if it already exists. + * + ******************************************************************************/ + static int ap_is_existing_file(char *pathname) { #ifndef _GNU_EFI @@ -136,6 +148,7 @@ int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance) } else { ACPI_MOVE_NAME(filename, table->signature); } + filename[0] = (char)tolower((int)filename[0]); filename[1] = (char)tolower((int)filename[1]); filename[2] = (char)tolower((int)filename[2]); diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile index 2e2ba2efa0d9..0adaf0c7c03a 100644 --- a/tools/power/cpupower/Makefile +++ b/tools/power/cpupower/Makefile @@ -47,6 +47,11 @@ NLS ?= true # cpufreq-bench benchmarking tool CPUFREQ_BENCH ?= true +# Do not build libraries, but build the code in statically +# Libraries are still built, otherwise the Makefile code would +# be rather ugly. +export STATIC ?= false + # Prefix to the directories we're installing to DESTDIR ?= @@ -161,6 +166,12 @@ ifeq ($(strip $(CPUFREQ_BENCH)),true) COMPILE_BENCH += compile-bench endif +ifeq ($(strip $(STATIC)),true) + UTIL_OBJS += $(LIB_OBJS) + UTIL_HEADERS += $(LIB_HEADERS) + UTIL_SRC += $(LIB_SRC) +endif + CFLAGS += $(WARNINGS) ifeq ($(strip $(V)),false) @@ -209,7 +220,11 @@ $(OUTPUT)%.o: %.c $(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)libcpupower.so.$(LIB_MAJ) $(ECHO) " CC " $@ +ifeq ($(strip $(STATIC)),true) + $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lrt -lpci -L$(OUTPUT) -o $@ +else $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -lrt -lpci -L$(OUTPUT) -o $@ +endif $(QUIET) $(STRIPCMD) $@ $(OUTPUT)po/$(PACKAGE).pot: $(UTIL_SRC) @@ -291,7 +306,11 @@ install-bench: @#DESTDIR must be set from outside to survive @sbindir=$(sbindir) bindir=$(bindir) docdir=$(docdir) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT) install +ifeq ($(strip $(STATIC)),true) +install: all install-tools install-man $(INSTALL_NLS) $(INSTALL_BENCH) +else install: all install-lib install-tools install-man $(INSTALL_NLS) $(INSTALL_BENCH) +endif uninstall: - rm -f $(DESTDIR)${libdir}/libcpupower.* diff --git a/tools/power/cpupower/bench/Makefile b/tools/power/cpupower/bench/Makefile index 7ec7021a29cd..d0f879b223fc 100644 --- a/tools/power/cpupower/bench/Makefile +++ b/tools/power/cpupower/bench/Makefile @@ -5,9 +5,15 @@ ifneq ($(O),) endif endif +ifeq ($(strip $(STATIC)),true) +LIBS = -L../ -L$(OUTPUT) -lm +OBJS = $(OUTPUT)main.o $(OUTPUT)parse.o $(OUTPUT)system.o $(OUTPUT)benchmark.o \ + $(OUTPUT)../lib/cpufreq.o $(OUTPUT)../lib/sysfs.o +else LIBS = -L../ -L$(OUTPUT) -lm -lcpupower - OBJS = $(OUTPUT)main.o $(OUTPUT)parse.o $(OUTPUT)system.o $(OUTPUT)benchmark.o +endif + CFLAGS += -D_GNU_SOURCE -I../lib -DDEFAULT_CONFIG_FILE=\"$(confdir)/cpufreq-bench.conf\" $(OUTPUT)%.o : %.c diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c index 0e6764330241..8f3f5bb9c74e 100644 --- a/tools/power/cpupower/utils/cpufreq-info.c +++ b/tools/power/cpupower/utils/cpufreq-info.c @@ -14,6 +14,7 @@ #include <getopt.h> #include "cpufreq.h" +#include "helpers/sysfs.h" #include "helpers/helpers.h" #include "helpers/bitmask.h" @@ -244,149 +245,21 @@ static int get_boost_mode(unsigned int cpu) return 0; } -static void debug_output_one(unsigned int cpu) -{ - char *driver; - struct cpufreq_affected_cpus *cpus; - struct cpufreq_available_frequencies *freqs; - unsigned long min, max, freq_kernel, freq_hardware; - unsigned long total_trans, latency; - unsigned long long total_time; - struct cpufreq_policy *policy; - struct cpufreq_available_governors *governors; - struct cpufreq_stats *stats; - - if (cpufreq_cpu_exists(cpu)) - return; - - freq_kernel = cpufreq_get_freq_kernel(cpu); - freq_hardware = cpufreq_get_freq_hardware(cpu); - - driver = cpufreq_get_driver(cpu); - if (!driver) { - printf(_(" no or unknown cpufreq driver is active on this CPU\n")); - } else { - printf(_(" driver: %s\n"), driver); - cpufreq_put_driver(driver); - } - - cpus = cpufreq_get_related_cpus(cpu); - if (cpus) { - printf(_(" CPUs which run at the same hardware frequency: ")); - while (cpus->next) { - printf("%d ", cpus->cpu); - cpus = cpus->next; - } - printf("%d\n", cpus->cpu); - cpufreq_put_related_cpus(cpus); - } - - cpus = cpufreq_get_affected_cpus(cpu); - if (cpus) { - printf(_(" CPUs which need to have their frequency coordinated by software: ")); - while (cpus->next) { - printf("%d ", cpus->cpu); - cpus = cpus->next; - } - printf("%d\n", cpus->cpu); - cpufreq_put_affected_cpus(cpus); - } - - latency = cpufreq_get_transition_latency(cpu); - if (latency) { - printf(_(" maximum transition latency: ")); - print_duration(latency); - printf(".\n"); - } - - if (!(cpufreq_get_hardware_limits(cpu, &min, &max))) { - printf(_(" hardware limits: ")); - print_speed(min); - printf(" - "); - print_speed(max); - printf("\n"); - } - - freqs = cpufreq_get_available_frequencies(cpu); - if (freqs) { - printf(_(" available frequency steps: ")); - while (freqs->next) { - print_speed(freqs->frequency); - printf(", "); - freqs = freqs->next; - } - print_speed(freqs->frequency); - printf("\n"); - cpufreq_put_available_frequencies(freqs); - } - - governors = cpufreq_get_available_governors(cpu); - if (governors) { - printf(_(" available cpufreq governors: ")); - while (governors->next) { - printf("%s, ", governors->governor); - governors = governors->next; - } - printf("%s\n", governors->governor); - cpufreq_put_available_governors(governors); - } - - policy = cpufreq_get_policy(cpu); - if (policy) { - printf(_(" current policy: frequency should be within ")); - print_speed(policy->min); - printf(_(" and ")); - print_speed(policy->max); - - printf(".\n "); - printf(_("The governor \"%s\" may" - " decide which speed to use\n within this range.\n"), - policy->governor); - cpufreq_put_policy(policy); - } - - if (freq_kernel || freq_hardware) { - printf(_(" current CPU frequency is ")); - if (freq_hardware) { - print_speed(freq_hardware); - printf(_(" (asserted by call to hardware)")); - } else - print_speed(freq_kernel); - printf(".\n"); - } - stats = cpufreq_get_stats(cpu, &total_time); - if (stats) { - printf(_(" cpufreq stats: ")); - while (stats) { - print_speed(stats->frequency); - printf(":%.2f%%", (100.0 * stats->time_in_state) / total_time); - stats = stats->next; - if (stats) - printf(", "); - } - cpufreq_put_stats(stats); - total_trans = cpufreq_get_transitions(cpu); - if (total_trans) - printf(" (%lu)\n", total_trans); - else - printf("\n"); - } - get_boost_mode(cpu); - -} - /* --freq / -f */ static int get_freq_kernel(unsigned int cpu, unsigned int human) { unsigned long freq = cpufreq_get_freq_kernel(cpu); - if (!freq) + printf(_(" current CPU frequency: ")); + if (!freq) { + printf(_(" Unable to call to kernel\n")); return -EINVAL; + } if (human) { print_speed(freq); - printf("\n"); } else - printf("%lu\n", freq); + printf("%lu", freq); + printf(_(" (asserted by call to kernel)\n")); return 0; } @@ -396,13 +269,16 @@ static int get_freq_kernel(unsigned int cpu, unsigned int human) static int get_freq_hardware(unsigned int cpu, unsigned int human) { unsigned long freq = cpufreq_get_freq_hardware(cpu); - if (!freq) + printf(_(" current CPU frequency: ")); + if (!freq) { + printf("Unable to call hardware\n"); return -EINVAL; + } if (human) { print_speed(freq); - printf("\n"); } else - printf("%lu\n", freq); + printf("%lu", freq); + printf(_(" (asserted by call to hardware)\n")); return 0; } @@ -411,9 +287,17 @@ static int get_freq_hardware(unsigned int cpu, unsigned int human) static int get_hardware_limits(unsigned int cpu) { unsigned long min, max; - if (cpufreq_get_hardware_limits(cpu, &min, &max)) + + printf(_(" hardware limits: ")); + if (cpufreq_get_hardware_limits(cpu, &min, &max)) { + printf(_("Not Available\n")); return -EINVAL; - printf("%lu %lu\n", min, max); + } + + print_speed(min); + printf(" - "); + print_speed(max); + printf("\n"); return 0; } @@ -422,9 +306,11 @@ static int get_hardware_limits(unsigned int cpu) static int get_driver(unsigned int cpu) { char *driver = cpufreq_get_driver(cpu); - if (!driver) + if (!driver) { + printf(_(" no or unknown cpufreq driver is active on this CPU\n")); return -EINVAL; - printf("%s\n", driver); + } + printf(" driver: %s\n", driver); cpufreq_put_driver(driver); return 0; } @@ -434,9 +320,19 @@ static int get_driver(unsigned int cpu) static int get_policy(unsigned int cpu) { struct cpufreq_policy *policy = cpufreq_get_policy(cpu); - if (!policy) + if (!policy) { + printf(_(" Unable to determine current policy\n")); return -EINVAL; - printf("%lu %lu %s\n", policy->min, policy->max, policy->governor); + } + printf(_(" current policy: frequency should be within ")); + print_speed(policy->min); + printf(_(" and ")); + print_speed(policy->max); + + printf(".\n "); + printf(_("The governor \"%s\" may decide which speed to use\n" + " within this range.\n"), + policy->governor); cpufreq_put_policy(policy); return 0; } @@ -447,8 +343,12 @@ static int get_available_governors(unsigned int cpu) { struct cpufreq_available_governors *governors = cpufreq_get_available_governors(cpu); - if (!governors) + + printf(_(" available cpufreq governors: ")); + if (!governors) { + printf(_("Not Available\n")); return -EINVAL; + } while (governors->next) { printf("%s ", governors->governor); @@ -465,8 +365,12 @@ static int get_available_governors(unsigned int cpu) static int get_affected_cpus(unsigned int cpu) { struct cpufreq_affected_cpus *cpus = cpufreq_get_affected_cpus(cpu); - if (!cpus) + + printf(_(" CPUs which need to have their frequency coordinated by software: ")); + if (!cpus) { + printf(_("Not Available\n")); return -EINVAL; + } while (cpus->next) { printf("%d ", cpus->cpu); @@ -482,8 +386,12 @@ static int get_affected_cpus(unsigned int cpu) static int get_related_cpus(unsigned int cpu) { struct cpufreq_affected_cpus *cpus = cpufreq_get_related_cpus(cpu); - if (!cpus) + + printf(_(" CPUs which run at the same hardware frequency: ")); + if (!cpus) { + printf(_("Not Available\n")); return -EINVAL; + } while (cpus->next) { printf("%d ", cpus->cpu); @@ -524,8 +432,12 @@ static int get_freq_stats(unsigned int cpu, unsigned int human) static int get_latency(unsigned int cpu, unsigned int human) { unsigned long latency = cpufreq_get_transition_latency(cpu); - if (!latency) + + printf(_(" maximum transition latency: ")); + if (!latency || latency == UINT_MAX) { + printf(_(" Cannot determine or is not supported.\n")); return -EINVAL; + } if (human) { print_duration(latency); @@ -535,6 +447,36 @@ static int get_latency(unsigned int cpu, unsigned int human) return 0; } +static void debug_output_one(unsigned int cpu) +{ + struct cpufreq_available_frequencies *freqs; + + get_driver(cpu); + get_related_cpus(cpu); + get_affected_cpus(cpu); + get_latency(cpu, 1); + get_hardware_limits(cpu); + + freqs = cpufreq_get_available_frequencies(cpu); + if (freqs) { + printf(_(" available frequency steps: ")); + while (freqs->next) { + print_speed(freqs->frequency); + printf(", "); + freqs = freqs->next; + } + print_speed(freqs->frequency); + printf("\n"); + cpufreq_put_available_frequencies(freqs); + } + + get_available_governors(cpu); + get_policy(cpu); + if (get_freq_hardware(cpu, 1) < 0) + get_freq_kernel(cpu, 1); + get_boost_mode(cpu); +} + static struct option info_opts[] = { {"debug", no_argument, NULL, 'e'}, {"boost", no_argument, NULL, 'b'}, @@ -647,11 +589,14 @@ int cmd_freq_info(int argc, char **argv) if (!bitmask_isbitset(cpus_chosen, cpu)) continue; - if (cpufreq_cpu_exists(cpu)) { - printf(_("couldn't analyze CPU %d as it doesn't seem to be present\n"), cpu); + + printf(_("analyzing CPU %d:\n"), cpu); + + if (sysfs_is_cpu_online(cpu) != 1) { + printf(_(" *is offline\n")); + printf("\n"); continue; } - printf(_("analyzing CPU %d:\n"), cpu); switch (output_param) { case 'b': @@ -693,6 +638,7 @@ int cmd_freq_info(int argc, char **argv) } if (ret) return ret; + printf("\n"); } return ret; } diff --git a/tools/power/cpupower/utils/cpuidle-info.c b/tools/power/cpupower/utils/cpuidle-info.c index 750c1d82c3f7..8bf8ab5ffa25 100644 --- a/tools/power/cpupower/utils/cpuidle-info.c +++ b/tools/power/cpupower/utils/cpuidle-info.c @@ -12,7 +12,6 @@ #include <stdlib.h> #include <string.h> #include <getopt.h> -#include <cpufreq.h> #include "helpers/helpers.h" #include "helpers/sysfs.h" @@ -25,8 +24,6 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose) unsigned int idlestates, idlestate; char *tmp; - printf(_ ("Analyzing CPU %d:\n"), cpu); - idlestates = sysfs_get_idlestate_count(cpu); if (idlestates == 0) { printf(_("CPU %u: No idle states\n"), cpu); @@ -71,7 +68,6 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose) printf(_("Duration: %llu\n"), sysfs_get_idlestate_time(cpu, idlestate)); } - printf("\n"); } static void cpuidle_general_output(void) @@ -189,10 +185,17 @@ int cmd_idle_info(int argc, char **argv) for (cpu = bitmask_first(cpus_chosen); cpu <= bitmask_last(cpus_chosen); cpu++) { - if (!bitmask_isbitset(cpus_chosen, cpu) || - cpufreq_cpu_exists(cpu)) + if (!bitmask_isbitset(cpus_chosen, cpu)) continue; + printf(_("analyzing CPU %d:\n"), cpu); + + if (sysfs_is_cpu_online(cpu) != 1) { + printf(_(" *is offline\n")); + printf("\n"); + continue; + } + switch (output_param) { case 'o': @@ -203,6 +206,7 @@ int cmd_idle_info(int argc, char **argv) cpuidle_cpu_output(cpu, verbose); break; } + printf("\n"); } return EXIT_SUCCESS; } diff --git a/tools/power/cpupower/utils/cpupower-info.c b/tools/power/cpupower/utils/cpupower-info.c index 10299f2e9d2a..c7caa8eaa6d0 100644 --- a/tools/power/cpupower/utils/cpupower-info.c +++ b/tools/power/cpupower/utils/cpupower-info.c @@ -12,7 +12,6 @@ #include <string.h> #include <getopt.h> -#include <cpufreq.h> #include "helpers/helpers.h" #include "helpers/sysfs.h" @@ -83,12 +82,16 @@ int cmd_info(int argc, char **argv) for (cpu = bitmask_first(cpus_chosen); cpu <= bitmask_last(cpus_chosen); cpu++) { - if (!bitmask_isbitset(cpus_chosen, cpu) || - cpufreq_cpu_exists(cpu)) + if (!bitmask_isbitset(cpus_chosen, cpu)) continue; printf(_("analyzing CPU %d:\n"), cpu); + if (sysfs_is_cpu_online(cpu) != 1){ + printf(_(" *is offline\n")); + continue; + } + if (params.perf_bias) { ret = msr_intel_get_perf_bias(cpu); if (ret < 0) { diff --git a/tools/power/cpupower/utils/cpupower-set.c b/tools/power/cpupower/utils/cpupower-set.c index 3e6f374f8dd7..532f46b9a335 100644 --- a/tools/power/cpupower/utils/cpupower-set.c +++ b/tools/power/cpupower/utils/cpupower-set.c @@ -12,7 +12,6 @@ #include <string.h> #include <getopt.h> -#include <cpufreq.h> #include "helpers/helpers.h" #include "helpers/sysfs.h" #include "helpers/bitmask.h" @@ -78,10 +77,15 @@ int cmd_set(int argc, char **argv) for (cpu = bitmask_first(cpus_chosen); cpu <= bitmask_last(cpus_chosen); cpu++) { - if (!bitmask_isbitset(cpus_chosen, cpu) || - cpufreq_cpu_exists(cpu)) + if (!bitmask_isbitset(cpus_chosen, cpu)) continue; + if (sysfs_is_cpu_online(cpu) != 1){ + fprintf(stderr, _("Cannot set values on CPU %d:"), cpu); + fprintf(stderr, _(" *is offline\n")); + continue; + } + if (params.perf_bias) { ret = msr_intel_set_perf_bias(cpu, perf_bias); if (ret) { diff --git a/tools/power/cpupower/utils/helpers/topology.c b/tools/power/cpupower/utils/helpers/topology.c index 9cbb7fd75171..5f9c908f4557 100644 --- a/tools/power/cpupower/utils/helpers/topology.c +++ b/tools/power/cpupower/utils/helpers/topology.c @@ -106,7 +106,7 @@ int get_cpu_topology(struct cpupower_topology *cpu_top) cpu_top->pkgs++; } } - if (!cpu_top->core_info[0].pkg == -1) + if (!(cpu_top->core_info[0].pkg == -1)) cpu_top->pkgs++; /* Intel's cores count is not consecutively numbered, there may |