Merge tag 'pm+acpi-3.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm into next

Pull ACPI and power management updates from Rafael Wysocki:
 "ACPICA is the leader this time (63 commits), followed by cpufreq (28
  commits), devfreq (15 commits), system suspend/hibernation (12
  commits), ACPI video and ACPI device enumeration (10 commits each).

  We have no major new features this time, but there are a few
  significant changes of how things work.  The most visible one will
  probably be that we are now going to create platform devices rather
  than PNP devices by default for ACPI device objects with _HID.  That
  was long overdue and will be really necessary to be able to use the
  same drivers for the same hardware blocks on ACPI and DT-based systems
  going forward.  We're not expecting fallout from this one (as usual),
  but it's something to watch nevertheless.

  The second change having a chance to be visible is that ACPI video
  will now default to using native backlight rather than the ACPI
  backlight interface which should generally help systems with broken
  Win8 BIOSes.  We're hoping that all problems with the native backlight
  handling that we had previously have been addressed and we are in a
  good enough shape to flip the default, but this change should be easy
  enough to revert if need be.

  In addition to that, the system suspend core has a new mechanism to
  allow runtime-suspended devices to stay suspended throughout system
  suspend/resume transitions if some extra conditions are met
  (generally, they are related to coordination within device hierarchy).
  However, enabling this feature requires cooperation from the bus type
  layer and for now it has only been implemented for the ACPI PM domain
  (used by ACPI-enumerated platform devices mostly today).

  Also, the acpidump utility that was previously shipped as a separate
  tool will now be provided by the upstream ACPICA along with the rest
  of ACPICA code, which will allow it to be more up to date and better
  supported, and we have one new cpuidle driver (ARM clps711x).

  The rest is improvements related to certain specific use cases,
  cleanups and fixes all over the place.

  Specifics:

   - ACPICA update to upstream version 20140424.  That includes a number
     of fixes and improvements related to things like GPE handling,
     table loading, headers, memory mapping and unmapping, DSDT/SSDT
     overriding, and the Unload() operator.  The acpidump utility from
     upstream ACPICA is included too.  From Bob Moore, Lv Zheng, David
     Box, David Binderman, and Colin Ian King.

   - Fixes and cleanups related to ACPI video and backlight interfaces
     from Hans de Goede.  That includes blacklist entries for some new
     machines and using native backlight by default.

   - ACPI device enumeration changes to create platform devices rather
     than PNP devices for ACPI device objects with _HID by default.  PNP
     devices will still be created for the ACPI device object with
     device IDs corresponding to real PNP devices, so that change should
     not break things left and right, and we're expecting to see more
     and more ACPI-enumerated platform devices in the future.  From
     Zhang Rui and Rafael J Wysocki.

   - Updates for the ACPI LPSS (Low-Power Subsystem) driver allowing it
     to handle system suspend/resume on Asus T100 correctly.  From
     Heikki Krogerus and Rafael J Wysocki.

   - PM core update introducing a mechanism to allow runtime-suspended
     devices to stay suspended over system suspend/resume transitions if
     certain additional conditions related to coordination within device
     hierarchy are met.  Related PM documentation update and ACPI PM
     domain support for the new feature.  From Rafael J Wysocki.

   - Fixes and improvements related to the "freeze" sleep state.  They
     affect several places including cpuidle, PM core, ACPI core, and
     the ACPI battery driver.  From Rafael J Wysocki and Zhang Rui.

   - Miscellaneous fixes and updates of the ACPI core from Aaron Lu,
     Bjørn Mork, Hanjun Guo, Lan Tianyu, and Rafael J Wysocki.

   - Fixes and cleanups for the ACPI processor and ACPI PAD (Processor
     Aggregator Device) drivers from Baoquan He, Manuel Schölling, Tony
     Camuso, and Toshi Kani.

   - System suspend/resume optimization in the ACPI battery driver from
     Lan Tianyu.

   - OPP (Operating Performance Points) subsystem updates from Chander
     Kashyap, Mark Brown, and Nishanth Menon.

   - cpufreq core fixes, updates and cleanups from Srivatsa S Bhat,
     Stratos Karafotis, and Viresh Kumar.

   - Updates, fixes and cleanups for the Tegra, powernow-k8, imx6q,
     s5pv210, nforce2, and powernv cpufreq drivers from Brian Norris,
     Jingoo Han, Paul Bolle, Philipp Zabel, Stratos Karafotis, and
     Viresh Kumar.

   - intel_pstate driver fixes and cleanups from Dirk Brandewie, Doug
     Smythies, and Stratos Karafotis.

   - Enabling the big.LITTLE cpufreq driver on arm64 from Mark Brown.

   - Fix for the cpuidle menu governor from Chander Kashyap.

   - New ARM clps711x cpuidle driver from Alexander Shiyan.

   - Hibernate core fixes and cleanups from Chen Gang, Dan Carpenter,
     Fabian Frederick, Pali Rohár, and Sebastian Capella.

   - Intel RAPL (Running Average Power Limit) driver updates from Jacob
     Pan.

   - PNP subsystem updates from Bjorn Helgaas and Fabian Frederick.

   - devfreq core updates from Chanwoo Choi and Paul Bolle.

   - devfreq updates for exynos4 and exynos5 from Chanwoo Choi and
     Bartlomiej Zolnierkiewicz.

   - turbostat tool fix from Jean Delvare.

   - cpupower tool updates from Prarit Bhargava, Ramkumar Ramachandra
     and Thomas Renninger.

   - New ACPI ec_access.c tool for poking at the EC in a safe way from
     Thomas Renninger"

* tag 'pm+acpi-3.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (187 commits)
  ACPICA: Namespace: Remove _PRP method support.
  intel_pstate: Improve initial busy calculation
  intel_pstate: add sample time scaling
  intel_pstate: Correct rounding in busy calculation
  intel_pstate: Remove C0 tracking
  PM / hibernate: fixed typo in comment
  ACPI: Fix x86 regression related to early mapping size limitation
  ACPICA: Tables: Add mechanism to control early table checksum verification.
  ACPI / scan: use platform bus type by default for _HID enumeration
  ACPI / scan: always register ACPI LPSS scan handler
  ACPI / scan: always register memory hotplug scan handler
  ACPI / scan: always register container scan handler
  ACPI / scan: Change the meaning of missing .attach() in scan handlers
  ACPI / scan: introduce platform_id device PNP type flag
  ACPI / scan: drop unsupported serial IDs from PNP ACPI scan handler ID list
  ACPI / scan: drop IDs that do not comply with the ACPI PNP ID rule
  ACPI / PNP: use device ID list for PNPACPI device enumeration
  ACPI / scan: .match() callback for ACPI scan handlers
  ACPI / battery: wakeup the system only when necessary
  power_supply: allow power supply devices registered w/o wakeup source
  ...
This commit is contained in:
Linus Torvalds
2014-06-04 08:57:16 -07:00
188 changed files with 9460 additions and 3810 deletions

View File

@@ -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
@@ -68,7 +70,8 @@ WARNINGS += $(call cc-supports,-Wstrict-prototypes)
WARNINGS += $(call cc-supports,-Wdeclaration-after-statement)
KERNEL_INCLUDE := ../../../include
CFLAGS += -D_LINUX -DDEFINE_ALTERNATE_TYPES -I$(KERNEL_INCLUDE)
ACPICA_INCLUDE := ../../../drivers/acpi/acpica
CFLAGS += -D_LINUX -I$(KERNEL_INCLUDE) -I$(ACPICA_INCLUDE)
CFLAGS += $(WARNINGS)
ifeq ($(strip $(V)),false)
@@ -92,10 +95,29 @@ endif
# --- ACPIDUMP BEGIN ---
vpath %.c \
tools/acpidump
../../../drivers/acpi/acpica\
tools/acpidump\
common\
os_specific/service_layers
CFLAGS += -DACPI_DUMP_APP -Itools/acpidump
DUMP_OBJS = \
acpidump.o
apdump.o\
apfiles.o\
apmain.o\
osunixdir.o\
osunixmap.o\
tbprint.o\
tbxfroot.o\
utbuffer.o\
utexcep.o\
utmath.o\
utstring.o\
utxferror.o\
oslinuxtbl.o\
cmfsize.o\
getopt.o
DUMP_OBJS := $(addprefix $(OUTPUT)tools/acpidump/,$(DUMP_OBJS))

View File

@@ -0,0 +1,101 @@
/******************************************************************************
*
* Module Name: cfsize - Common get file size function
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include <acpi/acpi.h>
#include "accommon.h"
#include "acapps.h"
#include <stdio.h>
#define _COMPONENT ACPI_TOOLS
ACPI_MODULE_NAME("cmfsize")
/*******************************************************************************
*
* FUNCTION: cm_get_file_size
*
* PARAMETERS: file - Open file descriptor
*
* RETURN: File Size. On error, -1 (ACPI_UINT32_MAX)
*
* DESCRIPTION: Get the size of a file. Uses seek-to-EOF. File must be open.
* Does not disturb the current file pointer. Uses perror for
* error messages.
*
******************************************************************************/
u32 cm_get_file_size(FILE * file)
{
long file_size;
long current_offset;
/* Save the current file pointer, seek to EOF to obtain file size */
current_offset = ftell(file);
if (current_offset < 0) {
goto offset_error;
}
if (fseek(file, 0, SEEK_END)) {
goto seek_error;
}
file_size = ftell(file);
if (file_size < 0) {
goto offset_error;
}
/* Restore original file pointer */
if (fseek(file, current_offset, SEEK_SET)) {
goto seek_error;
}
return ((u32)file_size);
offset_error:
perror("Could not get file offset");
return (ACPI_UINT32_MAX);
seek_error:
perror("Could not seek file");
return (ACPI_UINT32_MAX);
}

View File

@@ -0,0 +1,239 @@
/******************************************************************************
*
* Module Name: getopt
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
/*
* ACPICA getopt() implementation
*
* Option strings:
* "f" - Option has no arguments
* "f:" - Option requires an argument
* "f^" - Option has optional single-char sub-options
* "f|" - Option has required single-char sub-options
*/
#include <stdio.h>
#include <string.h>
#include <acpi/acpi.h>
#include "accommon.h"
#include "acapps.h"
#define ACPI_OPTION_ERROR(msg, badchar) \
if (acpi_gbl_opterr) {fprintf (stderr, "%s%c\n", msg, badchar);}
int acpi_gbl_opterr = 1;
int acpi_gbl_optind = 1;
int acpi_gbl_sub_opt_char = 0;
char *acpi_gbl_optarg;
static int current_char_ptr = 1;
/*******************************************************************************
*
* FUNCTION: acpi_getopt_argument
*
* PARAMETERS: argc, argv - from main
*
* RETURN: 0 if an argument was found, -1 otherwise. Sets acpi_gbl_Optarg
* to point to the next argument.
*
* DESCRIPTION: Get the next argument. Used to obtain arguments for the
* two-character options after the original call to acpi_getopt.
* Note: Either the argument starts at the next character after
* the option, or it is pointed to by the next argv entry.
* (After call to acpi_getopt, we need to backup to the previous
* argv entry).
*
******************************************************************************/
int acpi_getopt_argument(int argc, char **argv)
{
acpi_gbl_optind--;
current_char_ptr++;
if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
acpi_gbl_optarg =
&argv[acpi_gbl_optind++][(int)(current_char_ptr + 1)];
} else if (++acpi_gbl_optind >= argc) {
ACPI_OPTION_ERROR("Option requires an argument: -", 'v');
current_char_ptr = 1;
return (-1);
} else {
acpi_gbl_optarg = argv[acpi_gbl_optind++];
}
current_char_ptr = 1;
return (0);
}
/*******************************************************************************
*
* FUNCTION: acpi_getopt
*
* PARAMETERS: argc, argv - from main
* opts - options info list
*
* RETURN: Option character or EOF
*
* DESCRIPTION: Get the next option
*
******************************************************************************/
int acpi_getopt(int argc, char **argv, char *opts)
{
int current_char;
char *opts_ptr;
if (current_char_ptr == 1) {
if (acpi_gbl_optind >= argc ||
argv[acpi_gbl_optind][0] != '-' ||
argv[acpi_gbl_optind][1] == '\0') {
return (EOF);
} else if (strcmp(argv[acpi_gbl_optind], "--") == 0) {
acpi_gbl_optind++;
return (EOF);
}
}
/* Get the option */
current_char = argv[acpi_gbl_optind][current_char_ptr];
/* Make sure that the option is legal */
if (current_char == ':' ||
(opts_ptr = strchr(opts, current_char)) == NULL) {
ACPI_OPTION_ERROR("Illegal option: -", current_char);
if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
acpi_gbl_optind++;
current_char_ptr = 1;
}
return ('?');
}
/* Option requires an argument? */
if (*++opts_ptr == ':') {
if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
acpi_gbl_optarg =
&argv[acpi_gbl_optind++][(int)
(current_char_ptr + 1)];
} else if (++acpi_gbl_optind >= argc) {
ACPI_OPTION_ERROR("Option requires an argument: -",
current_char);
current_char_ptr = 1;
return ('?');
} else {
acpi_gbl_optarg = argv[acpi_gbl_optind++];
}
current_char_ptr = 1;
}
/* Option has an optional argument? */
else if (*opts_ptr == '+') {
if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
acpi_gbl_optarg =
&argv[acpi_gbl_optind++][(int)
(current_char_ptr + 1)];
} else if (++acpi_gbl_optind >= argc) {
acpi_gbl_optarg = NULL;
} else {
acpi_gbl_optarg = argv[acpi_gbl_optind++];
}
current_char_ptr = 1;
}
/* Option has optional single-char arguments? */
else if (*opts_ptr == '^') {
if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
acpi_gbl_optarg =
&argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
} else {
acpi_gbl_optarg = "^";
}
acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
acpi_gbl_optind++;
current_char_ptr = 1;
}
/* Option has a required single-char argument? */
else if (*opts_ptr == '|') {
if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
acpi_gbl_optarg =
&argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
} else {
ACPI_OPTION_ERROR
("Option requires a single-character suboption: -",
current_char);
current_char_ptr = 1;
return ('?');
}
acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
acpi_gbl_optind++;
current_char_ptr = 1;
}
/* Option with no arguments */
else {
if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
current_char_ptr = 1;
acpi_gbl_optind++;
}
acpi_gbl_optarg = NULL;
}
return (current_char);
}

View File

@@ -1,18 +1,64 @@
.TH ACPIDUMP 8
.SH NAME
acpidump \- Dump system's ACPI tables to an ASCII file.
acpidump \- dump a system's ACPI tables to an ASCII file
.SH SYNOPSIS
.ft B
.B acpidump > acpidump.out
.B acpidump
.RI [ options ]
.br
.SH DESCRIPTION
\fBacpidump \fP dumps the systems ACPI tables to an ASCII file
appropriate for attaching to a bug report.
.B acpidump
dumps the systems ACPI tables to an ASCII file appropriate for
attaching to a bug report.
Subsequently, they can be processed by utilities in the ACPICA package.
.SS Options
no options worth worrying about.
.PP
.SH EXAMPLE
.SH OPTIONS
acpidump options are as follow:
.TP
.B Options
.TP
.B \-b
Dump tables to binary files
.TP
.B \-c
Dump customized tables
.TP
.B \-h \-?
This help message
.TP
.B \-o <File>
Redirect output to file
.TP
.B \-r <Address>
Dump tables from specified RSDP
.TP
.B \-s
Print table summaries only
.TP
.B \-v
Display version information
.TP
.B \-z
Verbose mode
.TP
.B Table Options
.TP
.B \-a <Address>
Get table via a physical address
.TP
.B \-f <BinaryFile>
Get table via a binary file
.TP
.B \-n <Signature>
Get table via a name/signature
.TP
Invocation without parameters dumps all available tables
.TP
Multiple mixed instances of -a, -f, and -n are supported
.SH EXAMPLES
.nf
# acpidump > acpidump.out
@@ -50,10 +96,25 @@ ACPICA: https://acpica.org/
.ta
.nf
/dev/mem
/sys/firmware/acpi/tables/*
/sys/firmware/acpi/tables/dynamic/*
/sys/firmware/efi/systab
.fi
.PP
.SH AUTHOR
.nf
Written by Len Brown <len.brown@intel.com>
.TP
Original by:
Len Brown <len.brown@intel.com>
.TP
Written by:
Chao Guan <chao.guan@intel.com>
.TP
Updated by:
Bob Moore <robert.moore@intel.com>
Lv Zheng <lv.zheng@intel.com>
.SH SEE ALSO
\&\fIacpixtract\fR\|(8), \fIiasl\fR\|(8).
.SH COPYRIGHT
COPYRIGHT (c) 2013, Intel Corporation.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,204 @@
/******************************************************************************
*
* Module Name: osunixdir - Unix directory access interfaces
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include <acpi/acpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <fnmatch.h>
#include <ctype.h>
#include <sys/stat.h>
/*
* Allocated structure returned from os_open_directory
*/
typedef struct external_find_info {
char *dir_pathname;
DIR *dir_ptr;
char temp_buffer[256];
char *wildcard_spec;
char requested_file_type;
} external_find_info;
/*******************************************************************************
*
* FUNCTION: acpi_os_open_directory
*
* PARAMETERS: dir_pathname - Full pathname to the directory
* wildcard_spec - string of the form "*.c", etc.
*
* RETURN: A directory "handle" to be used in subsequent search operations.
* NULL returned on failure.
*
* DESCRIPTION: Open a directory in preparation for a wildcard search
*
******************************************************************************/
void *acpi_os_open_directory(char *dir_pathname,
char *wildcard_spec, char requested_file_type)
{
struct external_find_info *external_info;
DIR *dir;
/* Allocate the info struct that will be returned to the caller */
external_info = calloc(1, sizeof(struct external_find_info));
if (!external_info) {
return (NULL);
}
/* Get the directory stream */
dir = opendir(dir_pathname);
if (!dir) {
fprintf(stderr, "Cannot open directory - %s\n", dir_pathname);
free(external_info);
return (NULL);
}
/* Save the info in the return structure */
external_info->wildcard_spec = wildcard_spec;
external_info->requested_file_type = requested_file_type;
external_info->dir_pathname = dir_pathname;
external_info->dir_ptr = dir;
return (external_info);
}
/*******************************************************************************
*
* FUNCTION: acpi_os_get_next_filename
*
* PARAMETERS: dir_handle - Created via acpi_os_open_directory
*
* RETURN: Next filename matched. NULL if no more matches.
*
* DESCRIPTION: Get the next file in the directory that matches the wildcard
* specification.
*
******************************************************************************/
char *acpi_os_get_next_filename(void *dir_handle)
{
struct external_find_info *external_info = dir_handle;
struct dirent *dir_entry;
char *temp_str;
int str_len;
struct stat temp_stat;
int err;
while ((dir_entry = readdir(external_info->dir_ptr))) {
if (!fnmatch
(external_info->wildcard_spec, dir_entry->d_name, 0)) {
if (dir_entry->d_name[0] == '.') {
continue;
}
str_len = strlen(dir_entry->d_name) +
strlen(external_info->dir_pathname) + 2;
temp_str = calloc(str_len, 1);
if (!temp_str) {
fprintf(stderr,
"Could not allocate buffer for temporary string\n");
return (NULL);
}
strcpy(temp_str, external_info->dir_pathname);
strcat(temp_str, "/");
strcat(temp_str, dir_entry->d_name);
err = stat(temp_str, &temp_stat);
if (err == -1) {
fprintf(stderr,
"Cannot stat file (should not happen) - %s\n",
temp_str);
free(temp_str);
return (NULL);
}
free(temp_str);
if ((S_ISDIR(temp_stat.st_mode)
&& (external_info->requested_file_type ==
REQUEST_DIR_ONLY))
|| ((!S_ISDIR(temp_stat.st_mode)
&& external_info->requested_file_type ==
REQUEST_FILE_ONLY))) {
/* copy to a temp buffer because dir_entry struct is on the stack */
strcpy(external_info->temp_buffer,
dir_entry->d_name);
return (external_info->temp_buffer);
}
}
}
return (NULL);
}
/*******************************************************************************
*
* FUNCTION: acpi_os_close_directory
*
* PARAMETERS: dir_handle - Created via acpi_os_open_directory
*
* RETURN: None.
*
* DESCRIPTION: Close the open directory and cleanup.
*
******************************************************************************/
void acpi_os_close_directory(void *dir_handle)
{
struct external_find_info *external_info = dir_handle;
/* Close the directory and free allocations */
closedir(external_info->dir_ptr);
free(dir_handle);
}

View File

@@ -0,0 +1,151 @@
/******************************************************************************
*
* Module Name: osunixmap - Unix OSL for file mappings
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include "acpidump.h"
#include <unistd.h>
#include <sys/mman.h>
#ifdef _free_BSD
#include <sys/param.h>
#endif
#define _COMPONENT ACPI_OS_SERVICES
ACPI_MODULE_NAME("osunixmap")
#ifndef O_BINARY
#define O_BINARY 0
#endif
#ifdef _free_BSD
#define MMAP_FLAGS MAP_SHARED
#else
#define MMAP_FLAGS MAP_PRIVATE
#endif
#define SYSTEM_MEMORY "/dev/mem"
/*******************************************************************************
*
* FUNCTION: acpi_os_get_page_size
*
* PARAMETERS: None
*
* RETURN: Page size of the platform.
*
* DESCRIPTION: Obtain page size of the platform.
*
******************************************************************************/
static acpi_size acpi_os_get_page_size(void)
{
#ifdef PAGE_SIZE
return PAGE_SIZE;
#else
return sysconf(_SC_PAGESIZE);
#endif
}
/******************************************************************************
*
* FUNCTION: acpi_os_map_memory
*
* PARAMETERS: where - Physical address of memory to be mapped
* length - How much memory to map
*
* RETURN: Pointer to mapped memory. Null on error.
*
* DESCRIPTION: Map physical memory into local address space.
*
*****************************************************************************/
void *acpi_os_map_memory(acpi_physical_address where, acpi_size length)
{
u8 *mapped_memory;
acpi_physical_address offset;
acpi_size page_size;
int fd;
fd = open(SYSTEM_MEMORY, O_RDONLY | O_BINARY);
if (fd < 0) {
fprintf(stderr, "Cannot open %s\n", SYSTEM_MEMORY);
return (NULL);
}
/* Align the offset to use mmap */
page_size = acpi_os_get_page_size();
offset = where % page_size;
/* Map the table header to get the length of the full table */
mapped_memory = mmap(NULL, (length + offset), PROT_READ, MMAP_FLAGS,
fd, (where - offset));
if (mapped_memory == MAP_FAILED) {
fprintf(stderr, "Cannot map %s\n", SYSTEM_MEMORY);
close(fd);
return (NULL);
}
close(fd);
return (ACPI_CAST8(mapped_memory + offset));
}
/******************************************************************************
*
* FUNCTION: acpi_os_unmap_memory
*
* PARAMETERS: where - Logical address of memory to be unmapped
* length - How much memory to unmap
*
* RETURN: None.
*
* DESCRIPTION: Delete a previously created mapping. Where and Length must
* correspond to a previous mapping exactly.
*
*****************************************************************************/
void acpi_os_unmap_memory(void *where, acpi_size length)
{
acpi_physical_address offset;
acpi_size page_size;
page_size = acpi_os_get_page_size();
offset = (acpi_physical_address) where % page_size;
munmap((u8 *)where - offset, (length + offset));
}

View File

@@ -1,559 +0,0 @@
/*
* (c) Alexey Starikovskiy, Intel, 2005-2006.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#ifdef DEFINE_ALTERNATE_TYPES
/* hack to enable building old application with new headers -lenb */
#define acpi_fadt_descriptor acpi_table_fadt
#define acpi_rsdp_descriptor acpi_table_rsdp
#define DSDT_SIG ACPI_SIG_DSDT
#define FACS_SIG ACPI_SIG_FACS
#define FADT_SIG ACPI_SIG_FADT
#define xfirmware_ctrl Xfacs
#define firmware_ctrl facs
typedef int s32;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef long long s64;
#endif
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <dirent.h>
#include <acpi/acconfig.h>
#include <acpi/platform/acenv.h>
#include <acpi/actypes.h>
#include <acpi/actbl.h>
static inline u8 checksum(u8 * buffer, u32 length)
{
u8 sum = 0, *i = buffer;
buffer += length;
for (; i < buffer; sum += *(i++));
return sum;
}
static unsigned long psz, addr, length;
static int print, connect, skip;
static u8 select_sig[4];
static unsigned long read_efi_systab( void )
{
char buffer[80];
unsigned long addr;
FILE *f = fopen("/sys/firmware/efi/systab", "r");
if (f) {
while (fgets(buffer, 80, f)) {
if (sscanf(buffer, "ACPI20=0x%lx", &addr) == 1)
return addr;
}
fclose(f);
}
return 0;
}
static u8 *acpi_map_memory(unsigned long where, unsigned length)
{
unsigned long offset;
u8 *there;
int fd = open("/dev/mem", O_RDONLY);
if (fd < 0) {
fprintf(stderr, "acpi_os_map_memory: cannot open /dev/mem\n");
exit(1);
}
offset = where % psz;
there = mmap(NULL, length + offset, PROT_READ, MAP_PRIVATE,
fd, where - offset);
close(fd);
if (there == MAP_FAILED) return 0;
return (there + offset);
}
static void acpi_unmap_memory(u8 * there, unsigned length)
{
unsigned long offset = (unsigned long)there % psz;
munmap(there - offset, length + offset);
}
static struct acpi_table_header *acpi_map_table(unsigned long where, char *sig)
{
unsigned size;
struct acpi_table_header *tbl = (struct acpi_table_header *)
acpi_map_memory(where, sizeof(struct acpi_table_header));
if (!tbl || (sig && memcmp(sig, tbl->signature, 4))) return 0;
size = tbl->length;
acpi_unmap_memory((u8 *) tbl, sizeof(struct acpi_table_header));
return (struct acpi_table_header *)acpi_map_memory(where, size);
}
static void acpi_unmap_table(struct acpi_table_header *tbl)
{
acpi_unmap_memory((u8 *)tbl, tbl->length);
}
static struct acpi_rsdp_descriptor *acpi_scan_for_rsdp(u8 *begin, u32 length)
{
struct acpi_rsdp_descriptor *rsdp;
u8 *i, *end = begin + length;
/* Search from given start address for the requested length */
for (i = begin; i < end; i += ACPI_RSDP_SCAN_STEP) {
/* The signature and checksum must both be correct */
if (memcmp((char *)i, "RSD PTR ", 8)) continue;
rsdp = (struct acpi_rsdp_descriptor *)i;
/* Signature matches, check the appropriate checksum */
if (!checksum((u8 *) rsdp, (rsdp->revision < 2) ?
ACPI_RSDP_CHECKSUM_LENGTH :
ACPI_RSDP_XCHECKSUM_LENGTH))
/* Checksum valid, we have found a valid RSDP */
return rsdp;
}
/* Searched entire block, no RSDP was found */
return 0;
}
/*
* Output data
*/
static void acpi_show_data(int fd, u8 * data, int size)
{
char buffer[256];
int len;
int i, remain = size;
while (remain > 0) {
len = snprintf(buffer, 256, " %04x:", size - remain);
for (i = 0; i < 16 && i < remain; i++) {
len +=
snprintf(&buffer[len], 256 - len, " %02x", data[i]);
}
for (; i < 16; i++) {
len += snprintf(&buffer[len], 256 - len, " ");
}
len += snprintf(&buffer[len], 256 - len, " ");
for (i = 0; i < 16 && i < remain; i++) {
buffer[len++] = (isprint(data[i])) ? data[i] : '.';
}
buffer[len++] = '\n';
write(fd, buffer, len);
data += 16;
remain -= 16;
}
}
/*
* Output ACPI table
*/
static void acpi_show_table(int fd, struct acpi_table_header *table, unsigned long addr)
{
char buff[80];
int len = snprintf(buff, 80, "%.4s @ %p\n", table->signature, (void *)addr);
write(fd, buff, len);
acpi_show_data(fd, (u8 *) table, table->length);
buff[0] = '\n';
write(fd, buff, 1);
}
static void write_table(int fd, struct acpi_table_header *tbl, unsigned long addr)
{
static int select_done = 0;
if (!select_sig[0]) {
if (print) {
acpi_show_table(fd, tbl, addr);
} else {
write(fd, tbl, tbl->length);
}
} else if (!select_done && !memcmp(select_sig, tbl->signature, 4)) {
if (skip > 0) {
--skip;
return;
}
if (print) {
acpi_show_table(fd, tbl, addr);
} else {
write(fd, tbl, tbl->length);
}
select_done = 1;
}
}
static void acpi_dump_FADT(int fd, struct acpi_table_header *tbl, unsigned long xaddr) {
struct acpi_fadt_descriptor x;
unsigned long addr;
size_t len = sizeof(struct acpi_fadt_descriptor);
if (len > tbl->length) len = tbl->length;
memcpy(&x, tbl, len);
x.header.length = len;
if (checksum((u8 *)tbl, len)) {
fprintf(stderr, "Wrong checksum for FADT!\n");
}
if (x.header.length >= 148 && x.Xdsdt) {
addr = (unsigned long)x.Xdsdt;
if (connect) {
x.Xdsdt = lseek(fd, 0, SEEK_CUR);
}
} else if (x.header.length >= 44 && x.dsdt) {
addr = (unsigned long)x.dsdt;
if (connect) {
x.dsdt = lseek(fd, 0, SEEK_CUR);
}
} else {
fprintf(stderr, "No DSDT in FADT!\n");
goto no_dsdt;
}
tbl = acpi_map_table(addr, DSDT_SIG);
if (!tbl) goto no_dsdt;
if (checksum((u8 *)tbl, tbl->length))
fprintf(stderr, "Wrong checksum for DSDT!\n");
write_table(fd, tbl, addr);
acpi_unmap_table(tbl);
no_dsdt:
if (x.header.length >= 140 && x.xfirmware_ctrl) {
addr = (unsigned long)x.xfirmware_ctrl;
if (connect) {
x.xfirmware_ctrl = lseek(fd, 0, SEEK_CUR);
}
} else if (x.header.length >= 40 && x.firmware_ctrl) {
addr = (unsigned long)x.firmware_ctrl;
if (connect) {
x.firmware_ctrl = lseek(fd, 0, SEEK_CUR);
}
} else {
fprintf(stderr, "No FACS in FADT!\n");
goto no_facs;
}
tbl = acpi_map_table(addr, FACS_SIG);
if (!tbl) goto no_facs;
/* do not checksum FACS */
write_table(fd, tbl, addr);
acpi_unmap_table(tbl);
no_facs:
write_table(fd, (struct acpi_table_header *)&x, xaddr);
}
static int acpi_dump_SDT(int fd, struct acpi_rsdp_descriptor *rsdp)
{
struct acpi_table_header *sdt, *tbl = 0;
int xsdt = 1, i, num;
char *offset;
unsigned long addr;
if (rsdp->revision > 1 && rsdp->xsdt_physical_address) {
tbl = acpi_map_table(rsdp->xsdt_physical_address, "XSDT");
}
if (!tbl && rsdp->rsdt_physical_address) {
xsdt = 0;
tbl = acpi_map_table(rsdp->rsdt_physical_address, "RSDT");
}
if (!tbl) return 0;
sdt = malloc(tbl->length);
memcpy(sdt, tbl, tbl->length);
acpi_unmap_table(tbl);
if (checksum((u8 *)sdt, sdt->length))
fprintf(stderr, "Wrong checksum for %s!\n", (xsdt)?"XSDT":"RSDT");
num = (sdt->length - sizeof(struct acpi_table_header))/((xsdt)?sizeof(u64):sizeof(u32));
offset = (char *)sdt + sizeof(struct acpi_table_header);
for (i = 0; i < num; ++i, offset += ((xsdt) ? sizeof(u64) : sizeof(u32))) {
addr = (xsdt) ? (unsigned long)(*(u64 *)offset):
(unsigned long)(*(u32 *)offset);
if (!addr) continue;
tbl = acpi_map_table(addr, 0);
if (!tbl) continue;
if (!memcmp(tbl->signature, FADT_SIG, 4)) {
acpi_dump_FADT(fd, tbl, addr);
} else {
if (checksum((u8 *)tbl, tbl->length))
fprintf(stderr, "Wrong checksum for generic table!\n");
write_table(fd, tbl, addr);
}
acpi_unmap_table(tbl);
if (connect) {
if (xsdt)
(*(u64*)offset) = lseek(fd, 0, SEEK_CUR);
else
(*(u32*)offset) = lseek(fd, 0, SEEK_CUR);
}
}
if (xsdt) {
addr = (unsigned long)rsdp->xsdt_physical_address;
if (connect) {
rsdp->xsdt_physical_address = lseek(fd, 0, SEEK_CUR);
}
} else {
addr = (unsigned long)rsdp->rsdt_physical_address;
if (connect) {
rsdp->rsdt_physical_address = lseek(fd, 0, SEEK_CUR);
}
}
write_table(fd, sdt, addr);
free (sdt);
return 1;
}
#define DYNAMIC_SSDT "/sys/firmware/acpi/tables/dynamic"
static void acpi_dump_dynamic_SSDT(int fd)
{
struct stat file_stat;
char filename[256], *ptr;
DIR *tabledir;
struct dirent *entry;
FILE *fp;
int count, readcount, length;
struct acpi_table_header table_header, *ptable;
if (stat(DYNAMIC_SSDT, &file_stat) == -1) {
/* The directory doesn't exist */
return;
}
tabledir = opendir(DYNAMIC_SSDT);
if(!tabledir){
/*can't open the directory */
return;
}
while ((entry = readdir(tabledir)) != 0){
/* skip the file of . /.. */
if (entry->d_name[0] == '.')
continue;
sprintf(filename, "%s/%s", DYNAMIC_SSDT, entry->d_name);
fp = fopen(filename, "r");
if (fp == NULL) {
fprintf(stderr, "Can't open the file of %s\n",
filename);
continue;
}
/* Read the Table header to parse the table length */
count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp);
if (count < sizeof(table_header)) {
/* the length is lessn than ACPI table header. skip it */
fclose(fp);
continue;
}
length = table_header.length;
ptr = malloc(table_header.length);
fseek(fp, 0, SEEK_SET);
readcount = 0;
while(!feof(fp) && readcount < length) {
count = fread(ptr + readcount, 1, 256, fp);
readcount += count;
}
fclose(fp);
ptable = (struct acpi_table_header *) ptr;
if (checksum((u8 *) ptable, ptable->length))
fprintf(stderr, "Wrong checksum "
"for dynamic SSDT table!\n");
write_table(fd, ptable, 0);
free(ptr);
}
closedir(tabledir);
return;
}
static void usage(const char *progname)
{
puts("Usage:");
printf("%s [--addr 0x1234][--table DSDT][--output filename]"
"[--binary][--length 0x456][--help]\n", progname);
puts("\t--addr 0x1234 or -a 0x1234 -- look for tables at this physical address");
puts("\t--table DSDT or -t DSDT -- only dump table with DSDT signature");
puts("\t--output filename or -o filename -- redirect output from stdin to filename");
puts("\t--binary or -b -- dump data in binary form rather than in hex-dump format");
puts("\t--length 0x456 or -l 0x456 -- works only with --addr, dump physical memory"
"\n\t\tregion without trying to understand it's contents");
puts("\t--skip 2 or -s 2 -- skip 2 tables of the given name and output only 3rd one");
puts("\t--help or -h -- this help message");
exit(0);
}
static struct option long_options[] = {
{"addr", 1, 0, 0},
{"table", 1, 0, 0},
{"output", 1, 0, 0},
{"binary", 0, 0, 0},
{"length", 1, 0, 0},
{"skip", 1, 0, 0},
{"help", 0, 0, 0},
{0, 0, 0, 0}
};
int main(int argc, char **argv)
{
int option_index, c, fd;
u8 *raw;
struct acpi_rsdp_descriptor rsdpx, *x = 0;
char *filename = 0;
char buff[80];
memset(select_sig, 0, 4);
print = 1;
connect = 0;
addr = length = 0;
skip = 0;
while (1) {
option_index = 0;
c = getopt_long(argc, argv, "a:t:o:bl:s:h",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0:
switch (option_index) {
case 0:
addr = strtoul(optarg, (char **)NULL, 16);
break;
case 1:
memcpy(select_sig, optarg, 4);
break;
case 2:
filename = optarg;
break;
case 3:
print = 0;
break;
case 4:
length = strtoul(optarg, (char **)NULL, 16);
break;
case 5:
skip = strtoul(optarg, (char **)NULL, 10);
break;
case 6:
usage(argv[0]);
exit(0);
}
break;
case 'a':
addr = strtoul(optarg, (char **)NULL, 16);
break;
case 't':
memcpy(select_sig, optarg, 4);
break;
case 'o':
filename = optarg;
break;
case 'b':
print = 0;
break;
case 'l':
length = strtoul(optarg, (char **)NULL, 16);
break;
case 's':
skip = strtoul(optarg, (char **)NULL, 10);
break;
case 'h':
usage(argv[0]);
exit(0);
default:
printf("Unknown option!\n");
usage(argv[0]);
exit(0);
}
}
fd = STDOUT_FILENO;
if (filename) {
fd = creat(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if (fd < 0)
return fd;
}
if (!select_sig[0] && !print) {
connect = 1;
}
psz = sysconf(_SC_PAGESIZE);
if (length && addr) {
/* We know length and address, it means we just want a memory dump */
if (!(raw = acpi_map_memory(addr, length)))
goto not_found;
write(fd, raw, length);
acpi_unmap_memory(raw, length);
close(fd);
return 0;
}
length = sizeof(struct acpi_rsdp_descriptor);
if (!addr) {
addr = read_efi_systab();
if (!addr) {
addr = ACPI_HI_RSDP_WINDOW_BASE;
length = ACPI_HI_RSDP_WINDOW_SIZE;
}
}
if (!(raw = acpi_map_memory(addr, length)) ||
!(x = acpi_scan_for_rsdp(raw, length)))
goto not_found;
/* Find RSDP and print all found tables */
memcpy(&rsdpx, x, sizeof(struct acpi_rsdp_descriptor));
acpi_unmap_memory(raw, length);
if (connect) {
lseek(fd, sizeof(struct acpi_rsdp_descriptor), SEEK_SET);
}
if (!acpi_dump_SDT(fd, &rsdpx))
goto not_found;
if (connect) {
lseek(fd, 0, SEEK_SET);
write(fd, x, (rsdpx.revision < 2) ?
ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
} else if (!select_sig[0] || !memcmp("RSD PTR ", select_sig, 4)) {
addr += (long)x - (long)raw;
length = snprintf(buff, 80, "RSD PTR @ %p\n", (void *)addr);
write(fd, buff, length);
acpi_show_data(fd, (u8 *) & rsdpx, (rsdpx.revision < 2) ?
ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
buff[0] = '\n';
write(fd, buff, 1);
}
acpi_dump_dynamic_SSDT(fd);
close(fd);
return 0;
not_found:
close(fd);
fprintf(stderr, "ACPI tables were not found. If you know location "
"of RSD PTR table (from dmesg, etc), "
"supply it with either --addr or -a option\n");
return 1;
}

View File

@@ -0,0 +1,130 @@
/******************************************************************************
*
* Module Name: acpidump.h - Include file for acpi_dump utility
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
/*
* Global variables. Defined in main.c only, externed in all other files
*/
#ifdef _DECLARE_GLOBALS
#define EXTERN
#define INIT_GLOBAL(a,b) a=b
#define DEFINE_ACPI_GLOBALS 1
#else
#define EXTERN extern
#define INIT_GLOBAL(a,b) a
#endif
#include <acpi/acpi.h>
#include "accommon.h"
#include "actables.h"
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
/* Globals */
EXTERN u8 INIT_GLOBAL(gbl_summary_mode, FALSE);
EXTERN u8 INIT_GLOBAL(gbl_verbose_mode, FALSE);
EXTERN u8 INIT_GLOBAL(gbl_binary_mode, FALSE);
EXTERN u8 INIT_GLOBAL(gbl_dump_customized_tables, FALSE);
EXTERN u8 INIT_GLOBAL(gbl_do_not_dump_xsdt, FALSE);
EXTERN FILE INIT_GLOBAL(*gbl_output_file, NULL);
EXTERN char INIT_GLOBAL(*gbl_output_filename, NULL);
EXTERN u64 INIT_GLOBAL(gbl_rsdp_base, 0);
/* Globals required for use with ACPICA modules */
#ifdef _DECLARE_GLOBALS
u8 acpi_gbl_integer_byte_width = 8;
#endif
/* Action table used to defer requested options */
struct ap_dump_action {
char *argument;
u32 to_be_done;
};
#define AP_MAX_ACTIONS 32
#define AP_DUMP_ALL_TABLES 0
#define AP_DUMP_TABLE_BY_ADDRESS 1
#define AP_DUMP_TABLE_BY_NAME 2
#define AP_DUMP_TABLE_BY_FILE 3
#define AP_MAX_ACPI_FILES 256 /* Prevent infinite loops */
/* Minimum FADT sizes for various table addresses */
#define MIN_FADT_FOR_DSDT (ACPI_FADT_OFFSET (dsdt) + sizeof (u32))
#define MIN_FADT_FOR_FACS (ACPI_FADT_OFFSET (facs) + sizeof (u32))
#define MIN_FADT_FOR_XDSDT (ACPI_FADT_OFFSET (Xdsdt) + sizeof (u64))
#define MIN_FADT_FOR_XFACS (ACPI_FADT_OFFSET (Xfacs) + sizeof (u64))
/*
* apdump - Table get/dump routines
*/
int ap_dump_table_from_file(char *pathname);
int ap_dump_table_by_name(char *signature);
int ap_dump_table_by_address(char *ascii_address);
int ap_dump_all_tables(void);
u8 ap_is_valid_header(struct acpi_table_header *table);
u8 ap_is_valid_checksum(struct acpi_table_header *table);
u32 ap_get_table_length(struct acpi_table_header *table);
/*
* apfiles - File I/O utilities
*/
int ap_open_output_file(char *pathname);
int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance);
struct acpi_table_header *ap_get_table_from_file(char *pathname,
u32 *file_size);

View File

@@ -0,0 +1,451 @@
/******************************************************************************
*
* Module Name: apdump - Dump routines for ACPI tables (acpidump)
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include "acpidump.h"
/* Local prototypes */
static int
ap_dump_table_buffer(struct acpi_table_header *table,
u32 instance, acpi_physical_address address);
/******************************************************************************
*
* FUNCTION: ap_is_valid_header
*
* PARAMETERS: table - Pointer to table to be validated
*
* RETURN: TRUE if the header appears to be valid. FALSE otherwise
*
* DESCRIPTION: Check for a valid ACPI table header
*
******************************************************************************/
u8 ap_is_valid_header(struct acpi_table_header *table)
{
if (!ACPI_VALIDATE_RSDP_SIG(table->signature)) {
/* Make sure signature is all ASCII and a valid ACPI name */
if (!acpi_ut_valid_acpi_name(table->signature)) {
fprintf(stderr,
"Table signature (0x%8.8X) is invalid\n",
*(u32 *)table->signature);
return (FALSE);
}
/* Check for minimum table length */
if (table->length < sizeof(struct acpi_table_header)) {
fprintf(stderr, "Table length (0x%8.8X) is invalid\n",
table->length);
return (FALSE);
}
}
return (TRUE);
}
/******************************************************************************
*
* FUNCTION: ap_is_valid_checksum
*
* PARAMETERS: table - Pointer to table to be validated
*
* RETURN: TRUE if the checksum appears to be valid. FALSE otherwise.
*
* DESCRIPTION: Check for a valid ACPI table checksum.
*
******************************************************************************/
u8 ap_is_valid_checksum(struct acpi_table_header *table)
{
acpi_status status;
struct acpi_table_rsdp *rsdp;
if (ACPI_VALIDATE_RSDP_SIG(table->signature)) {
/*
* Checksum for RSDP.
* Note: Other checksums are computed during the table dump.
*/
rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table);
status = acpi_tb_validate_rsdp(rsdp);
} else {
status = acpi_tb_verify_checksum(table, table->length);
}
if (ACPI_FAILURE(status)) {
fprintf(stderr, "%4.4s: Warning: wrong checksum in table\n",
table->signature);
}
return (AE_OK);
}
/******************************************************************************
*
* FUNCTION: ap_get_table_length
*
* PARAMETERS: table - Pointer to the table
*
* RETURN: Table length
*
* DESCRIPTION: Obtain table length according to table signature.
*
******************************************************************************/
u32 ap_get_table_length(struct acpi_table_header *table)
{
struct acpi_table_rsdp *rsdp;
/* Check if table is valid */
if (!ap_is_valid_header(table)) {
return (0);
}
if (ACPI_VALIDATE_RSDP_SIG(table->signature)) {
rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table);
return (rsdp->length);
}
/* Normal ACPI table */
return (table->length);
}
/******************************************************************************
*
* FUNCTION: ap_dump_table_buffer
*
* PARAMETERS: table - ACPI table to be dumped
* instance - ACPI table instance no. to be dumped
* address - Physical address of the table
*
* RETURN: None
*
* DESCRIPTION: Dump an ACPI table in standard ASCII hex format, with a
* header that is compatible with the acpi_xtract utility.
*
******************************************************************************/
static int
ap_dump_table_buffer(struct acpi_table_header *table,
u32 instance, acpi_physical_address address)
{
u32 table_length;
table_length = ap_get_table_length(table);
/* Print only the header if requested */
if (gbl_summary_mode) {
acpi_tb_print_table_header(address, table);
return (0);
}
/* Dump to binary file if requested */
if (gbl_binary_mode) {
return (ap_write_to_binary_file(table, instance));
}
/*
* Dump the table with header for use with acpixtract utility.
* Note: simplest to just always emit a 64-bit address. acpi_xtract
* utility can handle this.
*/
printf("%4.4s @ 0x%8.8X%8.8X\n", table->signature,
ACPI_FORMAT_UINT64(address));
acpi_ut_dump_buffer(ACPI_CAST_PTR(u8, table), table_length,
DB_BYTE_DISPLAY, 0);
printf("\n");
return (0);
}
/******************************************************************************
*
* FUNCTION: ap_dump_all_tables
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Get all tables from the RSDT/XSDT (or at least all of the
* tables that we can possibly get).
*
******************************************************************************/
int ap_dump_all_tables(void)
{
struct acpi_table_header *table;
u32 instance = 0;
acpi_physical_address address;
acpi_status status;
int table_status;
u32 i;
/* Get and dump all available ACPI tables */
for (i = 0; i < AP_MAX_ACPI_FILES; i++) {
status =
acpi_os_get_table_by_index(i, &table, &instance, &address);
if (ACPI_FAILURE(status)) {
/* AE_LIMIT means that no more tables are available */
if (status == AE_LIMIT) {
return (0);
} else if (i == 0) {
fprintf(stderr,
"Could not get ACPI tables, %s\n",
acpi_format_exception(status));
return (-1);
} else {
fprintf(stderr,
"Could not get ACPI table at index %u, %s\n",
i, acpi_format_exception(status));
continue;
}
}
table_status = ap_dump_table_buffer(table, instance, address);
free(table);
if (table_status) {
break;
}
}
/* Something seriously bad happened if the loop terminates here */
return (-1);
}
/******************************************************************************
*
* FUNCTION: ap_dump_table_by_address
*
* PARAMETERS: ascii_address - Address for requested ACPI table
*
* RETURN: Status
*
* DESCRIPTION: Get an ACPI table via a physical address and dump it.
*
******************************************************************************/
int ap_dump_table_by_address(char *ascii_address)
{
acpi_physical_address address;
struct acpi_table_header *table;
acpi_status status;
int table_status;
u64 long_address;
/* Convert argument to an integer physical address */
status = acpi_ut_strtoul64(ascii_address, 0, &long_address);
if (ACPI_FAILURE(status)) {
fprintf(stderr, "%s: Could not convert to a physical address\n",
ascii_address);
return (-1);
}
address = (acpi_physical_address) long_address;
status = acpi_os_get_table_by_address(address, &table);
if (ACPI_FAILURE(status)) {
fprintf(stderr, "Could not get table at 0x%8.8X%8.8X, %s\n",
ACPI_FORMAT_UINT64(address),
acpi_format_exception(status));
return (-1);
}
table_status = ap_dump_table_buffer(table, 0, address);
free(table);
return (table_status);
}
/******************************************************************************
*
* FUNCTION: ap_dump_table_by_name
*
* PARAMETERS: signature - Requested ACPI table signature
*
* RETURN: Status
*
* DESCRIPTION: Get an ACPI table via a signature and dump it. Handles
* multiple tables with the same signature (SSDTs).
*
******************************************************************************/
int ap_dump_table_by_name(char *signature)
{
char local_signature[ACPI_NAME_SIZE + 1];
u32 instance;
struct acpi_table_header *table;
acpi_physical_address address;
acpi_status status;
int table_status;
if (strlen(signature) != ACPI_NAME_SIZE) {
fprintf(stderr,
"Invalid table signature [%s]: must be exactly 4 characters\n",
signature);
return (-1);
}
/* Table signatures are expected to be uppercase */
strcpy(local_signature, signature);
acpi_ut_strupr(local_signature);
/* To be friendly, handle tables whose signatures do not match the name */
if (ACPI_COMPARE_NAME(local_signature, "FADT")) {
strcpy(local_signature, ACPI_SIG_FADT);
} else if (ACPI_COMPARE_NAME(local_signature, "MADT")) {
strcpy(local_signature, ACPI_SIG_MADT);
}
/* Dump all instances of this signature (to handle multiple SSDTs) */
for (instance = 0; instance < AP_MAX_ACPI_FILES; instance++) {
status = acpi_os_get_table_by_name(local_signature, instance,
&table, &address);
if (ACPI_FAILURE(status)) {
/* AE_LIMIT means that no more tables are available */
if (status == AE_LIMIT) {
return (0);
}
fprintf(stderr,
"Could not get ACPI table with signature [%s], %s\n",
local_signature, acpi_format_exception(status));
return (-1);
}
table_status = ap_dump_table_buffer(table, instance, address);
free(table);
if (table_status) {
break;
}
}
/* Something seriously bad happened if the loop terminates here */
return (-1);
}
/******************************************************************************
*
* FUNCTION: ap_dump_table_from_file
*
* PARAMETERS: pathname - File containing the binary ACPI table
*
* RETURN: Status
*
* DESCRIPTION: Dump an ACPI table from a binary file
*
******************************************************************************/
int ap_dump_table_from_file(char *pathname)
{
struct acpi_table_header *table;
u32 file_size = 0;
int table_status = -1;
/* Get the entire ACPI table from the file */
table = ap_get_table_from_file(pathname, &file_size);
if (!table) {
return (-1);
}
/* File must be at least as long as the table length */
if (table->length > file_size) {
fprintf(stderr,
"Table length (0x%X) is too large for input file (0x%X) %s\n",
table->length, file_size, pathname);
goto exit;
}
if (gbl_verbose_mode) {
fprintf(stderr,
"Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n",
pathname, table->signature, file_size, file_size);
}
table_status = ap_dump_table_buffer(table, 0, 0);
exit:
free(table);
return (table_status);
}
/******************************************************************************
*
* FUNCTION: acpi_os* print functions
*
* DESCRIPTION: Used for linkage with ACPICA modules
*
******************************************************************************/
void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stdout, fmt, args);
va_end(args);
}
void acpi_os_vprintf(const char *fmt, va_list args)
{
vfprintf(stdout, fmt, args);
}

View File

@@ -0,0 +1,228 @@
/******************************************************************************
*
* Module Name: apfiles - File-related functions for acpidump utility
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include "acpidump.h"
#include "acapps.h"
/******************************************************************************
*
* FUNCTION: ap_open_output_file
*
* PARAMETERS: pathname - Output filename
*
* RETURN: Open file handle
*
* DESCRIPTION: Open a text output file for acpidump. Checks if file already
* exists.
*
******************************************************************************/
int ap_open_output_file(char *pathname)
{
struct stat stat_info;
FILE *file;
/* If file exists, prompt for overwrite */
if (!stat(pathname, &stat_info)) {
fprintf(stderr,
"Target path already exists, overwrite? [y|n] ");
if (getchar() != 'y') {
return (-1);
}
}
/* Point stdout to the file */
file = freopen(pathname, "w", stdout);
if (!file) {
perror("Could not open output file");
return (-1);
}
/* Save the file and path */
gbl_output_file = file;
gbl_output_filename = pathname;
return (0);
}
/******************************************************************************
*
* FUNCTION: ap_write_to_binary_file
*
* PARAMETERS: table - ACPI table to be written
* instance - ACPI table instance no. to be written
*
* RETURN: Status
*
* DESCRIPTION: Write an ACPI table to a binary file. Builds the output
* filename from the table signature.
*
******************************************************************************/
int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)
{
char filename[ACPI_NAME_SIZE + 16];
char instance_str[16];
FILE *file;
size_t actual;
u32 table_length;
/* Obtain table length */
table_length = ap_get_table_length(table);
/* Construct lower-case filename from the table local signature */
if (ACPI_VALIDATE_RSDP_SIG(table->signature)) {
ACPI_MOVE_NAME(filename, ACPI_RSDP_NAME);
} else {
ACPI_MOVE_NAME(filename, table->signature);
}
filename[0] = (char)ACPI_TOLOWER(filename[0]);
filename[1] = (char)ACPI_TOLOWER(filename[1]);
filename[2] = (char)ACPI_TOLOWER(filename[2]);
filename[3] = (char)ACPI_TOLOWER(filename[3]);
filename[ACPI_NAME_SIZE] = 0;
/* Handle multiple SSDts - create different filenames for each */
if (instance > 0) {
sprintf(instance_str, "%u", instance);
strcat(filename, instance_str);
}
strcat(filename, ACPI_TABLE_FILE_SUFFIX);
if (gbl_verbose_mode) {
fprintf(stderr,
"Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n",
table->signature, filename, table->length,
table->length);
}
/* Open the file and dump the entire table in binary mode */
file = fopen(filename, "wb");
if (!file) {
perror("Could not open output file");
return (-1);
}
actual = fwrite(table, 1, table_length, file);
if (actual != table_length) {
perror("Error writing binary output file");
fclose(file);
return (-1);
}
fclose(file);
return (0);
}
/******************************************************************************
*
* FUNCTION: ap_get_table_from_file
*
* PARAMETERS: pathname - File containing the binary ACPI table
* out_file_size - Where the file size is returned
*
* RETURN: Buffer containing the ACPI table. NULL on error.
*
* DESCRIPTION: Open a file and read it entirely into a new buffer
*
******************************************************************************/
struct acpi_table_header *ap_get_table_from_file(char *pathname,
u32 *out_file_size)
{
struct acpi_table_header *buffer = NULL;
FILE *file;
u32 file_size;
size_t actual;
/* Must use binary mode */
file = fopen(pathname, "rb");
if (!file) {
perror("Could not open input file");
return (NULL);
}
/* Need file size to allocate a buffer */
file_size = cm_get_file_size(file);
if (file_size == ACPI_UINT32_MAX) {
fprintf(stderr,
"Could not get input file size: %s\n", pathname);
goto cleanup;
}
/* Allocate a buffer for the entire file */
buffer = calloc(1, file_size);
if (!buffer) {
fprintf(stderr,
"Could not allocate file buffer of size: %u\n",
file_size);
goto cleanup;
}
/* Read the entire file */
actual = fread(buffer, 1, file_size, file);
if (actual != file_size) {
fprintf(stderr, "Could not read input file: %s\n", pathname);
free(buffer);
buffer = NULL;
goto cleanup;
}
*out_file_size = file_size;
cleanup:
fclose(file);
return (buffer);
}

View File

@@ -0,0 +1,351 @@
/******************************************************************************
*
* Module Name: apmain - Main module for the acpidump utility
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#define _DECLARE_GLOBALS
#include "acpidump.h"
#include "acapps.h"
/*
* acpidump - A portable utility for obtaining system ACPI tables and dumping
* them in an ASCII hex format suitable for binary extraction via acpixtract.
*
* Obtaining the system ACPI tables is an OS-specific operation.
*
* This utility can be ported to any host operating system by providing a
* module containing system-specific versions of these interfaces:
*
* acpi_os_get_table_by_address
* acpi_os_get_table_by_index
* acpi_os_get_table_by_name
*
* See the ACPICA Reference Guide for the exact definitions of these
* interfaces. Also, see these ACPICA source code modules for example
* implementations:
*
* source/os_specific/service_layers/oswintbl.c
* source/os_specific/service_layers/oslinuxtbl.c
*/
/* Local prototypes */
static void ap_display_usage(void);
static int ap_do_options(int argc, char **argv);
static void ap_insert_action(char *argument, u32 to_be_done);
/* Table for deferred actions from command line options */
struct ap_dump_action action_table[AP_MAX_ACTIONS];
u32 current_action = 0;
#define AP_UTILITY_NAME "ACPI Binary Table Dump Utility"
#define AP_SUPPORTED_OPTIONS "?a:bcf:hn:o:r:svxz"
/******************************************************************************
*
* FUNCTION: ap_display_usage
*
* DESCRIPTION: Usage message for the acpi_dump utility
*
******************************************************************************/
static void ap_display_usage(void)
{
ACPI_USAGE_HEADER("acpidump [options]");
ACPI_OPTION("-b", "Dump tables to binary files");
ACPI_OPTION("-c", "Dump customized tables");
ACPI_OPTION("-h -?", "This help message");
ACPI_OPTION("-o <File>", "Redirect output to file");
ACPI_OPTION("-r <Address>", "Dump tables from specified RSDP");
ACPI_OPTION("-s", "Print table summaries only");
ACPI_OPTION("-v", "Display version information");
ACPI_OPTION("-z", "Verbose mode");
printf("\nTable Options:\n");
ACPI_OPTION("-a <Address>", "Get table via a physical address");
ACPI_OPTION("-f <BinaryFile>", "Get table via a binary file");
ACPI_OPTION("-n <Signature>", "Get table via a name/signature");
ACPI_OPTION("-x", "Do not use but dump XSDT");
ACPI_OPTION("-x -x", "Do not use or dump XSDT");
printf("\n"
"Invocation without parameters dumps all available tables\n"
"Multiple mixed instances of -a, -f, and -n are supported\n\n");
}
/******************************************************************************
*
* FUNCTION: ap_insert_action
*
* PARAMETERS: argument - Pointer to the argument for this action
* to_be_done - What to do to process this action
*
* RETURN: None. Exits program if action table becomes full.
*
* DESCRIPTION: Add an action item to the action table
*
******************************************************************************/
static void ap_insert_action(char *argument, u32 to_be_done)
{
/* Insert action and check for table overflow */
action_table[current_action].argument = argument;
action_table[current_action].to_be_done = to_be_done;
current_action++;
if (current_action > AP_MAX_ACTIONS) {
fprintf(stderr, "Too many table options (max %u)\n",
AP_MAX_ACTIONS);
exit(-1);
}
}
/******************************************************************************
*
* FUNCTION: ap_do_options
*
* PARAMETERS: argc/argv - Standard argc/argv
*
* RETURN: Status
*
* DESCRIPTION: Command line option processing. The main actions for getting
* and dumping tables are deferred via the action table.
*
*****************************************************************************/
static int ap_do_options(int argc, char **argv)
{
int j;
acpi_status status;
/* Command line options */
while ((j = acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != EOF)
switch (j) {
/*
* Global options
*/
case 'b': /* Dump all input tables to binary files */
gbl_binary_mode = TRUE;
continue;
case 'c': /* Dump customized tables */
gbl_dump_customized_tables = TRUE;
continue;
case 'h':
case '?':
ap_display_usage();
exit(0);
case 'o': /* Redirect output to a single file */
if (ap_open_output_file(acpi_gbl_optarg)) {
exit(-1);
}
continue;
case 'r': /* Dump tables from specified RSDP */
status =
acpi_ut_strtoul64(acpi_gbl_optarg, 0,
&gbl_rsdp_base);
if (ACPI_FAILURE(status)) {
fprintf(stderr,
"%s: Could not convert to a physical address\n",
acpi_gbl_optarg);
exit(-1);
}
continue;
case 's': /* Print table summaries only */
gbl_summary_mode = TRUE;
continue;
case 'x': /* Do not use XSDT */
if (!acpi_gbl_do_not_use_xsdt) {
acpi_gbl_do_not_use_xsdt = TRUE;
} else {
gbl_do_not_dump_xsdt = TRUE;
}
continue;
case 'v': /* Revision/version */
printf(ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
exit(0);
case 'z': /* Verbose mode */
gbl_verbose_mode = TRUE;
fprintf(stderr, ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
continue;
/*
* Table options
*/
case 'a': /* Get table by physical address */
ap_insert_action(acpi_gbl_optarg,
AP_DUMP_TABLE_BY_ADDRESS);
break;
case 'f': /* Get table from a file */
ap_insert_action(acpi_gbl_optarg,
AP_DUMP_TABLE_BY_FILE);
break;
case 'n': /* Get table by input name (signature) */
ap_insert_action(acpi_gbl_optarg,
AP_DUMP_TABLE_BY_NAME);
break;
default:
ap_display_usage();
exit(-1);
}
/* If there are no actions, this means "get/dump all tables" */
if (current_action == 0) {
ap_insert_action(NULL, AP_DUMP_ALL_TABLES);
}
return (0);
}
/******************************************************************************
*
* FUNCTION: main
*
* PARAMETERS: argc/argv - Standard argc/argv
*
* RETURN: Status
*
* DESCRIPTION: C main function for acpidump utility
*
******************************************************************************/
int ACPI_SYSTEM_XFACE main(int argc, char *argv[])
{
int status = 0;
struct ap_dump_action *action;
u32 file_size;
u32 i;
ACPI_DEBUG_INITIALIZE(); /* For debug version only */
/* Process command line options */
if (ap_do_options(argc, argv)) {
return (-1);
}
/* Get/dump ACPI table(s) as requested */
for (i = 0; i < current_action; i++) {
action = &action_table[i];
switch (action->to_be_done) {
case AP_DUMP_ALL_TABLES:
status = ap_dump_all_tables();
break;
case AP_DUMP_TABLE_BY_ADDRESS:
status = ap_dump_table_by_address(action->argument);
break;
case AP_DUMP_TABLE_BY_NAME:
status = ap_dump_table_by_name(action->argument);
break;
case AP_DUMP_TABLE_BY_FILE:
status = ap_dump_table_from_file(action->argument);
break;
default:
fprintf(stderr,
"Internal error, invalid action: 0x%X\n",
action->to_be_done);
return (-1);
}
if (status) {
return (status);
}
}
if (gbl_output_file) {
if (gbl_verbose_mode) {
/* Summary for the output file */
file_size = cm_get_file_size(gbl_output_file);
fprintf(stderr,
"Output file %s contains 0x%X (%u) bytes\n\n",
gbl_output_filename, file_size, file_size);
}
fclose(gbl_output_file);
}
return (status);
}

View File

@@ -0,0 +1,22 @@
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

View File

@@ -0,0 +1,238 @@
/*
* 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);
}

View File

@@ -62,7 +62,7 @@ LIB_MAJ= 0.0.0
LIB_MIN= 0
PACKAGE = cpupower
PACKAGE_BUGREPORT = cpufreq@vger.kernel.org
PACKAGE_BUGREPORT = linux-pm@vger.kernel.org
LANGUAGES = de fr it cs pt
@@ -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;

View File

@@ -1,6 +1,4 @@
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

View File

@@ -3,7 +3,6 @@ ToDos sorted by priority:
- Use bitmask functions to parse CPU topology more robust
(current implementation has issues on AMD)
- Try to read out boost states and frequencies on Intel
- Adjust README
- Somewhere saw the ability to read power consumption of
RAM from HW on Intel SandyBridge -> another monitor?
- Add another c1e debug idle monitor

View File

@@ -18,7 +18,7 @@
* 5.) if the third value, "diff_pmtmr", changes between 2. and 4., the
* TSC-based delay routine on the Linux kernel does not correctly
* handle the cpufreq transition. Please report this to
* cpufreq@vger.kernel.org
* linux-pm@vger.kernel.org
*/
#include <linux/kernel.h>

View File

@@ -50,6 +50,9 @@ Prints out information like provided by the /proc/cpufreq interface in 2.4. and
\fB\-m\fR \fB\-\-human\fR
human\-readable output for the \-f, \-w, \-s and \-y parameters.
.TP
\fB\-n\fR \fB\-\-no-rounding\fR
Output frequencies and latencies without rounding off values.
.TP
.SH "REMARKS"
.LP
By default only values of core zero are displayed. How to display settings of

View File

@@ -13,11 +13,17 @@ sleep states. This can be handy for power vs performance tuning.
.SH "OPTIONS"
.LP
.TP
\fB\-d\fR \fB\-\-disable\fR
\fB\-d\fR \fB\-\-disable\fR <STATE_NO>
Disable a specific processor sleep state.
.TP
\fB\-e\fR \fB\-\-enable\fR
\fB\-e\fR \fB\-\-enable\fR <STATE_NO>
Enable a specific processor sleep state.
.TP
\fB\-D\fR \fB\-\-disable-by-latency\fR <LATENCY>
Disable all idle states with a equal or higher latency than <LATENCY>
.TP
\fB\-E\fR \fB\-\-enable-all\fR
Enable all idle states if not enabled already.
.SH "REMARKS"
.LP

View File

@@ -3,7 +3,7 @@
cpupower\-info \- Shows processor power related kernel or hardware configurations
.SH SYNOPSIS
.ft B
.B cpupower info [ \-b ] [ \-s ] [ \-m ]
.B cpupower info [ \-b ]
.SH DESCRIPTION
\fBcpupower info \fP shows kernel configurations or processor hardware

View File

@@ -3,7 +3,7 @@
cpupower\-set \- Set processor power related kernel or hardware configurations
.SH SYNOPSIS
.ft B
.B cpupower set [ \-b VAL ] [ \-s VAL ] [ \-m VAL ]
.B cpupower set [ \-b VAL ]
.SH DESCRIPTION
@@ -55,35 +55,6 @@ Use \fBcpupower -c all info -b\fP to verify.
This options needs the msr kernel driver (CONFIG_X86_MSR) loaded.
.RE
.PP
\-\-sched\-mc, \-m [ VAL ]
.RE
\-\-sched\-smt, \-s [ VAL ]
.RS 4
\-\-sched\-mc utilizes cores in one processor package/socket first before
processes are scheduled to other processor packages/sockets.
\-\-sched\-smt utilizes thread siblings of one processor core first before
processes are scheduled to other cores.
The impact on power consumption and performance (positiv or negativ) heavily
depends on processor support for deep sleep states, frequency scaling and
frequency boost modes and their dependencies between other thread siblings
and processor cores.
Taken over from kernel documentation:
Adjust the kernel's multi-core scheduler support.
Possible values are:
.RS 2
0 - No power saving load balance (default value)
1 - Fill one thread/core/package first for long running threads
2 - Also bias task wakeups to semi-idle cpu package for power
savings
.RE
.SH "SEE ALSO"
cpupower-info(1), cpupower-monitor(1), powertop(1)

View File

@@ -82,29 +82,42 @@ static void proc_cpufreq_output(void)
}
}
static int no_rounding;
static void print_speed(unsigned long speed)
{
unsigned long tmp;
if (speed > 1000000) {
tmp = speed % 10000;
if (tmp >= 5000)
speed += 10000;
printf("%u.%02u GHz", ((unsigned int) speed/1000000),
((unsigned int) (speed%1000000)/10000));
} else if (speed > 100000) {
tmp = speed % 1000;
if (tmp >= 500)
speed += 1000;
printf("%u MHz", ((unsigned int) speed / 1000));
} else if (speed > 1000) {
tmp = speed % 100;
if (tmp >= 50)
speed += 100;
printf("%u.%01u MHz", ((unsigned int) speed/1000),
((unsigned int) (speed%1000)/100));
} else
printf("%lu kHz", speed);
if (no_rounding) {
if (speed > 1000000)
printf("%u.%06u GHz", ((unsigned int) speed/1000000),
((unsigned int) speed%1000000));
else if (speed > 100000)
printf("%u MHz", (unsigned int) speed);
else if (speed > 1000)
printf("%u.%03u MHz", ((unsigned int) speed/1000),
(unsigned int) (speed%1000));
else
printf("%lu kHz", speed);
} else {
if (speed > 1000000) {
tmp = speed%10000;
if (tmp >= 5000)
speed += 10000;
printf("%u.%02u GHz", ((unsigned int) speed/1000000),
((unsigned int) (speed%1000000)/10000));
} else if (speed > 100000) {
tmp = speed%1000;
if (tmp >= 500)
speed += 1000;
printf("%u MHz", ((unsigned int) speed/1000));
} else if (speed > 1000) {
tmp = speed%100;
if (tmp >= 50)
speed += 100;
printf("%u.%01u MHz", ((unsigned int) speed/1000),
((unsigned int) (speed%1000)/100));
}
}
return;
}
@@ -113,26 +126,38 @@ static void print_duration(unsigned long duration)
{
unsigned long tmp;
if (duration > 1000000) {
tmp = duration % 10000;
if (tmp >= 5000)
duration += 10000;
printf("%u.%02u ms", ((unsigned int) duration/1000000),
((unsigned int) (duration%1000000)/10000));
} else if (duration > 100000) {
tmp = duration % 1000;
if (tmp >= 500)
duration += 1000;
printf("%u us", ((unsigned int) duration / 1000));
} else if (duration > 1000) {
tmp = duration % 100;
if (tmp >= 50)
duration += 100;
printf("%u.%01u us", ((unsigned int) duration/1000),
((unsigned int) (duration%1000)/100));
} else
printf("%lu ns", duration);
if (no_rounding) {
if (duration > 1000000)
printf("%u.%06u ms", ((unsigned int) duration/1000000),
((unsigned int) duration%1000000));
else if (duration > 100000)
printf("%u us", ((unsigned int) duration/1000));
else if (duration > 1000)
printf("%u.%03u us", ((unsigned int) duration/1000),
((unsigned int) duration%1000));
else
printf("%lu ns", duration);
} else {
if (duration > 1000000) {
tmp = duration%10000;
if (tmp >= 5000)
duration += 10000;
printf("%u.%02u ms", ((unsigned int) duration/1000000),
((unsigned int) (duration%1000000)/10000));
} else if (duration > 100000) {
tmp = duration%1000;
if (tmp >= 500)
duration += 1000;
printf("%u us", ((unsigned int) duration / 1000));
} else if (duration > 1000) {
tmp = duration%100;
if (tmp >= 50)
duration += 100;
printf("%u.%01u us", ((unsigned int) duration/1000),
((unsigned int) (duration%1000)/100));
} else
printf("%lu ns", duration);
}
return;
}
@@ -525,6 +550,7 @@ static struct option info_opts[] = {
{ .name = "latency", .has_arg = no_argument, .flag = NULL, .val = 'y'},
{ .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'},
{ .name = "human", .has_arg = no_argument, .flag = NULL, .val = 'm'},
{ .name = "no-rounding", .has_arg = no_argument, .flag = NULL, .val = 'n'},
{ },
};
@@ -538,7 +564,8 @@ int cmd_freq_info(int argc, char **argv)
int output_param = 0;
do {
ret = getopt_long(argc, argv, "oefwldpgrasmyb", info_opts, NULL);
ret = getopt_long(argc, argv, "oefwldpgrasmybn", info_opts,
NULL);
switch (ret) {
case '?':
output_param = '?';
@@ -575,6 +602,9 @@ int cmd_freq_info(int argc, char **argv)
}
human = 1;
break;
case 'n':
no_rounding = 1;
break;
default:
fprintf(stderr, "invalid or unknown argument\n");
return EXIT_FAILURE;

View File

@@ -13,8 +13,14 @@
#include "helpers/sysfs.h"
static struct option info_opts[] = {
{ .name = "disable", .has_arg = required_argument, .flag = NULL, .val = 'd'},
{ .name = "enable", .has_arg = required_argument, .flag = NULL, .val = 'e'},
{ .name = "disable",
.has_arg = required_argument, .flag = NULL, .val = 'd'},
{ .name = "enable",
.has_arg = required_argument, .flag = NULL, .val = 'e'},
{ .name = "disable-by-latency",
.has_arg = required_argument, .flag = NULL, .val = 'D'},
{ .name = "enable-all",
.has_arg = no_argument, .flag = NULL, .val = 'E'},
{ },
};
@@ -23,11 +29,13 @@ int cmd_idle_set(int argc, char **argv)
{
extern char *optarg;
extern int optind, opterr, optopt;
int ret = 0, cont = 1, param = 0, idlestate = 0;
unsigned int cpu = 0;
int ret = 0, cont = 1, param = 0, disabled;
unsigned long long latency = 0, state_latency;
unsigned int cpu = 0, idlestate = 0, idlestates = 0;
char *endptr;
do {
ret = getopt_long(argc, argv, "d:e:", info_opts, NULL);
ret = getopt_long(argc, argv, "d:e:ED:", info_opts, NULL);
if (ret == -1)
break;
switch (ret) {
@@ -53,6 +61,27 @@ int cmd_idle_set(int argc, char **argv)
param = ret;
idlestate = atoi(optarg);
break;
case 'D':
if (param) {
param = -1;
cont = 0;
break;
}
param = ret;
latency = strtoull(optarg, &endptr, 10);
if (*endptr != '\0') {
printf(_("Bad latency value: %s\n"), optarg);
exit(EXIT_FAILURE);
}
break;
case 'E':
if (param) {
param = -1;
cont = 0;
break;
}
param = ret;
break;
case -1:
cont = 0;
break;
@@ -79,8 +108,14 @@ int cmd_idle_set(int argc, char **argv)
if (!bitmask_isbitset(cpus_chosen, cpu))
continue;
switch (param) {
if (sysfs_is_cpu_online(cpu) != 1)
continue;
idlestates = sysfs_get_idlestate_count(cpu);
if (idlestates <= 0)
continue;
switch (param) {
case 'd':
ret = sysfs_idlestate_disable(cpu, idlestate, 1);
if (ret == 0)
@@ -107,6 +142,34 @@ int cmd_idle_set(int argc, char **argv)
printf(_("Idlestate %u not enabled on CPU %u\n"),
idlestate, cpu);
break;
case 'D':
for (idlestate = 0; idlestate < idlestates; idlestate++) {
disabled = sysfs_is_idlestate_disabled
(cpu, idlestate);
state_latency = sysfs_get_idlestate_latency
(cpu, idlestate);
printf("CPU: %u - idlestate %u - state_latency: %llu - latency: %llu\n",
cpu, idlestate, state_latency, latency);
if (disabled == 1 || latency > state_latency)
continue;
ret = sysfs_idlestate_disable
(cpu, idlestate, 1);
if (ret == 0)
printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu);
}
break;
case 'E':
for (idlestate = 0; idlestate < idlestates; idlestate++) {
disabled = sysfs_is_idlestate_disabled
(cpu, idlestate);
if (disabled == 1) {
ret = sysfs_idlestate_disable
(cpu, idlestate, 0);
if (ret == 0)
printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu);
}
}
break;
default:
/* Not reachable with proper args checking */
printf(_("Invalid or unknown argument\n"));

View File

@@ -18,8 +18,6 @@
static struct option set_opts[] = {
{ .name = "perf-bias", .has_arg = optional_argument, .flag = NULL, .val = 'b'},
{ .name = "sched-mc", .has_arg = optional_argument, .flag = NULL, .val = 'm'},
{ .name = "sched-smt", .has_arg = optional_argument, .flag = NULL, .val = 's'},
{ },
};
@@ -37,8 +35,6 @@ int cmd_info(int argc, char **argv)
union {
struct {
int sched_mc:1;
int sched_smt:1;
int perf_bias:1;
};
int params;
@@ -49,23 +45,13 @@ int cmd_info(int argc, char **argv)
textdomain(PACKAGE);
/* parameter parsing */
while ((ret = getopt_long(argc, argv, "msb", set_opts, NULL)) != -1) {
while ((ret = getopt_long(argc, argv, "b", set_opts, NULL)) != -1) {
switch (ret) {
case 'b':
if (params.perf_bias)
print_wrong_arg_exit();
params.perf_bias = 1;
break;
case 'm':
if (params.sched_mc)
print_wrong_arg_exit();
params.sched_mc = 1;
break;
case 's':
if (params.sched_smt)
print_wrong_arg_exit();
params.sched_smt = 1;
break;
default:
print_wrong_arg_exit();
}
@@ -78,25 +64,6 @@ int cmd_info(int argc, char **argv)
if (bitmask_isallclear(cpus_chosen))
bitmask_setbit(cpus_chosen, 0);
if (params.sched_mc) {
ret = sysfs_get_sched("mc");
printf(_("System's multi core scheduler setting: "));
if (ret < 0)
/* if sysfs file is missing it's: errno == ENOENT */
printf(_("not supported\n"));
else
printf("%d\n", ret);
}
if (params.sched_smt) {
ret = sysfs_get_sched("smt");
printf(_("System's thread sibling scheduler setting: "));
if (ret < 0)
/* if sysfs file is missing it's: errno == ENOENT */
printf(_("not supported\n"));
else
printf("%d\n", ret);
}
/* Add more per cpu options here */
if (!params.perf_bias)
return ret;
@@ -125,11 +92,12 @@ int cmd_info(int argc, char **argv)
if (params.perf_bias) {
ret = msr_intel_get_perf_bias(cpu);
if (ret < 0) {
printf(_("Could not read perf-bias value\n"));
break;
fprintf(stderr,
_("Could not read perf-bias value[%d]\n"), ret);
exit(EXIT_FAILURE);
} else
printf(_("perf-bias: %d\n"), ret);
}
}
return ret;
return 0;
}

View File

@@ -19,8 +19,6 @@
static struct option set_opts[] = {
{ .name = "perf-bias", .has_arg = required_argument, .flag = NULL, .val = 'b'},
{ .name = "sched-mc", .has_arg = required_argument, .flag = NULL, .val = 'm'},
{ .name = "sched-smt", .has_arg = required_argument, .flag = NULL, .val = 's'},
{ },
};
@@ -38,13 +36,11 @@ int cmd_set(int argc, char **argv)
union {
struct {
int sched_mc:1;
int sched_smt:1;
int perf_bias:1;
};
int params;
} params;
int sched_mc = 0, sched_smt = 0, perf_bias = 0;
int perf_bias = 0;
int ret = 0;
setlocale(LC_ALL, "");
@@ -52,7 +48,7 @@ int cmd_set(int argc, char **argv)
params.params = 0;
/* parameter parsing */
while ((ret = getopt_long(argc, argv, "m:s:b:",
while ((ret = getopt_long(argc, argv, "b:",
set_opts, NULL)) != -1) {
switch (ret) {
case 'b':
@@ -66,28 +62,6 @@ int cmd_set(int argc, char **argv)
}
params.perf_bias = 1;
break;
case 'm':
if (params.sched_mc)
print_wrong_arg_exit();
sched_mc = atoi(optarg);
if (sched_mc < 0 || sched_mc > 2) {
printf(_("--sched-mc param out "
"of range [0-%d]\n"), 2);
print_wrong_arg_exit();
}
params.sched_mc = 1;
break;
case 's':
if (params.sched_smt)
print_wrong_arg_exit();
sched_smt = atoi(optarg);
if (sched_smt < 0 || sched_smt > 2) {
printf(_("--sched-smt param out "
"of range [0-%d]\n"), 2);
print_wrong_arg_exit();
}
params.sched_smt = 1;
break;
default:
print_wrong_arg_exit();
}
@@ -96,19 +70,6 @@ int cmd_set(int argc, char **argv)
if (!params.params)
print_wrong_arg_exit();
if (params.sched_mc) {
ret = sysfs_set_sched("mc", sched_mc);
if (ret)
fprintf(stderr, _("Error setting sched-mc %s\n"),
(ret == -ENODEV) ? "not supported" : "");
}
if (params.sched_smt) {
ret = sysfs_set_sched("smt", sched_smt);
if (ret)
fprintf(stderr, _("Error setting sched-smt %s\n"),
(ret == -ENODEV) ? "not supported" : "");
}
/* Default is: set all CPUs */
if (bitmask_isallclear(cpus_chosen))
bitmask_setall(cpus_chosen);

View File

@@ -12,6 +12,9 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include "builtin.h"
#include "helpers/helpers.h"
@@ -169,6 +172,8 @@ int main(int argc, const char *argv[])
{
const char *cmd;
unsigned int i, ret;
struct stat statbuf;
struct utsname uts;
cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
@@ -195,6 +200,15 @@ int main(int argc, const char *argv[])
get_cpu_info(0, &cpupower_cpu_info);
run_as_root = !getuid();
if (run_as_root) {
ret = uname(&uts);
if (!ret && !strcmp(uts.machine, "x86_64") &&
stat("/dev/cpu/0/msr", &statbuf) != 0) {
if (system("modprobe msr") == -1)
fprintf(stderr, _("MSR access not available.\n"));
}
}
for (i = 0; i < ARRAY_SIZE(commands); i++) {
struct cmd_struct *p = commands + i;

View File

@@ -1971,13 +1971,13 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk
if (get_msr(0, MSR_IA32_TEMPERATURE_TARGET, &msr))
goto guess;
target_c_local = (msr >> 16) & 0x7F;
target_c_local = (msr >> 16) & 0xFF;
if (verbose)
fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
cpu, msr, target_c_local);
if (target_c_local < 85 || target_c_local > 127)
if (!target_c_local)
goto guess;
tcc_activation_temp = target_c_local;