aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile6
-rw-r--r--tools/lib/api/fs/debugfs.c4
-rw-r--r--tools/lib/lockdep/Makefile5
-rw-r--r--tools/lib/traceevent/event-parse.c1
-rw-r--r--tools/lib/traceevent/event-parse.h4
-rw-r--r--tools/net/bpf_dbg.c2
-rw-r--r--tools/perf/Makefile.perf2
-rw-r--r--tools/perf/arch/x86/tests/dwarf-unwind.c3
-rw-r--r--tools/perf/arch/x86/tests/regs_load.S8
-rw-r--r--tools/perf/config/Makefile46
-rw-r--r--tools/perf/tests/make2
-rw-r--r--tools/perf/util/machine.c16
-rw-r--r--tools/power/acpi/Makefile26
-rw-r--r--tools/power/acpi/common/cmfsize.c101
-rw-r--r--tools/power/acpi/common/getopt.c239
-rw-r--r--tools/power/acpi/man/acpidump.885
-rw-r--r--tools/power/acpi/os_specific/service_layers/oslinuxtbl.c1329
-rw-r--r--tools/power/acpi/os_specific/service_layers/osunixdir.c204
-rw-r--r--tools/power/acpi/os_specific/service_layers/osunixmap.c151
-rw-r--r--tools/power/acpi/tools/acpidump/acpidump.c559
-rw-r--r--tools/power/acpi/tools/acpidump/acpidump.h130
-rw-r--r--tools/power/acpi/tools/acpidump/apdump.c451
-rw-r--r--tools/power/acpi/tools/acpidump/apfiles.c228
-rw-r--r--tools/power/acpi/tools/acpidump/apmain.c351
-rw-r--r--tools/power/cpupower/Makefile12
-rw-r--r--tools/power/cpupower/README24
-rw-r--r--tools/power/cpupower/ToDo1
-rw-r--r--tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c2
-rw-r--r--tools/power/cpupower/man/cpupower-frequency-info.13
-rw-r--r--tools/power/cpupower/man/cpupower-idle-set.110
-rw-r--r--tools/power/cpupower/man/cpupower-info.12
-rw-r--r--tools/power/cpupower/man/cpupower-set.131
-rw-r--r--tools/power/cpupower/utils/cpufreq-info.c110
-rw-r--r--tools/power/cpupower/utils/cpuidle-set.c75
-rw-r--r--tools/power/cpupower/utils/cpupower-info.c42
-rw-r--r--tools/power/cpupower/utils/cpupower-set.c43
-rw-r--r--tools/power/cpupower/utils/cpupower.c14
-rw-r--r--tools/power/x86/turbostat/turbostat.c4
38 files changed, 3549 insertions, 777 deletions
diff --git a/tools/Makefile b/tools/Makefile
index bcae806b0c39..9a617adc6675 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -44,6 +44,9 @@ cpupower: FORCE
44cgroup firewire hv guest usb virtio vm net: FORCE 44cgroup firewire hv guest usb virtio vm net: FORCE
45 $(call descend,$@) 45 $(call descend,$@)
46 46
47liblockdep: FORCE
48 $(call descend,lib/lockdep)
49
47libapikfs: FORCE 50libapikfs: FORCE
48 $(call descend,lib/api) 51 $(call descend,lib/api)
49 52
@@ -91,6 +94,9 @@ cpupower_clean:
91cgroup_clean hv_clean firewire_clean lguest_clean usb_clean virtio_clean vm_clean net_clean: 94cgroup_clean hv_clean firewire_clean lguest_clean usb_clean virtio_clean vm_clean net_clean:
92 $(call descend,$(@:_clean=),clean) 95 $(call descend,$(@:_clean=),clean)
93 96
97liblockdep_clean:
98 $(call descend,lib/lockdep,clean)
99
94libapikfs_clean: 100libapikfs_clean:
95 $(call descend,lib/api,clean) 101 $(call descend,lib/api,clean)
96 102
diff --git a/tools/lib/api/fs/debugfs.c b/tools/lib/api/fs/debugfs.c
index 7c4347962353..a74fba6d7743 100644
--- a/tools/lib/api/fs/debugfs.c
+++ b/tools/lib/api/fs/debugfs.c
@@ -12,8 +12,8 @@
12char debugfs_mountpoint[PATH_MAX + 1] = "/sys/kernel/debug"; 12char debugfs_mountpoint[PATH_MAX + 1] = "/sys/kernel/debug";
13 13
14static const char * const debugfs_known_mountpoints[] = { 14static const char * const debugfs_known_mountpoints[] = {
15 "/sys/kernel/debug/", 15 "/sys/kernel/debug",
16 "/debug/", 16 "/debug",
17 0, 17 0,
18}; 18};
19 19
diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile
index cb09d3ff8f58..bba2f5253b6e 100644
--- a/tools/lib/lockdep/Makefile
+++ b/tools/lib/lockdep/Makefile
@@ -1,8 +1,7 @@
1# file format version 1# file format version
2FILE_VERSION = 1 2FILE_VERSION = 1
3 3
4MAKEFLAGS += --no-print-directory 4LIBLOCKDEP_VERSION=$(shell make --no-print-directory -sC ../../.. kernelversion)
5LIBLOCKDEP_VERSION=$(shell make -sC ../../.. kernelversion)
6 5
7# Makefiles suck: This macro sets a default value of $(2) for the 6# Makefiles suck: This macro sets a default value of $(2) for the
8# variable named by $(1), unless the variable has been set by 7# variable named by $(1), unless the variable has been set by
@@ -231,7 +230,7 @@ install_lib: all_cmd
231install: install_lib 230install: install_lib
232 231
233clean: 232clean:
234 $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d 233 $(RM) *.o *~ $(TARGETS) *.a *liblockdep*.so* $(VERSION_FILES) .*.d
235 $(RM) tags TAGS 234 $(RM) tags TAGS
236 235
237endif # skip-makefile 236endif # skip-makefile
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index baec7d887da4..b83184f2d484 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -4344,6 +4344,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
4344 format, len_arg, arg); 4344 format, len_arg, arg);
4345 trace_seq_terminate(&p); 4345 trace_seq_terminate(&p);
4346 trace_seq_puts(s, p.buffer); 4346 trace_seq_puts(s, p.buffer);
4347 trace_seq_destroy(&p);
4347 arg = arg->next; 4348 arg = arg->next;
4348 break; 4349 break;
4349 default: 4350 default:
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 791c539374c7..feab94281634 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -876,8 +876,8 @@ struct event_filter {
876struct event_filter *pevent_filter_alloc(struct pevent *pevent); 876struct event_filter *pevent_filter_alloc(struct pevent *pevent);
877 877
878/* for backward compatibility */ 878/* for backward compatibility */
879#define FILTER_NONE PEVENT_ERRNO__FILTER_NOT_FOUND 879#define FILTER_NONE PEVENT_ERRNO__NO_FILTER
880#define FILTER_NOEXIST PEVENT_ERRNO__NO_FILTER 880#define FILTER_NOEXIST PEVENT_ERRNO__FILTER_NOT_FOUND
881#define FILTER_MISS PEVENT_ERRNO__FILTER_MISS 881#define FILTER_MISS PEVENT_ERRNO__FILTER_MISS
882#define FILTER_MATCH PEVENT_ERRNO__FILTER_MATCH 882#define FILTER_MATCH PEVENT_ERRNO__FILTER_MATCH
883 883
diff --git a/tools/net/bpf_dbg.c b/tools/net/bpf_dbg.c
index bb31813e43dd..9a287bec695a 100644
--- a/tools/net/bpf_dbg.c
+++ b/tools/net/bpf_dbg.c
@@ -820,7 +820,7 @@ do_div:
820 r->A &= r->X; 820 r->A &= r->X;
821 break; 821 break;
822 case BPF_ALU_AND | BPF_K: 822 case BPF_ALU_AND | BPF_K:
823 r->A &= r->X; 823 r->A &= K;
824 break; 824 break;
825 case BPF_ALU_OR | BPF_X: 825 case BPF_ALU_OR | BPF_X:
826 r->A |= r->X; 826 r->A |= r->X;
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index e96923310d57..895edd32930c 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -589,7 +589,7 @@ $(GTK_OBJS): $(OUTPUT)%.o: %.c $(LIB_H)
589 $(QUIET_CC)$(CC) -o $@ -c -fPIC $(CFLAGS) $(GTK_CFLAGS) $< 589 $(QUIET_CC)$(CC) -o $@ -c -fPIC $(CFLAGS) $(GTK_CFLAGS) $<
590 590
591$(OUTPUT)libperf-gtk.so: $(GTK_OBJS) $(PERFLIBS) 591$(OUTPUT)libperf-gtk.so: $(GTK_OBJS) $(PERFLIBS)
592 $(QUIET_LINK)$(CC) -o $@ -shared $(ALL_LDFLAGS) $(filter %.o,$^) $(GTK_LIBS) 592 $(QUIET_LINK)$(CC) -o $@ -shared $(LDFLAGS) $(filter %.o,$^) $(GTK_LIBS)
593 593
594$(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS 594$(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
595 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \ 595 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
diff --git a/tools/perf/arch/x86/tests/dwarf-unwind.c b/tools/perf/arch/x86/tests/dwarf-unwind.c
index b602ad93ce63..83bc2385e6d3 100644
--- a/tools/perf/arch/x86/tests/dwarf-unwind.c
+++ b/tools/perf/arch/x86/tests/dwarf-unwind.c
@@ -23,9 +23,10 @@ static int sample_ustack(struct perf_sample *sample,
23 23
24 sp = (unsigned long) regs[PERF_REG_X86_SP]; 24 sp = (unsigned long) regs[PERF_REG_X86_SP];
25 25
26 map = map_groups__find(&thread->mg, MAP__FUNCTION, (u64) sp); 26 map = map_groups__find(&thread->mg, MAP__VARIABLE, (u64) sp);
27 if (!map) { 27 if (!map) {
28 pr_debug("failed to get stack map\n"); 28 pr_debug("failed to get stack map\n");
29 free(buf);
29 return -1; 30 return -1;
30 } 31 }
31 32
diff --git a/tools/perf/arch/x86/tests/regs_load.S b/tools/perf/arch/x86/tests/regs_load.S
index 99167bf644ea..60875d5c556c 100644
--- a/tools/perf/arch/x86/tests/regs_load.S
+++ b/tools/perf/arch/x86/tests/regs_load.S
@@ -1,4 +1,3 @@
1
2#include <linux/linkage.h> 1#include <linux/linkage.h>
3 2
4#define AX 0 3#define AX 0
@@ -90,3 +89,10 @@ ENTRY(perf_regs_load)
90 ret 89 ret
91ENDPROC(perf_regs_load) 90ENDPROC(perf_regs_load)
92#endif 91#endif
92
93/*
94 * We need to provide note.GNU-stack section, saying that we want
95 * NOT executable stack. Otherwise the final linking will assume that
96 * the ELF stack should not be restricted at all and set it RWX.
97 */
98.section .note.GNU-stack,"",@progbits
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index ee21fa95ebcf..802cf544202b 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -34,6 +34,14 @@ ifeq ($(ARCH),arm)
34 LIBUNWIND_LIBS = -lunwind -lunwind-arm 34 LIBUNWIND_LIBS = -lunwind -lunwind-arm
35endif 35endif
36 36
37# So far there's only x86 libdw unwind support merged in perf.
38# Disable it on all other architectures in case libdw unwind
39# support is detected in system. Add supported architectures
40# to the check.
41ifneq ($(ARCH),x86)
42 NO_LIBDW_DWARF_UNWIND := 1
43endif
44
37ifeq ($(LIBUNWIND_LIBS),) 45ifeq ($(LIBUNWIND_LIBS),)
38 NO_LIBUNWIND := 1 46 NO_LIBUNWIND := 1
39else 47else
@@ -109,6 +117,10 @@ CFLAGS += -Wall
109CFLAGS += -Wextra 117CFLAGS += -Wextra
110CFLAGS += -std=gnu99 118CFLAGS += -std=gnu99
111 119
120# Enforce a non-executable stack, as we may regress (again) in the future by
121# adding assembler files missing the .GNU-stack linker note.
122LDFLAGS += -Wl,-z,noexecstack
123
112EXTLIBS = -lelf -lpthread -lrt -lm -ldl 124EXTLIBS = -lelf -lpthread -lrt -lm -ldl
113 125
114ifneq ($(OUTPUT),) 126ifneq ($(OUTPUT),)
@@ -186,7 +198,10 @@ VF_FEATURE_TESTS = \
186 stackprotector-all \ 198 stackprotector-all \
187 timerfd \ 199 timerfd \
188 libunwind-debug-frame \ 200 libunwind-debug-frame \
189 bionic 201 bionic \
202 liberty \
203 liberty-z \
204 cplus-demangle
190 205
191# Set FEATURE_CHECK_(C|LD)FLAGS-all for all CORE_FEATURE_TESTS features. 206# Set FEATURE_CHECK_(C|LD)FLAGS-all for all CORE_FEATURE_TESTS features.
192# If in the future we need per-feature checks/flags for features not 207# If in the future we need per-feature checks/flags for features not
@@ -504,7 +519,21 @@ else
504endif 519endif
505 520
506ifeq ($(feature-libbfd), 1) 521ifeq ($(feature-libbfd), 1)
507 EXTLIBS += -lbfd -lz -liberty 522 EXTLIBS += -lbfd
523
524 # call all detections now so we get correct
525 # status in VF output
526 $(call feature_check,liberty)
527 $(call feature_check,liberty-z)
528 $(call feature_check,cplus-demangle)
529
530 ifeq ($(feature-liberty), 1)
531 EXTLIBS += -liberty
532 else
533 ifeq ($(feature-liberty-z), 1)
534 EXTLIBS += -liberty -lz
535 endif
536 endif
508endif 537endif
509 538
510ifdef NO_DEMANGLE 539ifdef NO_DEMANGLE
@@ -515,15 +544,10 @@ else
515 CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT 544 CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT
516 else 545 else
517 ifneq ($(feature-libbfd), 1) 546 ifneq ($(feature-libbfd), 1)
518 $(call feature_check,liberty) 547 ifneq ($(feature-liberty), 1)
519 ifeq ($(feature-liberty), 1) 548 ifneq ($(feature-liberty-z), 1)
520 EXTLIBS += -lbfd -liberty 549 # we dont have neither HAVE_CPLUS_DEMANGLE_SUPPORT
521 else 550 # or any of 'bfd iberty z' trinity
522 $(call feature_check,liberty-z)
523 ifeq ($(feature-liberty-z), 1)
524 EXTLIBS += -lbfd -liberty -lz
525 else
526 $(call feature_check,cplus-demangle)
527 ifeq ($(feature-cplus-demangle), 1) 551 ifeq ($(feature-cplus-demangle), 1)
528 EXTLIBS += -liberty 552 EXTLIBS += -liberty
529 CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT 553 CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 5daeae1cb4c0..2f92d6e7ee00 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -46,6 +46,7 @@ make_install_man := install-man
46make_install_html := install-html 46make_install_html := install-html
47make_install_info := install-info 47make_install_info := install-info
48make_install_pdf := install-pdf 48make_install_pdf := install-pdf
49make_static := LDFLAGS=-static
49 50
50# all the NO_* variable combined 51# all the NO_* variable combined
51make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 52make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1
@@ -87,6 +88,7 @@ run += make_install_bin
87# run += make_install_info 88# run += make_install_info
88# run += make_install_pdf 89# run += make_install_pdf
89run += make_minimal 90run += make_minimal
91run += make_static
90 92
91ifneq ($(call has,ctags),) 93ifneq ($(call has,ctags),)
92run += make_tags 94run += make_tags
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index a53cd0b8c151..27c2a5efe450 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -717,7 +717,7 @@ static char *get_kernel_version(const char *root_dir)
717} 717}
718 718
719static int map_groups__set_modules_path_dir(struct map_groups *mg, 719static int map_groups__set_modules_path_dir(struct map_groups *mg,
720 const char *dir_name) 720 const char *dir_name, int depth)
721{ 721{
722 struct dirent *dent; 722 struct dirent *dent;
723 DIR *dir = opendir(dir_name); 723 DIR *dir = opendir(dir_name);
@@ -742,7 +742,15 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg,
742 !strcmp(dent->d_name, "..")) 742 !strcmp(dent->d_name, ".."))
743 continue; 743 continue;
744 744
745 ret = map_groups__set_modules_path_dir(mg, path); 745 /* Do not follow top-level source and build symlinks */
746 if (depth == 0) {
747 if (!strcmp(dent->d_name, "source") ||
748 !strcmp(dent->d_name, "build"))
749 continue;
750 }
751
752 ret = map_groups__set_modules_path_dir(mg, path,
753 depth + 1);
746 if (ret < 0) 754 if (ret < 0)
747 goto out; 755 goto out;
748 } else { 756 } else {
@@ -786,11 +794,11 @@ static int machine__set_modules_path(struct machine *machine)
786 if (!version) 794 if (!version)
787 return -1; 795 return -1;
788 796
789 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel", 797 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s",
790 machine->root_dir, version); 798 machine->root_dir, version);
791 free(version); 799 free(version);
792 800
793 return map_groups__set_modules_path_dir(&machine->kmaps, modules_path); 801 return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0);
794} 802}
795 803
796static int machine__create_module(void *arg, const char *name, u64 start) 804static int machine__create_module(void *arg, const char *name, u64 start)
diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile
index c225d6d9fb29..e5a3c4be2a10 100644
--- a/tools/power/acpi/Makefile
+++ b/tools/power/acpi/Makefile
@@ -70,7 +70,8 @@ WARNINGS += $(call cc-supports,-Wstrict-prototypes)
70WARNINGS += $(call cc-supports,-Wdeclaration-after-statement) 70WARNINGS += $(call cc-supports,-Wdeclaration-after-statement)
71 71
72KERNEL_INCLUDE := ../../../include 72KERNEL_INCLUDE := ../../../include
73CFLAGS += -D_LINUX -DDEFINE_ALTERNATE_TYPES -I$(KERNEL_INCLUDE) 73ACPICA_INCLUDE := ../../../drivers/acpi/acpica
74CFLAGS += -D_LINUX -I$(KERNEL_INCLUDE) -I$(ACPICA_INCLUDE)
74CFLAGS += $(WARNINGS) 75CFLAGS += $(WARNINGS)
75 76
76ifeq ($(strip $(V)),false) 77ifeq ($(strip $(V)),false)
@@ -94,10 +95,29 @@ endif
94# --- ACPIDUMP BEGIN --- 95# --- ACPIDUMP BEGIN ---
95 96
96vpath %.c \ 97vpath %.c \
97 tools/acpidump 98 ../../../drivers/acpi/acpica\
99 tools/acpidump\
100 common\
101 os_specific/service_layers
102
103CFLAGS += -DACPI_DUMP_APP -Itools/acpidump
98 104
99DUMP_OBJS = \ 105DUMP_OBJS = \
100 acpidump.o 106 apdump.o\
107 apfiles.o\
108 apmain.o\
109 osunixdir.o\
110 osunixmap.o\
111 tbprint.o\
112 tbxfroot.o\
113 utbuffer.o\
114 utexcep.o\
115 utmath.o\
116 utstring.o\
117 utxferror.o\
118 oslinuxtbl.o\
119 cmfsize.o\
120 getopt.o
101 121
102DUMP_OBJS := $(addprefix $(OUTPUT)tools/acpidump/,$(DUMP_OBJS)) 122DUMP_OBJS := $(addprefix $(OUTPUT)tools/acpidump/,$(DUMP_OBJS))
103 123
diff --git a/tools/power/acpi/common/cmfsize.c b/tools/power/acpi/common/cmfsize.c
new file mode 100644
index 000000000000..5140e5edae1f
--- /dev/null
+++ b/tools/power/acpi/common/cmfsize.c
@@ -0,0 +1,101 @@
1/******************************************************************************
2 *
3 * Module Name: cfsize - Common get file size function
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acapps.h"
47#include <stdio.h>
48
49#define _COMPONENT ACPI_TOOLS
50ACPI_MODULE_NAME("cmfsize")
51
52/*******************************************************************************
53 *
54 * FUNCTION: cm_get_file_size
55 *
56 * PARAMETERS: file - Open file descriptor
57 *
58 * RETURN: File Size. On error, -1 (ACPI_UINT32_MAX)
59 *
60 * DESCRIPTION: Get the size of a file. Uses seek-to-EOF. File must be open.
61 * Does not disturb the current file pointer. Uses perror for
62 * error messages.
63 *
64 ******************************************************************************/
65u32 cm_get_file_size(FILE * file)
66{
67 long file_size;
68 long current_offset;
69
70 /* Save the current file pointer, seek to EOF to obtain file size */
71
72 current_offset = ftell(file);
73 if (current_offset < 0) {
74 goto offset_error;
75 }
76
77 if (fseek(file, 0, SEEK_END)) {
78 goto seek_error;
79 }
80
81 file_size = ftell(file);
82 if (file_size < 0) {
83 goto offset_error;
84 }
85
86 /* Restore original file pointer */
87
88 if (fseek(file, current_offset, SEEK_SET)) {
89 goto seek_error;
90 }
91
92 return ((u32)file_size);
93
94offset_error:
95 perror("Could not get file offset");
96 return (ACPI_UINT32_MAX);
97
98seek_error:
99 perror("Could not seek file");
100 return (ACPI_UINT32_MAX);
101}
diff --git a/tools/power/acpi/common/getopt.c b/tools/power/acpi/common/getopt.c
new file mode 100644
index 000000000000..a302f52e4fd3
--- /dev/null
+++ b/tools/power/acpi/common/getopt.c
@@ -0,0 +1,239 @@
1/******************************************************************************
2 *
3 * Module Name: getopt
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44/*
45 * ACPICA getopt() implementation
46 *
47 * Option strings:
48 * "f" - Option has no arguments
49 * "f:" - Option requires an argument
50 * "f^" - Option has optional single-char sub-options
51 * "f|" - Option has required single-char sub-options
52 */
53
54#include <stdio.h>
55#include <string.h>
56#include <acpi/acpi.h>
57#include "accommon.h"
58#include "acapps.h"
59
60#define ACPI_OPTION_ERROR(msg, badchar) \
61 if (acpi_gbl_opterr) {fprintf (stderr, "%s%c\n", msg, badchar);}
62
63int acpi_gbl_opterr = 1;
64int acpi_gbl_optind = 1;
65int acpi_gbl_sub_opt_char = 0;
66char *acpi_gbl_optarg;
67
68static int current_char_ptr = 1;
69
70/*******************************************************************************
71 *
72 * FUNCTION: acpi_getopt_argument
73 *
74 * PARAMETERS: argc, argv - from main
75 *
76 * RETURN: 0 if an argument was found, -1 otherwise. Sets acpi_gbl_Optarg
77 * to point to the next argument.
78 *
79 * DESCRIPTION: Get the next argument. Used to obtain arguments for the
80 * two-character options after the original call to acpi_getopt.
81 * Note: Either the argument starts at the next character after
82 * the option, or it is pointed to by the next argv entry.
83 * (After call to acpi_getopt, we need to backup to the previous
84 * argv entry).
85 *
86 ******************************************************************************/
87
88int acpi_getopt_argument(int argc, char **argv)
89{
90 acpi_gbl_optind--;
91 current_char_ptr++;
92
93 if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
94 acpi_gbl_optarg =
95 &argv[acpi_gbl_optind++][(int)(current_char_ptr + 1)];
96 } else if (++acpi_gbl_optind >= argc) {
97 ACPI_OPTION_ERROR("Option requires an argument: -", 'v');
98
99 current_char_ptr = 1;
100 return (-1);
101 } else {
102 acpi_gbl_optarg = argv[acpi_gbl_optind++];
103 }
104
105 current_char_ptr = 1;
106 return (0);
107}
108
109/*******************************************************************************
110 *
111 * FUNCTION: acpi_getopt
112 *
113 * PARAMETERS: argc, argv - from main
114 * opts - options info list
115 *
116 * RETURN: Option character or EOF
117 *
118 * DESCRIPTION: Get the next option
119 *
120 ******************************************************************************/
121
122int acpi_getopt(int argc, char **argv, char *opts)
123{
124 int current_char;
125 char *opts_ptr;
126
127 if (current_char_ptr == 1) {
128 if (acpi_gbl_optind >= argc ||
129 argv[acpi_gbl_optind][0] != '-' ||
130 argv[acpi_gbl_optind][1] == '\0') {
131 return (EOF);
132 } else if (strcmp(argv[acpi_gbl_optind], "--") == 0) {
133 acpi_gbl_optind++;
134 return (EOF);
135 }
136 }
137
138 /* Get the option */
139
140 current_char = argv[acpi_gbl_optind][current_char_ptr];
141
142 /* Make sure that the option is legal */
143
144 if (current_char == ':' ||
145 (opts_ptr = strchr(opts, current_char)) == NULL) {
146 ACPI_OPTION_ERROR("Illegal option: -", current_char);
147
148 if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
149 acpi_gbl_optind++;
150 current_char_ptr = 1;
151 }
152
153 return ('?');
154 }
155
156 /* Option requires an argument? */
157
158 if (*++opts_ptr == ':') {
159 if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
160 acpi_gbl_optarg =
161 &argv[acpi_gbl_optind++][(int)
162 (current_char_ptr + 1)];
163 } else if (++acpi_gbl_optind >= argc) {
164 ACPI_OPTION_ERROR("Option requires an argument: -",
165 current_char);
166
167 current_char_ptr = 1;
168 return ('?');
169 } else {
170 acpi_gbl_optarg = argv[acpi_gbl_optind++];
171 }
172
173 current_char_ptr = 1;
174 }
175
176 /* Option has an optional argument? */
177
178 else if (*opts_ptr == '+') {
179 if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
180 acpi_gbl_optarg =
181 &argv[acpi_gbl_optind++][(int)
182 (current_char_ptr + 1)];
183 } else if (++acpi_gbl_optind >= argc) {
184 acpi_gbl_optarg = NULL;
185 } else {
186 acpi_gbl_optarg = argv[acpi_gbl_optind++];
187 }
188
189 current_char_ptr = 1;
190 }
191
192 /* Option has optional single-char arguments? */
193
194 else if (*opts_ptr == '^') {
195 if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
196 acpi_gbl_optarg =
197 &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
198 } else {
199 acpi_gbl_optarg = "^";
200 }
201
202 acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
203 acpi_gbl_optind++;
204 current_char_ptr = 1;
205 }
206
207 /* Option has a required single-char argument? */
208
209 else if (*opts_ptr == '|') {
210 if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
211 acpi_gbl_optarg =
212 &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
213 } else {
214 ACPI_OPTION_ERROR
215 ("Option requires a single-character suboption: -",
216 current_char);
217
218 current_char_ptr = 1;
219 return ('?');
220 }
221
222 acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
223 acpi_gbl_optind++;
224 current_char_ptr = 1;
225 }
226
227 /* Option with no arguments */
228
229 else {
230 if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
231 current_char_ptr = 1;
232 acpi_gbl_optind++;
233 }
234
235 acpi_gbl_optarg = NULL;
236 }
237
238 return (current_char);
239}
diff --git a/tools/power/acpi/man/acpidump.8 b/tools/power/acpi/man/acpidump.8
index adfa99166e5e..38f095d86b52 100644
--- a/tools/power/acpi/man/acpidump.8
+++ b/tools/power/acpi/man/acpidump.8
@@ -1,18 +1,64 @@
1.TH ACPIDUMP 8 1.TH ACPIDUMP 8
2.SH NAME 2.SH NAME
3acpidump \- Dump system's ACPI tables to an ASCII file. 3acpidump \- dump a system's ACPI tables to an ASCII file
4
4.SH SYNOPSIS 5.SH SYNOPSIS
5.ft B 6.B acpidump
6.B acpidump > acpidump.out 7.RI [ options ]
8.br
9
7.SH DESCRIPTION 10.SH DESCRIPTION
8\fBacpidump \fP dumps the systems ACPI tables to an ASCII file 11.B acpidump
9appropriate for attaching to a bug report. 12dumps the systems ACPI tables to an ASCII file appropriate for
13attaching to a bug report.
10 14
11Subsequently, they can be processed by utilities in the ACPICA package. 15Subsequently, they can be processed by utilities in the ACPICA package.
12.SS Options 16
13no options worth worrying about. 17.SH OPTIONS
14.PP 18acpidump options are as follow:
15.SH EXAMPLE 19.TP
20.B Options
21.TP
22.B \-b
23Dump tables to binary files
24.TP
25.B \-c
26Dump customized tables
27.TP
28.B \-h \-?
29This help message
30.TP
31.B \-o <File>
32Redirect output to file
33.TP
34.B \-r <Address>
35Dump tables from specified RSDP
36.TP
37.B \-s
38Print table summaries only
39.TP
40.B \-v
41Display version information
42.TP
43.B \-z
44Verbose mode
45.TP
46.B Table Options
47.TP
48.B \-a <Address>
49Get table via a physical address
50.TP
51.B \-f <BinaryFile>
52Get table via a binary file
53.TP
54.B \-n <Signature>
55Get table via a name/signature
56.TP
57Invocation without parameters dumps all available tables
58.TP
59Multiple mixed instances of -a, -f, and -n are supported
60
61.SH EXAMPLES
16 62
17.nf 63.nf
18# acpidump > acpidump.out 64# acpidump > acpidump.out
@@ -50,10 +96,25 @@ ACPICA: https://acpica.org/
50.ta 96.ta
51.nf 97.nf
52/dev/mem 98/dev/mem
99/sys/firmware/acpi/tables/*
53/sys/firmware/acpi/tables/dynamic/* 100/sys/firmware/acpi/tables/dynamic/*
101/sys/firmware/efi/systab
54.fi 102.fi
55 103
56.PP
57.SH AUTHOR 104.SH AUTHOR
58.nf 105.TP
59Written by Len Brown <len.brown@intel.com> 106Original by:
107 Len Brown <len.brown@intel.com>
108.TP
109Written by:
110 Chao Guan <chao.guan@intel.com>
111.TP
112Updated by:
113 Bob Moore <robert.moore@intel.com>
114 Lv Zheng <lv.zheng@intel.com>
115
116.SH SEE ALSO
117\&\fIacpixtract\fR\|(8), \fIiasl\fR\|(8).
118
119.SH COPYRIGHT
120COPYRIGHT (c) 2013, Intel Corporation.
diff --git a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
new file mode 100644
index 000000000000..28c52008e854
--- /dev/null
+++ b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
@@ -0,0 +1,1329 @@
1/******************************************************************************
2 *
3 * Module Name: oslinuxtbl - Linux OSL for obtaining ACPI tables
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include "acpidump.h"
45
46#define _COMPONENT ACPI_OS_SERVICES
47ACPI_MODULE_NAME("oslinuxtbl")
48
49#ifndef PATH_MAX
50#define PATH_MAX 256
51#endif
52/* List of information about obtained ACPI tables */
53typedef struct osl_table_info {
54 struct osl_table_info *next;
55 u32 instance;
56 char signature[ACPI_NAME_SIZE];
57
58} osl_table_info;
59
60/* Local prototypes */
61
62static acpi_status osl_table_initialize(void);
63
64static acpi_status
65osl_table_name_from_file(char *filename, char *signature, u32 *instance);
66
67static acpi_status osl_add_table_to_list(char *signature, u32 instance);
68
69static acpi_status
70osl_read_table_from_file(char *filename,
71 acpi_size file_offset,
72 char *signature, struct acpi_table_header **table);
73
74static acpi_status
75osl_map_table(acpi_size address,
76 char *signature, struct acpi_table_header **table);
77
78static void osl_unmap_table(struct acpi_table_header *table);
79
80static acpi_physical_address osl_find_rsdp_via_efi(void);
81
82static acpi_status osl_load_rsdp(void);
83
84static acpi_status osl_list_customized_tables(char *directory);
85
86static acpi_status
87osl_get_customized_table(char *pathname,
88 char *signature,
89 u32 instance,
90 struct acpi_table_header **table,
91 acpi_physical_address * address);
92
93static acpi_status osl_list_bios_tables(void);
94
95static acpi_status
96osl_get_bios_table(char *signature,
97 u32 instance,
98 struct acpi_table_header **table,
99 acpi_physical_address * address);
100
101static acpi_status osl_get_last_status(acpi_status default_status);
102
103/* File locations */
104
105#define DYNAMIC_TABLE_DIR "/sys/firmware/acpi/tables/dynamic"
106#define STATIC_TABLE_DIR "/sys/firmware/acpi/tables"
107#define EFI_SYSTAB "/sys/firmware/efi/systab"
108
109/* Should we get dynamically loaded SSDTs from DYNAMIC_TABLE_DIR? */
110
111u8 gbl_dump_dynamic_tables = TRUE;
112
113/* Initialization flags */
114
115u8 gbl_table_list_initialized = FALSE;
116
117/* Local copies of main ACPI tables */
118
119struct acpi_table_rsdp gbl_rsdp;
120struct acpi_table_fadt *gbl_fadt = NULL;
121struct acpi_table_rsdt *gbl_rsdt = NULL;
122struct acpi_table_xsdt *gbl_xsdt = NULL;
123
124/* Table addresses */
125
126acpi_physical_address gbl_fadt_address = 0;
127acpi_physical_address gbl_rsdp_address = 0;
128
129/* Revision of RSD PTR */
130
131u8 gbl_revision = 0;
132
133struct osl_table_info *gbl_table_list_head = NULL;
134u32 gbl_table_count = 0;
135
136/******************************************************************************
137 *
138 * FUNCTION: osl_get_last_status
139 *
140 * PARAMETERS: default_status - Default error status to return
141 *
142 * RETURN: Status; Converted from errno.
143 *
144 * DESCRIPTION: Get last errno and conver it to acpi_status.
145 *
146 *****************************************************************************/
147
148static acpi_status osl_get_last_status(acpi_status default_status)
149{
150
151 switch (errno) {
152 case EACCES:
153 case EPERM:
154
155 return (AE_ACCESS);
156
157 case ENOENT:
158
159 return (AE_NOT_FOUND);
160
161 case ENOMEM:
162
163 return (AE_NO_MEMORY);
164
165 default:
166
167 return (default_status);
168 }
169}
170
171/******************************************************************************
172 *
173 * FUNCTION: acpi_os_get_table_by_address
174 *
175 * PARAMETERS: address - Physical address of the ACPI table
176 * table - Where a pointer to the table is returned
177 *
178 * RETURN: Status; Table buffer is returned if AE_OK.
179 * AE_NOT_FOUND: A valid table was not found at the address
180 *
181 * DESCRIPTION: Get an ACPI table via a physical memory address.
182 *
183 *****************************************************************************/
184
185acpi_status
186acpi_os_get_table_by_address(acpi_physical_address address,
187 struct acpi_table_header ** table)
188{
189 u32 table_length;
190 struct acpi_table_header *mapped_table;
191 struct acpi_table_header *local_table = NULL;
192 acpi_status status = AE_OK;
193
194 /* Get main ACPI tables from memory on first invocation of this function */
195
196 status = osl_table_initialize();
197 if (ACPI_FAILURE(status)) {
198 return (status);
199 }
200
201 /* Map the table and validate it */
202
203 status = osl_map_table(address, NULL, &mapped_table);
204 if (ACPI_FAILURE(status)) {
205 return (status);
206 }
207
208 /* Copy table to local buffer and return it */
209
210 table_length = ap_get_table_length(mapped_table);
211 if (table_length == 0) {
212 status = AE_BAD_HEADER;
213 goto exit;
214 }
215
216 local_table = calloc(1, table_length);
217 if (!local_table) {
218 status = AE_NO_MEMORY;
219 goto exit;
220 }
221
222 ACPI_MEMCPY(local_table, mapped_table, table_length);
223
224exit:
225 osl_unmap_table(mapped_table);
226 *table = local_table;
227 return (status);
228}
229
230/******************************************************************************
231 *
232 * FUNCTION: acpi_os_get_table_by_name
233 *
234 * PARAMETERS: signature - ACPI Signature for desired table. Must be
235 * a null terminated 4-character string.
236 * instance - Multiple table support for SSDT/UEFI (0...n)
237 * Must be 0 for other tables.
238 * table - Where a pointer to the table is returned
239 * address - Where the table physical address is returned
240 *
241 * RETURN: Status; Table buffer and physical address returned if AE_OK.
242 * AE_LIMIT: Instance is beyond valid limit
243 * AE_NOT_FOUND: A table with the signature was not found
244 *
245 * NOTE: Assumes the input signature is uppercase.
246 *
247 *****************************************************************************/
248
249acpi_status
250acpi_os_get_table_by_name(char *signature,
251 u32 instance,
252 struct acpi_table_header ** table,
253 acpi_physical_address * address)
254{
255 acpi_status status;
256
257 /* Get main ACPI tables from memory on first invocation of this function */
258
259 status = osl_table_initialize();
260 if (ACPI_FAILURE(status)) {
261 return (status);
262 }
263
264 /* Not a main ACPI table, attempt to extract it from the RSDT/XSDT */
265
266 if (!gbl_dump_customized_tables) {
267
268 /* Attempt to get the table from the memory */
269
270 status =
271 osl_get_bios_table(signature, instance, table, address);
272 } else {
273 /* Attempt to get the table from the static directory */
274
275 status = osl_get_customized_table(STATIC_TABLE_DIR, signature,
276 instance, table, address);
277 }
278
279 if (ACPI_FAILURE(status) && status == AE_LIMIT) {
280 if (gbl_dump_dynamic_tables) {
281
282 /* Attempt to get a dynamic table */
283
284 status =
285 osl_get_customized_table(DYNAMIC_TABLE_DIR,
286 signature, instance, table,
287 address);
288 }
289 }
290
291 return (status);
292}
293
294/******************************************************************************
295 *
296 * FUNCTION: osl_add_table_to_list
297 *
298 * PARAMETERS: signature - Table signature
299 * instance - Table instance
300 *
301 * RETURN: Status; Successfully added if AE_OK.
302 * AE_NO_MEMORY: Memory allocation error
303 *
304 * DESCRIPTION: Insert a table structure into OSL table list.
305 *
306 *****************************************************************************/
307
308static acpi_status osl_add_table_to_list(char *signature, u32 instance)
309{
310 struct osl_table_info *new_info;
311 struct osl_table_info *next;
312 u32 next_instance = 0;
313 u8 found = FALSE;
314
315 new_info = calloc(1, sizeof(struct osl_table_info));
316 if (!new_info) {
317 return (AE_NO_MEMORY);
318 }
319
320 ACPI_MOVE_NAME(new_info->signature, signature);
321
322 if (!gbl_table_list_head) {
323 gbl_table_list_head = new_info;
324 } else {
325 next = gbl_table_list_head;
326 while (1) {
327 if (ACPI_COMPARE_NAME(next->signature, signature)) {
328 if (next->instance == instance) {
329 found = TRUE;
330 }
331 if (next->instance >= next_instance) {
332 next_instance = next->instance + 1;
333 }
334 }
335
336 if (!next->next) {
337 break;
338 }
339 next = next->next;
340 }
341 next->next = new_info;
342 }
343
344 if (found) {
345 if (instance) {
346 fprintf(stderr,
347 "%4.4s: Warning unmatched table instance %d, expected %d\n",
348 signature, instance, next_instance);
349 }
350 instance = next_instance;
351 }
352
353 new_info->instance = instance;
354 gbl_table_count++;
355
356 return (AE_OK);
357}
358
359/******************************************************************************
360 *
361 * FUNCTION: acpi_os_get_table_by_index
362 *
363 * PARAMETERS: index - Which table to get
364 * table - Where a pointer to the table is returned
365 * instance - Where a pointer to the table instance no. is
366 * returned
367 * address - Where the table physical address is returned
368 *
369 * RETURN: Status; Table buffer and physical address returned if AE_OK.
370 * AE_LIMIT: Index is beyond valid limit
371 *
372 * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns
373 * AE_LIMIT when an invalid index is reached. Index is not
374 * necessarily an index into the RSDT/XSDT.
375 *
376 *****************************************************************************/
377
378acpi_status
379acpi_os_get_table_by_index(u32 index,
380 struct acpi_table_header ** table,
381 u32 *instance, acpi_physical_address * address)
382{
383 struct osl_table_info *info;
384 acpi_status status;
385 u32 i;
386
387 /* Get main ACPI tables from memory on first invocation of this function */
388
389 status = osl_table_initialize();
390 if (ACPI_FAILURE(status)) {
391 return (status);
392 }
393
394 /* Validate Index */
395
396 if (index >= gbl_table_count) {
397 return (AE_LIMIT);
398 }
399
400 /* Point to the table list entry specified by the Index argument */
401
402 info = gbl_table_list_head;
403 for (i = 0; i < index; i++) {
404 info = info->next;
405 }
406
407 /* Now we can just get the table via the signature */
408
409 status = acpi_os_get_table_by_name(info->signature, info->instance,
410 table, address);
411
412 if (ACPI_SUCCESS(status)) {
413 *instance = info->instance;
414 }
415 return (status);
416}
417
418/******************************************************************************
419 *
420 * FUNCTION: osl_find_rsdp_via_efi
421 *
422 * PARAMETERS: None
423 *
424 * RETURN: RSDP address if found
425 *
426 * DESCRIPTION: Find RSDP address via EFI.
427 *
428 *****************************************************************************/
429
430static acpi_physical_address osl_find_rsdp_via_efi(void)
431{
432 FILE *file;
433 char buffer[80];
434 unsigned long address = 0;
435
436 file = fopen(EFI_SYSTAB, "r");
437 if (file) {
438 while (fgets(buffer, 80, file)) {
439 if (sscanf(buffer, "ACPI20=0x%lx", &address) == 1) {
440 break;
441 }
442 }
443 fclose(file);
444 }
445
446 return ((acpi_physical_address) (address));
447}
448
449/******************************************************************************
450 *
451 * FUNCTION: osl_load_rsdp
452 *
453 * PARAMETERS: None
454 *
455 * RETURN: Status
456 *
457 * DESCRIPTION: Scan and load RSDP.
458 *
459 *****************************************************************************/
460
461static acpi_status osl_load_rsdp(void)
462{
463 struct acpi_table_header *mapped_table;
464 u8 *rsdp_address;
465 acpi_physical_address rsdp_base;
466 acpi_size rsdp_size;
467
468 /* Get RSDP from memory */
469
470 rsdp_size = sizeof(struct acpi_table_rsdp);
471 if (gbl_rsdp_base) {
472 rsdp_base = gbl_rsdp_base;
473 } else {
474 rsdp_base = osl_find_rsdp_via_efi();
475 }
476
477 if (!rsdp_base) {
478 rsdp_base = ACPI_HI_RSDP_WINDOW_BASE;
479 rsdp_size = ACPI_HI_RSDP_WINDOW_SIZE;
480 }
481
482 rsdp_address = acpi_os_map_memory(rsdp_base, rsdp_size);
483 if (!rsdp_address) {
484 return (osl_get_last_status(AE_BAD_ADDRESS));
485 }
486
487 /* Search low memory for the RSDP */
488
489 mapped_table = ACPI_CAST_PTR(struct acpi_table_header,
490 acpi_tb_scan_memory_for_rsdp(rsdp_address,
491 rsdp_size));
492 if (!mapped_table) {
493 acpi_os_unmap_memory(rsdp_address, rsdp_size);
494 return (AE_NOT_FOUND);
495 }
496
497 gbl_rsdp_address =
498 rsdp_base + (ACPI_CAST8(mapped_table) - rsdp_address);
499
500 ACPI_MEMCPY(&gbl_rsdp, mapped_table, sizeof(struct acpi_table_rsdp));
501 acpi_os_unmap_memory(rsdp_address, rsdp_size);
502
503 return (AE_OK);
504}
505
506/******************************************************************************
507 *
508 * FUNCTION: osl_can_use_xsdt
509 *
510 * PARAMETERS: None
511 *
512 * RETURN: TRUE if XSDT is allowed to be used.
513 *
514 * DESCRIPTION: This function collects logic that can be used to determine if
515 * XSDT should be used instead of RSDT.
516 *
517 *****************************************************************************/
518
519static u8 osl_can_use_xsdt(void)
520{
521 if (gbl_revision && !acpi_gbl_do_not_use_xsdt) {
522 return (TRUE);
523 } else {
524 return (FALSE);
525 }
526}
527
528/******************************************************************************
529 *
530 * FUNCTION: osl_table_initialize
531 *
532 * PARAMETERS: None
533 *
534 * RETURN: Status
535 *
536 * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to
537 * local variables. Main ACPI tables include RSDT, FADT, RSDT,
538 * and/or XSDT.
539 *
540 *****************************************************************************/
541
542static acpi_status osl_table_initialize(void)
543{
544 acpi_status status;
545 acpi_physical_address address;
546
547 if (gbl_table_list_initialized) {
548 return (AE_OK);
549 }
550
551 /* Get RSDP from memory */
552
553 status = osl_load_rsdp();
554 if (ACPI_FAILURE(status)) {
555 return (status);
556 }
557
558 /* Get XSDT from memory */
559
560 if (gbl_rsdp.revision && !gbl_do_not_dump_xsdt) {
561 if (gbl_xsdt) {
562 free(gbl_xsdt);
563 gbl_xsdt = NULL;
564 }
565
566 gbl_revision = 2;
567 status = osl_get_bios_table(ACPI_SIG_XSDT, 0,
568 ACPI_CAST_PTR(struct
569 acpi_table_header *,
570 &gbl_xsdt), &address);
571 if (ACPI_FAILURE(status)) {
572 return (status);
573 }
574 }
575
576 /* Get RSDT from memory */
577
578 if (gbl_rsdp.rsdt_physical_address) {
579 if (gbl_rsdt) {
580 free(gbl_rsdt);
581 gbl_rsdt = NULL;
582 }
583
584 status = osl_get_bios_table(ACPI_SIG_RSDT, 0,
585 ACPI_CAST_PTR(struct
586 acpi_table_header *,
587 &gbl_rsdt), &address);
588 if (ACPI_FAILURE(status)) {
589 return (status);
590 }
591 }
592
593 /* Get FADT from memory */
594
595 if (gbl_fadt) {
596 free(gbl_fadt);
597 gbl_fadt = NULL;
598 }
599
600 status = osl_get_bios_table(ACPI_SIG_FADT, 0,
601 ACPI_CAST_PTR(struct acpi_table_header *,
602 &gbl_fadt),
603 &gbl_fadt_address);
604 if (ACPI_FAILURE(status)) {
605 return (status);
606 }
607
608 if (!gbl_dump_customized_tables) {
609
610 /* Add mandatory tables to global table list first */
611
612 status = osl_add_table_to_list(ACPI_RSDP_NAME, 0);
613 if (ACPI_FAILURE(status)) {
614 return (status);
615 }
616
617 status = osl_add_table_to_list(ACPI_SIG_RSDT, 0);
618 if (ACPI_FAILURE(status)) {
619 return (status);
620 }
621
622 if (gbl_revision == 2) {
623 status = osl_add_table_to_list(ACPI_SIG_XSDT, 0);
624 if (ACPI_FAILURE(status)) {
625 return (status);
626 }
627 }
628
629 status = osl_add_table_to_list(ACPI_SIG_DSDT, 0);
630 if (ACPI_FAILURE(status)) {
631 return (status);
632 }
633
634 status = osl_add_table_to_list(ACPI_SIG_FACS, 0);
635 if (ACPI_FAILURE(status)) {
636 return (status);
637 }
638
639 /* Add all tables found in the memory */
640
641 status = osl_list_bios_tables();
642 if (ACPI_FAILURE(status)) {
643 return (status);
644 }
645 } else {
646 /* Add all tables found in the static directory */
647
648 status = osl_list_customized_tables(STATIC_TABLE_DIR);
649 if (ACPI_FAILURE(status)) {
650 return (status);
651 }
652 }
653
654 if (gbl_dump_dynamic_tables) {
655
656 /* Add all dynamically loaded tables in the dynamic directory */
657
658 status = osl_list_customized_tables(DYNAMIC_TABLE_DIR);
659 if (ACPI_FAILURE(status)) {
660 return (status);
661 }
662 }
663
664 gbl_table_list_initialized = TRUE;
665 return (AE_OK);
666}
667
668/******************************************************************************
669 *
670 * FUNCTION: osl_list_bios_tables
671 *
672 * PARAMETERS: None
673 *
674 * RETURN: Status; Table list is initialized if AE_OK.
675 *
676 * DESCRIPTION: Add ACPI tables to the table list from memory.
677 *
678 * NOTE: This works on Linux as table customization does not modify the
679 * addresses stored in RSDP/RSDT/XSDT/FADT.
680 *
681 *****************************************************************************/
682
683static acpi_status osl_list_bios_tables(void)
684{
685 struct acpi_table_header *mapped_table = NULL;
686 u8 *table_data;
687 u8 number_of_tables;
688 u8 item_size;
689 acpi_physical_address table_address = 0;
690 acpi_status status = AE_OK;
691 u32 i;
692
693 if (osl_can_use_xsdt()) {
694 item_size = sizeof(u64);
695 table_data =
696 ACPI_CAST8(gbl_xsdt) + sizeof(struct acpi_table_header);
697 number_of_tables =
698 (u8)((gbl_xsdt->header.length -
699 sizeof(struct acpi_table_header))
700 / item_size);
701 } else { /* Use RSDT if XSDT is not available */
702
703 item_size = sizeof(u32);
704 table_data =
705 ACPI_CAST8(gbl_rsdt) + sizeof(struct acpi_table_header);
706 number_of_tables =
707 (u8)((gbl_rsdt->header.length -
708 sizeof(struct acpi_table_header))
709 / item_size);
710 }
711
712 /* Search RSDT/XSDT for the requested table */
713
714 for (i = 0; i < number_of_tables; ++i, table_data += item_size) {
715 if (osl_can_use_xsdt()) {
716 table_address =
717 (acpi_physical_address) (*ACPI_CAST64(table_data));
718 } else {
719 table_address =
720 (acpi_physical_address) (*ACPI_CAST32(table_data));
721 }
722
723 /* Skip NULL entries in RSDT/XSDT */
724
725 if (!table_address) {
726 continue;
727 }
728
729 status = osl_map_table(table_address, NULL, &mapped_table);
730 if (ACPI_FAILURE(status)) {
731 return (status);
732 }
733
734 osl_add_table_to_list(mapped_table->signature, 0);
735 osl_unmap_table(mapped_table);
736 }
737
738 return (AE_OK);
739}
740
741/******************************************************************************
742 *
743 * FUNCTION: osl_get_bios_table
744 *
745 * PARAMETERS: signature - ACPI Signature for common table. Must be
746 * a null terminated 4-character string.
747 * instance - Multiple table support for SSDT/UEFI (0...n)
748 * Must be 0 for other tables.
749 * table - Where a pointer to the table is returned
750 * address - Where the table physical address is returned
751 *
752 * RETURN: Status; Table buffer and physical address returned if AE_OK.
753 * AE_LIMIT: Instance is beyond valid limit
754 * AE_NOT_FOUND: A table with the signature was not found
755 *
756 * DESCRIPTION: Get a BIOS provided ACPI table
757 *
758 * NOTE: Assumes the input signature is uppercase.
759 *
760 *****************************************************************************/
761
762static acpi_status
763osl_get_bios_table(char *signature,
764 u32 instance,
765 struct acpi_table_header **table,
766 acpi_physical_address * address)
767{
768 struct acpi_table_header *local_table = NULL;
769 struct acpi_table_header *mapped_table = NULL;
770 u8 *table_data;
771 u8 number_of_tables;
772 u8 item_size;
773 u32 current_instance = 0;
774 acpi_physical_address table_address = 0;
775 u32 table_length = 0;
776 acpi_status status = AE_OK;
777 u32 i;
778
779 /* Handle special tables whose addresses are not in RSDT/XSDT */
780
781 if (ACPI_COMPARE_NAME(signature, ACPI_RSDP_NAME) ||
782 ACPI_COMPARE_NAME(signature, ACPI_SIG_RSDT) ||
783 ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT) ||
784 ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT) ||
785 ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) {
786 if (instance > 0) {
787 return (AE_LIMIT);
788 }
789
790 /*
791 * Get the appropriate address, either 32-bit or 64-bit. Be very
792 * careful about the FADT length and validate table addresses.
793 * Note: The 64-bit addresses have priority.
794 */
795 if (ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT)) {
796 if ((gbl_fadt->header.length >= MIN_FADT_FOR_XDSDT) &&
797 gbl_fadt->Xdsdt) {
798 table_address =
799 (acpi_physical_address) gbl_fadt->Xdsdt;
800 } else
801 if ((gbl_fadt->header.length >= MIN_FADT_FOR_DSDT)
802 && gbl_fadt->dsdt) {
803 table_address =
804 (acpi_physical_address) gbl_fadt->dsdt;
805 }
806 } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) {
807 if ((gbl_fadt->header.length >= MIN_FADT_FOR_XFACS) &&
808 gbl_fadt->Xfacs) {
809 table_address =
810 (acpi_physical_address) gbl_fadt->Xfacs;
811 } else
812 if ((gbl_fadt->header.length >= MIN_FADT_FOR_FACS)
813 && gbl_fadt->facs) {
814 table_address =
815 (acpi_physical_address) gbl_fadt->facs;
816 }
817 } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT)) {
818 if (!gbl_revision) {
819 return (AE_BAD_SIGNATURE);
820 }
821 table_address =
822 (acpi_physical_address) gbl_rsdp.
823 xsdt_physical_address;
824 } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_RSDT)) {
825 table_address =
826 (acpi_physical_address) gbl_rsdp.
827 rsdt_physical_address;
828 } else {
829 table_address =
830 (acpi_physical_address) gbl_rsdp_address;
831 signature = ACPI_SIG_RSDP;
832 }
833
834 /* Now we can get the requested special table */
835
836 status = osl_map_table(table_address, signature, &mapped_table);
837 if (ACPI_FAILURE(status)) {
838 return (status);
839 }
840
841 table_length = ap_get_table_length(mapped_table);
842 } else { /* Case for a normal ACPI table */
843
844 if (osl_can_use_xsdt()) {
845 item_size = sizeof(u64);
846 table_data =
847 ACPI_CAST8(gbl_xsdt) +
848 sizeof(struct acpi_table_header);
849 number_of_tables =
850 (u8)((gbl_xsdt->header.length -
851 sizeof(struct acpi_table_header))
852 / item_size);
853 } else { /* Use RSDT if XSDT is not available */
854
855 item_size = sizeof(u32);
856 table_data =
857 ACPI_CAST8(gbl_rsdt) +
858 sizeof(struct acpi_table_header);
859 number_of_tables =
860 (u8)((gbl_rsdt->header.length -
861 sizeof(struct acpi_table_header))
862 / item_size);
863 }
864
865 /* Search RSDT/XSDT for the requested table */
866
867 for (i = 0; i < number_of_tables; ++i, table_data += item_size) {
868 if (osl_can_use_xsdt()) {
869 table_address =
870 (acpi_physical_address) (*ACPI_CAST64
871 (table_data));
872 } else {
873 table_address =
874 (acpi_physical_address) (*ACPI_CAST32
875 (table_data));
876 }
877
878 /* Skip NULL entries in RSDT/XSDT */
879
880 if (!table_address) {
881 continue;
882 }
883
884 status =
885 osl_map_table(table_address, NULL, &mapped_table);
886 if (ACPI_FAILURE(status)) {
887 return (status);
888 }
889 table_length = mapped_table->length;
890
891 /* Does this table match the requested signature? */
892
893 if (!ACPI_COMPARE_NAME
894 (mapped_table->signature, signature)) {
895 osl_unmap_table(mapped_table);
896 mapped_table = NULL;
897 continue;
898 }
899
900 /* Match table instance (for SSDT/UEFI tables) */
901
902 if (current_instance != instance) {
903 osl_unmap_table(mapped_table);
904 mapped_table = NULL;
905 current_instance++;
906 continue;
907 }
908
909 break;
910 }
911 }
912
913 if (!mapped_table) {
914 return (AE_LIMIT);
915 }
916
917 if (table_length == 0) {
918 status = AE_BAD_HEADER;
919 goto exit;
920 }
921
922 /* Copy table to local buffer and return it */
923
924 local_table = calloc(1, table_length);
925 if (!local_table) {
926 status = AE_NO_MEMORY;
927 goto exit;
928 }
929
930 ACPI_MEMCPY(local_table, mapped_table, table_length);
931 *address = table_address;
932 *table = local_table;
933
934exit:
935 osl_unmap_table(mapped_table);
936 return (status);
937}
938
939/******************************************************************************
940 *
941 * FUNCTION: osl_list_customized_tables
942 *
943 * PARAMETERS: directory - Directory that contains the tables
944 *
945 * RETURN: Status; Table list is initialized if AE_OK.
946 *
947 * DESCRIPTION: Add ACPI tables to the table list from a directory.
948 *
949 *****************************************************************************/
950
951static acpi_status osl_list_customized_tables(char *directory)
952{
953 void *table_dir;
954 u32 instance;
955 char temp_name[ACPI_NAME_SIZE];
956 char *filename;
957 acpi_status status = AE_OK;
958
959 /* Open the requested directory */
960
961 table_dir = acpi_os_open_directory(directory, "*", REQUEST_FILE_ONLY);
962 if (!table_dir) {
963 return (osl_get_last_status(AE_NOT_FOUND));
964 }
965
966 /* Examine all entries in this directory */
967
968 while ((filename = acpi_os_get_next_filename(table_dir))) {
969
970 /* Extract table name and instance number */
971
972 status =
973 osl_table_name_from_file(filename, temp_name, &instance);
974
975 /* Ignore meaningless files */
976
977 if (ACPI_FAILURE(status)) {
978 continue;
979 }
980
981 /* Add new info node to global table list */
982
983 status = osl_add_table_to_list(temp_name, instance);
984 if (ACPI_FAILURE(status)) {
985 break;
986 }
987 }
988
989 acpi_os_close_directory(table_dir);
990 return (status);
991}
992
993/******************************************************************************
994 *
995 * FUNCTION: osl_map_table
996 *
997 * PARAMETERS: address - Address of the table in memory
998 * signature - Optional ACPI Signature for desired table.
999 * Null terminated 4-character string.
1000 * table - Where a pointer to the mapped table is
1001 * returned
1002 *
1003 * RETURN: Status; Mapped table is returned if AE_OK.
1004 * AE_NOT_FOUND: A valid table was not found at the address
1005 *
1006 * DESCRIPTION: Map entire ACPI table into caller's address space.
1007 *
1008 *****************************************************************************/
1009
1010static acpi_status
1011osl_map_table(acpi_size address,
1012 char *signature, struct acpi_table_header **table)
1013{
1014 struct acpi_table_header *mapped_table;
1015 u32 length;
1016
1017 if (!address) {
1018 return (AE_BAD_ADDRESS);
1019 }
1020
1021 /*
1022 * Map the header so we can get the table length.
1023 * Use sizeof (struct acpi_table_header) as:
1024 * 1. it is bigger than 24 to include RSDP->Length
1025 * 2. it is smaller than sizeof (struct acpi_table_rsdp)
1026 */
1027 mapped_table =
1028 acpi_os_map_memory(address, sizeof(struct acpi_table_header));
1029 if (!mapped_table) {
1030 fprintf(stderr, "Could not map table header at 0x%8.8X%8.8X\n",
1031 ACPI_FORMAT_UINT64(address));
1032 return (osl_get_last_status(AE_BAD_ADDRESS));
1033 }
1034
1035 /* If specified, signature must match */
1036
1037 if (signature) {
1038 if (ACPI_VALIDATE_RSDP_SIG(signature)) {
1039 if (!ACPI_VALIDATE_RSDP_SIG(mapped_table->signature)) {
1040 acpi_os_unmap_memory(mapped_table,
1041 sizeof(struct
1042 acpi_table_header));
1043 return (AE_BAD_SIGNATURE);
1044 }
1045 } else
1046 if (!ACPI_COMPARE_NAME(signature, mapped_table->signature))
1047 {
1048 acpi_os_unmap_memory(mapped_table,
1049 sizeof(struct acpi_table_header));
1050 return (AE_BAD_SIGNATURE);
1051 }
1052 }
1053
1054 /* Map the entire table */
1055
1056 length = ap_get_table_length(mapped_table);
1057 acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header));
1058 if (length == 0) {
1059 return (AE_BAD_HEADER);
1060 }
1061
1062 mapped_table = acpi_os_map_memory(address, length);
1063 if (!mapped_table) {
1064 fprintf(stderr,
1065 "Could not map table at 0x%8.8X%8.8X length %8.8X\n",
1066 ACPI_FORMAT_UINT64(address), length);
1067 return (osl_get_last_status(AE_INVALID_TABLE_LENGTH));
1068 }
1069
1070 (void)ap_is_valid_checksum(mapped_table);
1071
1072 *table = mapped_table;
1073 return (AE_OK);
1074}
1075
1076/******************************************************************************
1077 *
1078 * FUNCTION: osl_unmap_table
1079 *
1080 * PARAMETERS: table - A pointer to the mapped table
1081 *
1082 * RETURN: None
1083 *
1084 * DESCRIPTION: Unmap entire ACPI table.
1085 *
1086 *****************************************************************************/
1087
1088static void osl_unmap_table(struct acpi_table_header *table)
1089{
1090 if (table) {
1091 acpi_os_unmap_memory(table, ap_get_table_length(table));
1092 }
1093}
1094
1095/******************************************************************************
1096 *
1097 * FUNCTION: osl_table_name_from_file
1098 *
1099 * PARAMETERS: filename - File that contains the desired table
1100 * signature - Pointer to 4-character buffer to store
1101 * extracted table signature.
1102 * instance - Pointer to integer to store extracted
1103 * table instance number.
1104 *
1105 * RETURN: Status; Table name is extracted if AE_OK.
1106 *
1107 * DESCRIPTION: Extract table signature and instance number from a table file
1108 * name.
1109 *
1110 *****************************************************************************/
1111
1112static acpi_status
1113osl_table_name_from_file(char *filename, char *signature, u32 *instance)
1114{
1115
1116 /* Ignore meaningless files */
1117
1118 if (strlen(filename) < ACPI_NAME_SIZE) {
1119 return (AE_BAD_SIGNATURE);
1120 }
1121
1122 /* Extract instance number */
1123
1124 if (isdigit((int)filename[ACPI_NAME_SIZE])) {
1125 sscanf(&filename[ACPI_NAME_SIZE], "%d", instance);
1126 } else if (strlen(filename) != ACPI_NAME_SIZE) {
1127 return (AE_BAD_SIGNATURE);
1128 } else {
1129 *instance = 0;
1130 }
1131
1132 /* Extract signature */
1133
1134 ACPI_MOVE_NAME(signature, filename);
1135 return (AE_OK);
1136}
1137
1138/******************************************************************************
1139 *
1140 * FUNCTION: osl_read_table_from_file
1141 *
1142 * PARAMETERS: filename - File that contains the desired table
1143 * file_offset - Offset of the table in file
1144 * signature - Optional ACPI Signature for desired table.
1145 * A null terminated 4-character string.
1146 * table - Where a pointer to the table is returned
1147 *
1148 * RETURN: Status; Table buffer is returned if AE_OK.
1149 *
1150 * DESCRIPTION: Read a ACPI table from a file.
1151 *
1152 *****************************************************************************/
1153
1154static acpi_status
1155osl_read_table_from_file(char *filename,
1156 acpi_size file_offset,
1157 char *signature, struct acpi_table_header **table)
1158{
1159 FILE *table_file;
1160 struct acpi_table_header header;
1161 struct acpi_table_header *local_table = NULL;
1162 u32 table_length;
1163 s32 count;
1164 acpi_status status = AE_OK;
1165
1166 /* Open the file */
1167
1168 table_file = fopen(filename, "rb");
1169 if (table_file == NULL) {
1170 fprintf(stderr, "Could not open table file: %s\n", filename);
1171 return (osl_get_last_status(AE_NOT_FOUND));
1172 }
1173
1174 fseek(table_file, file_offset, SEEK_SET);
1175
1176 /* Read the Table header to get the table length */
1177
1178 count = fread(&header, 1, sizeof(struct acpi_table_header), table_file);
1179 if (count != sizeof(struct acpi_table_header)) {
1180 fprintf(stderr, "Could not read table header: %s\n", filename);
1181 status = AE_BAD_HEADER;
1182 goto exit;
1183 }
1184
1185 /* If signature is specified, it must match the table */
1186
1187 if (signature) {
1188 if (ACPI_VALIDATE_RSDP_SIG(signature)) {
1189 if (!ACPI_VALIDATE_RSDP_SIG(header.signature)) {
1190 fprintf(stderr,
1191 "Incorrect RSDP signature: found %8.8s\n",
1192 header.signature);
1193 status = AE_BAD_SIGNATURE;
1194 goto exit;
1195 }
1196 } else if (!ACPI_COMPARE_NAME(signature, header.signature)) {
1197 fprintf(stderr,
1198 "Incorrect signature: Expecting %4.4s, found %4.4s\n",
1199 signature, header.signature);
1200 status = AE_BAD_SIGNATURE;
1201 goto exit;
1202 }
1203 }
1204
1205 table_length = ap_get_table_length(&header);
1206 if (table_length == 0) {
1207 status = AE_BAD_HEADER;
1208 goto exit;
1209 }
1210
1211 /* Read the entire table into a local buffer */
1212
1213 local_table = calloc(1, table_length);
1214 if (!local_table) {
1215 fprintf(stderr,
1216 "%4.4s: Could not allocate buffer for table of length %X\n",
1217 header.signature, table_length);
1218 status = AE_NO_MEMORY;
1219 goto exit;
1220 }
1221
1222 fseek(table_file, file_offset, SEEK_SET);
1223
1224 count = fread(local_table, 1, table_length, table_file);
1225 if (count != table_length) {
1226 fprintf(stderr, "%4.4s: Could not read table content\n",
1227 header.signature);
1228 status = AE_INVALID_TABLE_LENGTH;
1229 goto exit;
1230 }
1231
1232 /* Validate checksum */
1233
1234 (void)ap_is_valid_checksum(local_table);
1235
1236exit:
1237 fclose(table_file);
1238 *table = local_table;
1239 return (status);
1240}
1241
1242/******************************************************************************
1243 *
1244 * FUNCTION: osl_get_customized_table
1245 *
1246 * PARAMETERS: pathname - Directory to find Linux customized table
1247 * signature - ACPI Signature for desired table. Must be
1248 * a null terminated 4-character string.
1249 * instance - Multiple table support for SSDT/UEFI (0...n)
1250 * Must be 0 for other tables.
1251 * table - Where a pointer to the table is returned
1252 * address - Where the table physical address is returned
1253 *
1254 * RETURN: Status; Table buffer is returned if AE_OK.
1255 * AE_LIMIT: Instance is beyond valid limit
1256 * AE_NOT_FOUND: A table with the signature was not found
1257 *
1258 * DESCRIPTION: Get an OS customized table.
1259 *
1260 *****************************************************************************/
1261
1262static acpi_status
1263osl_get_customized_table(char *pathname,
1264 char *signature,
1265 u32 instance,
1266 struct acpi_table_header **table,
1267 acpi_physical_address * address)
1268{
1269 void *table_dir;
1270 u32 current_instance = 0;
1271 char temp_name[ACPI_NAME_SIZE];
1272 char table_filename[PATH_MAX];
1273 char *filename;
1274 acpi_status status;
1275
1276 /* Open the directory for customized tables */
1277
1278 table_dir = acpi_os_open_directory(pathname, "*", REQUEST_FILE_ONLY);
1279 if (!table_dir) {
1280 return (osl_get_last_status(AE_NOT_FOUND));
1281 }
1282
1283 /* Attempt to find the table in the directory */
1284
1285 while ((filename = acpi_os_get_next_filename(table_dir))) {
1286
1287 /* Ignore meaningless files */
1288
1289 if (!ACPI_COMPARE_NAME(filename, signature)) {
1290 continue;
1291 }
1292
1293 /* Extract table name and instance number */
1294
1295 status =
1296 osl_table_name_from_file(filename, temp_name,
1297 &current_instance);
1298
1299 /* Ignore meaningless files */
1300
1301 if (ACPI_FAILURE(status) || current_instance != instance) {
1302 continue;
1303 }
1304
1305 /* Create the table pathname */
1306
1307 if (instance != 0) {
1308 sprintf(table_filename, "%s/%4.4s%d", pathname,
1309 temp_name, instance);
1310 } else {
1311 sprintf(table_filename, "%s/%4.4s", pathname,
1312 temp_name);
1313 }
1314 break;
1315 }
1316
1317 acpi_os_close_directory(table_dir);
1318
1319 if (!filename) {
1320 return (AE_LIMIT);
1321 }
1322
1323 /* There is no physical address saved for customized tables, use zero */
1324
1325 *address = 0;
1326 status = osl_read_table_from_file(table_filename, 0, NULL, table);
1327
1328 return (status);
1329}
diff --git a/tools/power/acpi/os_specific/service_layers/osunixdir.c b/tools/power/acpi/os_specific/service_layers/osunixdir.c
new file mode 100644
index 000000000000..733f9e490fc4
--- /dev/null
+++ b/tools/power/acpi/os_specific/service_layers/osunixdir.c
@@ -0,0 +1,204 @@
1/******************************************************************************
2 *
3 * Module Name: osunixdir - Unix directory access interfaces
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45
46#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
49#include <dirent.h>
50#include <fnmatch.h>
51#include <ctype.h>
52#include <sys/stat.h>
53
54/*
55 * Allocated structure returned from os_open_directory
56 */
57typedef struct external_find_info {
58 char *dir_pathname;
59 DIR *dir_ptr;
60 char temp_buffer[256];
61 char *wildcard_spec;
62 char requested_file_type;
63
64} external_find_info;
65
66/*******************************************************************************
67 *
68 * FUNCTION: acpi_os_open_directory
69 *
70 * PARAMETERS: dir_pathname - Full pathname to the directory
71 * wildcard_spec - string of the form "*.c", etc.
72 *
73 * RETURN: A directory "handle" to be used in subsequent search operations.
74 * NULL returned on failure.
75 *
76 * DESCRIPTION: Open a directory in preparation for a wildcard search
77 *
78 ******************************************************************************/
79
80void *acpi_os_open_directory(char *dir_pathname,
81 char *wildcard_spec, char requested_file_type)
82{
83 struct external_find_info *external_info;
84 DIR *dir;
85
86 /* Allocate the info struct that will be returned to the caller */
87
88 external_info = calloc(1, sizeof(struct external_find_info));
89 if (!external_info) {
90 return (NULL);
91 }
92
93 /* Get the directory stream */
94
95 dir = opendir(dir_pathname);
96 if (!dir) {
97 fprintf(stderr, "Cannot open directory - %s\n", dir_pathname);
98 free(external_info);
99 return (NULL);
100 }
101
102 /* Save the info in the return structure */
103
104 external_info->wildcard_spec = wildcard_spec;
105 external_info->requested_file_type = requested_file_type;
106 external_info->dir_pathname = dir_pathname;
107 external_info->dir_ptr = dir;
108 return (external_info);
109}
110
111/*******************************************************************************
112 *
113 * FUNCTION: acpi_os_get_next_filename
114 *
115 * PARAMETERS: dir_handle - Created via acpi_os_open_directory
116 *
117 * RETURN: Next filename matched. NULL if no more matches.
118 *
119 * DESCRIPTION: Get the next file in the directory that matches the wildcard
120 * specification.
121 *
122 ******************************************************************************/
123
124char *acpi_os_get_next_filename(void *dir_handle)
125{
126 struct external_find_info *external_info = dir_handle;
127 struct dirent *dir_entry;
128 char *temp_str;
129 int str_len;
130 struct stat temp_stat;
131 int err;
132
133 while ((dir_entry = readdir(external_info->dir_ptr))) {
134 if (!fnmatch
135 (external_info->wildcard_spec, dir_entry->d_name, 0)) {
136 if (dir_entry->d_name[0] == '.') {
137 continue;
138 }
139
140 str_len = strlen(dir_entry->d_name) +
141 strlen(external_info->dir_pathname) + 2;
142
143 temp_str = calloc(str_len, 1);
144 if (!temp_str) {
145 fprintf(stderr,
146 "Could not allocate buffer for temporary string\n");
147 return (NULL);
148 }
149
150 strcpy(temp_str, external_info->dir_pathname);
151 strcat(temp_str, "/");
152 strcat(temp_str, dir_entry->d_name);
153
154 err = stat(temp_str, &temp_stat);
155 if (err == -1) {
156 fprintf(stderr,
157 "Cannot stat file (should not happen) - %s\n",
158 temp_str);
159 free(temp_str);
160 return (NULL);
161 }
162
163 free(temp_str);
164
165 if ((S_ISDIR(temp_stat.st_mode)
166 && (external_info->requested_file_type ==
167 REQUEST_DIR_ONLY))
168 || ((!S_ISDIR(temp_stat.st_mode)
169 && external_info->requested_file_type ==
170 REQUEST_FILE_ONLY))) {
171
172 /* copy to a temp buffer because dir_entry struct is on the stack */
173
174 strcpy(external_info->temp_buffer,
175 dir_entry->d_name);
176 return (external_info->temp_buffer);
177 }
178 }
179 }
180
181 return (NULL);
182}
183
184/*******************************************************************************
185 *
186 * FUNCTION: acpi_os_close_directory
187 *
188 * PARAMETERS: dir_handle - Created via acpi_os_open_directory
189 *
190 * RETURN: None.
191 *
192 * DESCRIPTION: Close the open directory and cleanup.
193 *
194 ******************************************************************************/
195
196void acpi_os_close_directory(void *dir_handle)
197{
198 struct external_find_info *external_info = dir_handle;
199
200 /* Close the directory and free allocations */
201
202 closedir(external_info->dir_ptr);
203 free(dir_handle);
204}
diff --git a/tools/power/acpi/os_specific/service_layers/osunixmap.c b/tools/power/acpi/os_specific/service_layers/osunixmap.c
new file mode 100644
index 000000000000..99b47b6194a3
--- /dev/null
+++ b/tools/power/acpi/os_specific/service_layers/osunixmap.c
@@ -0,0 +1,151 @@
1/******************************************************************************
2 *
3 * Module Name: osunixmap - Unix OSL for file mappings
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include "acpidump.h"
45#include <unistd.h>
46#include <sys/mman.h>
47#ifdef _free_BSD
48#include <sys/param.h>
49#endif
50
51#define _COMPONENT ACPI_OS_SERVICES
52ACPI_MODULE_NAME("osunixmap")
53
54#ifndef O_BINARY
55#define O_BINARY 0
56#endif
57#ifdef _free_BSD
58#define MMAP_FLAGS MAP_SHARED
59#else
60#define MMAP_FLAGS MAP_PRIVATE
61#endif
62#define SYSTEM_MEMORY "/dev/mem"
63/*******************************************************************************
64 *
65 * FUNCTION: acpi_os_get_page_size
66 *
67 * PARAMETERS: None
68 *
69 * RETURN: Page size of the platform.
70 *
71 * DESCRIPTION: Obtain page size of the platform.
72 *
73 ******************************************************************************/
74static acpi_size acpi_os_get_page_size(void)
75{
76
77#ifdef PAGE_SIZE
78 return PAGE_SIZE;
79#else
80 return sysconf(_SC_PAGESIZE);
81#endif
82}
83
84/******************************************************************************
85 *
86 * FUNCTION: acpi_os_map_memory
87 *
88 * PARAMETERS: where - Physical address of memory to be mapped
89 * length - How much memory to map
90 *
91 * RETURN: Pointer to mapped memory. Null on error.
92 *
93 * DESCRIPTION: Map physical memory into local address space.
94 *
95 *****************************************************************************/
96
97void *acpi_os_map_memory(acpi_physical_address where, acpi_size length)
98{
99 u8 *mapped_memory;
100 acpi_physical_address offset;
101 acpi_size page_size;
102 int fd;
103
104 fd = open(SYSTEM_MEMORY, O_RDONLY | O_BINARY);
105 if (fd < 0) {
106 fprintf(stderr, "Cannot open %s\n", SYSTEM_MEMORY);
107 return (NULL);
108 }
109
110 /* Align the offset to use mmap */
111
112 page_size = acpi_os_get_page_size();
113 offset = where % page_size;
114
115 /* Map the table header to get the length of the full table */
116
117 mapped_memory = mmap(NULL, (length + offset), PROT_READ, MMAP_FLAGS,
118 fd, (where - offset));
119 if (mapped_memory == MAP_FAILED) {
120 fprintf(stderr, "Cannot map %s\n", SYSTEM_MEMORY);
121 close(fd);
122 return (NULL);
123 }
124
125 close(fd);
126 return (ACPI_CAST8(mapped_memory + offset));
127}
128
129/******************************************************************************
130 *
131 * FUNCTION: acpi_os_unmap_memory
132 *
133 * PARAMETERS: where - Logical address of memory to be unmapped
134 * length - How much memory to unmap
135 *
136 * RETURN: None.
137 *
138 * DESCRIPTION: Delete a previously created mapping. Where and Length must
139 * correspond to a previous mapping exactly.
140 *
141 *****************************************************************************/
142
143void acpi_os_unmap_memory(void *where, acpi_size length)
144{
145 acpi_physical_address offset;
146 acpi_size page_size;
147
148 page_size = acpi_os_get_page_size();
149 offset = (acpi_physical_address) where % page_size;
150 munmap((u8 *)where - offset, (length + offset));
151}
diff --git a/tools/power/acpi/tools/acpidump/acpidump.c b/tools/power/acpi/tools/acpidump/acpidump.c
deleted file mode 100644
index a84553a0e0df..000000000000
--- a/tools/power/acpi/tools/acpidump/acpidump.c
+++ /dev/null
@@ -1,559 +0,0 @@
1/*
2 * (c) Alexey Starikovskiy, Intel, 2005-2006.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions, and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * substantially similar to the "NO WARRANTY" disclaimer below
13 * ("Disclaimer") and any redistribution must be conditioned upon
14 * including a substantially similar Disclaimer requirement for further
15 * binary redistribution.
16 * 3. Neither the names of the above-listed copyright holders nor the names
17 * of any contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * NO WARRANTY
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
34 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGES.
36 */
37
38#ifdef DEFINE_ALTERNATE_TYPES
39/* hack to enable building old application with new headers -lenb */
40#define acpi_fadt_descriptor acpi_table_fadt
41#define acpi_rsdp_descriptor acpi_table_rsdp
42#define DSDT_SIG ACPI_SIG_DSDT
43#define FACS_SIG ACPI_SIG_FACS
44#define FADT_SIG ACPI_SIG_FADT
45#define xfirmware_ctrl Xfacs
46#define firmware_ctrl facs
47
48typedef int s32;
49typedef unsigned char u8;
50typedef unsigned short u16;
51typedef unsigned int u32;
52typedef unsigned long long u64;
53typedef long long s64;
54#endif
55
56#include <sys/mman.h>
57#include <sys/types.h>
58#include <sys/stat.h>
59#include <fcntl.h>
60#include <stdio.h>
61#include <string.h>
62#include <unistd.h>
63#include <getopt.h>
64
65#include <dirent.h>
66
67#include <acpi/acconfig.h>
68#include <acpi/platform/acenv.h>
69#include <acpi/actypes.h>
70#include <acpi/actbl.h>
71
72static inline u8 checksum(u8 * buffer, u32 length)
73{
74 u8 sum = 0, *i = buffer;
75 buffer += length;
76 for (; i < buffer; sum += *(i++));
77 return sum;
78}
79
80static unsigned long psz, addr, length;
81static int print, connect, skip;
82static u8 select_sig[4];
83
84static unsigned long read_efi_systab( void )
85{
86 char buffer[80];
87 unsigned long addr;
88 FILE *f = fopen("/sys/firmware/efi/systab", "r");
89 if (f) {
90 while (fgets(buffer, 80, f)) {
91 if (sscanf(buffer, "ACPI20=0x%lx", &addr) == 1)
92 return addr;
93 }
94 fclose(f);
95 }
96 return 0;
97}
98
99static u8 *acpi_map_memory(unsigned long where, unsigned length)
100{
101 unsigned long offset;
102 u8 *there;
103 int fd = open("/dev/mem", O_RDONLY);
104 if (fd < 0) {
105 fprintf(stderr, "acpi_os_map_memory: cannot open /dev/mem\n");
106 exit(1);
107 }
108 offset = where % psz;
109 there = mmap(NULL, length + offset, PROT_READ, MAP_PRIVATE,
110 fd, where - offset);
111 close(fd);
112 if (there == MAP_FAILED) return 0;
113 return (there + offset);
114}
115
116static void acpi_unmap_memory(u8 * there, unsigned length)
117{
118 unsigned long offset = (unsigned long)there % psz;
119 munmap(there - offset, length + offset);
120}
121
122static struct acpi_table_header *acpi_map_table(unsigned long where, char *sig)
123{
124 unsigned size;
125 struct acpi_table_header *tbl = (struct acpi_table_header *)
126 acpi_map_memory(where, sizeof(struct acpi_table_header));
127 if (!tbl || (sig && memcmp(sig, tbl->signature, 4))) return 0;
128 size = tbl->length;
129 acpi_unmap_memory((u8 *) tbl, sizeof(struct acpi_table_header));
130 return (struct acpi_table_header *)acpi_map_memory(where, size);
131}
132
133static void acpi_unmap_table(struct acpi_table_header *tbl)
134{
135 acpi_unmap_memory((u8 *)tbl, tbl->length);
136}
137
138static struct acpi_rsdp_descriptor *acpi_scan_for_rsdp(u8 *begin, u32 length)
139{
140 struct acpi_rsdp_descriptor *rsdp;
141 u8 *i, *end = begin + length;
142 /* Search from given start address for the requested length */
143 for (i = begin; i < end; i += ACPI_RSDP_SCAN_STEP) {
144 /* The signature and checksum must both be correct */
145 if (memcmp((char *)i, "RSD PTR ", 8)) continue;
146 rsdp = (struct acpi_rsdp_descriptor *)i;
147 /* Signature matches, check the appropriate checksum */
148 if (!checksum((u8 *) rsdp, (rsdp->revision < 2) ?
149 ACPI_RSDP_CHECKSUM_LENGTH :
150 ACPI_RSDP_XCHECKSUM_LENGTH))
151 /* Checksum valid, we have found a valid RSDP */
152 return rsdp;
153 }
154 /* Searched entire block, no RSDP was found */
155 return 0;
156}
157
158/*
159 * Output data
160 */
161static void acpi_show_data(int fd, u8 * data, int size)
162{
163 char buffer[256];
164 int len;
165 int i, remain = size;
166 while (remain > 0) {
167 len = snprintf(buffer, 256, " %04x:", size - remain);
168 for (i = 0; i < 16 && i < remain; i++) {
169 len +=
170 snprintf(&buffer[len], 256 - len, " %02x", data[i]);
171 }
172 for (; i < 16; i++) {
173 len += snprintf(&buffer[len], 256 - len, " ");
174 }
175 len += snprintf(&buffer[len], 256 - len, " ");
176 for (i = 0; i < 16 && i < remain; i++) {
177 buffer[len++] = (isprint(data[i])) ? data[i] : '.';
178 }
179 buffer[len++] = '\n';
180 write(fd, buffer, len);
181 data += 16;
182 remain -= 16;
183 }
184}
185
186/*
187 * Output ACPI table
188 */
189static void acpi_show_table(int fd, struct acpi_table_header *table, unsigned long addr)
190{
191 char buff[80];
192 int len = snprintf(buff, 80, "%.4s @ %p\n", table->signature, (void *)addr);
193 write(fd, buff, len);
194 acpi_show_data(fd, (u8 *) table, table->length);
195 buff[0] = '\n';
196 write(fd, buff, 1);
197}
198
199static void write_table(int fd, struct acpi_table_header *tbl, unsigned long addr)
200{
201 static int select_done = 0;
202 if (!select_sig[0]) {
203 if (print) {
204 acpi_show_table(fd, tbl, addr);
205 } else {
206 write(fd, tbl, tbl->length);
207 }
208 } else if (!select_done && !memcmp(select_sig, tbl->signature, 4)) {
209 if (skip > 0) {
210 --skip;
211 return;
212 }
213 if (print) {
214 acpi_show_table(fd, tbl, addr);
215 } else {
216 write(fd, tbl, tbl->length);
217 }
218 select_done = 1;
219 }
220}
221
222static void acpi_dump_FADT(int fd, struct acpi_table_header *tbl, unsigned long xaddr) {
223 struct acpi_fadt_descriptor x;
224 unsigned long addr;
225 size_t len = sizeof(struct acpi_fadt_descriptor);
226 if (len > tbl->length) len = tbl->length;
227 memcpy(&x, tbl, len);
228 x.header.length = len;
229 if (checksum((u8 *)tbl, len)) {
230 fprintf(stderr, "Wrong checksum for FADT!\n");
231 }
232 if (x.header.length >= 148 && x.Xdsdt) {
233 addr = (unsigned long)x.Xdsdt;
234 if (connect) {
235 x.Xdsdt = lseek(fd, 0, SEEK_CUR);
236 }
237 } else if (x.header.length >= 44 && x.dsdt) {
238 addr = (unsigned long)x.dsdt;
239 if (connect) {
240 x.dsdt = lseek(fd, 0, SEEK_CUR);
241 }
242 } else {
243 fprintf(stderr, "No DSDT in FADT!\n");
244 goto no_dsdt;
245 }
246 tbl = acpi_map_table(addr, DSDT_SIG);
247 if (!tbl) goto no_dsdt;
248 if (checksum((u8 *)tbl, tbl->length))
249 fprintf(stderr, "Wrong checksum for DSDT!\n");
250 write_table(fd, tbl, addr);
251 acpi_unmap_table(tbl);
252no_dsdt:
253 if (x.header.length >= 140 && x.xfirmware_ctrl) {
254 addr = (unsigned long)x.xfirmware_ctrl;
255 if (connect) {
256 x.xfirmware_ctrl = lseek(fd, 0, SEEK_CUR);
257 }
258 } else if (x.header.length >= 40 && x.firmware_ctrl) {
259 addr = (unsigned long)x.firmware_ctrl;
260 if (connect) {
261 x.firmware_ctrl = lseek(fd, 0, SEEK_CUR);
262 }
263 } else {
264 fprintf(stderr, "No FACS in FADT!\n");
265 goto no_facs;
266 }
267 tbl = acpi_map_table(addr, FACS_SIG);
268 if (!tbl) goto no_facs;
269 /* do not checksum FACS */
270 write_table(fd, tbl, addr);
271 acpi_unmap_table(tbl);
272no_facs:
273 write_table(fd, (struct acpi_table_header *)&x, xaddr);
274}
275
276static int acpi_dump_SDT(int fd, struct acpi_rsdp_descriptor *rsdp)
277{
278 struct acpi_table_header *sdt, *tbl = 0;
279 int xsdt = 1, i, num;
280 char *offset;
281 unsigned long addr;
282 if (rsdp->revision > 1 && rsdp->xsdt_physical_address) {
283 tbl = acpi_map_table(rsdp->xsdt_physical_address, "XSDT");
284 }
285 if (!tbl && rsdp->rsdt_physical_address) {
286 xsdt = 0;
287 tbl = acpi_map_table(rsdp->rsdt_physical_address, "RSDT");
288 }
289 if (!tbl) return 0;
290 sdt = malloc(tbl->length);
291 memcpy(sdt, tbl, tbl->length);
292 acpi_unmap_table(tbl);
293 if (checksum((u8 *)sdt, sdt->length))
294 fprintf(stderr, "Wrong checksum for %s!\n", (xsdt)?"XSDT":"RSDT");
295 num = (sdt->length - sizeof(struct acpi_table_header))/((xsdt)?sizeof(u64):sizeof(u32));
296 offset = (char *)sdt + sizeof(struct acpi_table_header);
297 for (i = 0; i < num; ++i, offset += ((xsdt) ? sizeof(u64) : sizeof(u32))) {
298 addr = (xsdt) ? (unsigned long)(*(u64 *)offset):
299 (unsigned long)(*(u32 *)offset);
300 if (!addr) continue;
301 tbl = acpi_map_table(addr, 0);
302 if (!tbl) continue;
303 if (!memcmp(tbl->signature, FADT_SIG, 4)) {
304 acpi_dump_FADT(fd, tbl, addr);
305 } else {
306 if (checksum((u8 *)tbl, tbl->length))
307 fprintf(stderr, "Wrong checksum for generic table!\n");
308 write_table(fd, tbl, addr);
309 }
310 acpi_unmap_table(tbl);
311 if (connect) {
312 if (xsdt)
313 (*(u64*)offset) = lseek(fd, 0, SEEK_CUR);
314 else
315 (*(u32*)offset) = lseek(fd, 0, SEEK_CUR);
316 }
317 }
318 if (xsdt) {
319 addr = (unsigned long)rsdp->xsdt_physical_address;
320 if (connect) {
321 rsdp->xsdt_physical_address = lseek(fd, 0, SEEK_CUR);
322 }
323 } else {
324 addr = (unsigned long)rsdp->rsdt_physical_address;
325 if (connect) {
326 rsdp->rsdt_physical_address = lseek(fd, 0, SEEK_CUR);
327 }
328 }
329 write_table(fd, sdt, addr);
330 free (sdt);
331 return 1;
332}
333
334#define DYNAMIC_SSDT "/sys/firmware/acpi/tables/dynamic"
335
336static void acpi_dump_dynamic_SSDT(int fd)
337{
338 struct stat file_stat;
339 char filename[256], *ptr;
340 DIR *tabledir;
341 struct dirent *entry;
342 FILE *fp;
343 int count, readcount, length;
344 struct acpi_table_header table_header, *ptable;
345
346 if (stat(DYNAMIC_SSDT, &file_stat) == -1) {
347 /* The directory doesn't exist */
348 return;
349 }
350 tabledir = opendir(DYNAMIC_SSDT);
351 if(!tabledir){
352 /*can't open the directory */
353 return;
354 }
355
356 while ((entry = readdir(tabledir)) != 0){
357 /* skip the file of . /.. */
358 if (entry->d_name[0] == '.')
359 continue;
360
361 sprintf(filename, "%s/%s", DYNAMIC_SSDT, entry->d_name);
362 fp = fopen(filename, "r");
363 if (fp == NULL) {
364 fprintf(stderr, "Can't open the file of %s\n",
365 filename);
366 continue;
367 }
368 /* Read the Table header to parse the table length */
369 count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp);
370 if (count < sizeof(table_header)) {
371 /* the length is lessn than ACPI table header. skip it */
372 fclose(fp);
373 continue;
374 }
375 length = table_header.length;
376 ptr = malloc(table_header.length);
377 fseek(fp, 0, SEEK_SET);
378 readcount = 0;
379 while(!feof(fp) && readcount < length) {
380 count = fread(ptr + readcount, 1, 256, fp);
381 readcount += count;
382 }
383 fclose(fp);
384 ptable = (struct acpi_table_header *) ptr;
385 if (checksum((u8 *) ptable, ptable->length))
386 fprintf(stderr, "Wrong checksum "
387 "for dynamic SSDT table!\n");
388 write_table(fd, ptable, 0);
389 free(ptr);
390 }
391 closedir(tabledir);
392 return;
393}
394
395static void usage(const char *progname)
396{
397 puts("Usage:");
398 printf("%s [--addr 0x1234][--table DSDT][--output filename]"
399 "[--binary][--length 0x456][--help]\n", progname);
400 puts("\t--addr 0x1234 or -a 0x1234 -- look for tables at this physical address");
401 puts("\t--table DSDT or -t DSDT -- only dump table with DSDT signature");
402 puts("\t--output filename or -o filename -- redirect output from stdin to filename");
403 puts("\t--binary or -b -- dump data in binary form rather than in hex-dump format");
404 puts("\t--length 0x456 or -l 0x456 -- works only with --addr, dump physical memory"
405 "\n\t\tregion without trying to understand it's contents");
406 puts("\t--skip 2 or -s 2 -- skip 2 tables of the given name and output only 3rd one");
407 puts("\t--help or -h -- this help message");
408 exit(0);
409}
410
411static struct option long_options[] = {
412 {"addr", 1, 0, 0},
413 {"table", 1, 0, 0},
414 {"output", 1, 0, 0},
415 {"binary", 0, 0, 0},
416 {"length", 1, 0, 0},
417 {"skip", 1, 0, 0},
418 {"help", 0, 0, 0},
419 {0, 0, 0, 0}
420};
421int main(int argc, char **argv)
422{
423 int option_index, c, fd;
424 u8 *raw;
425 struct acpi_rsdp_descriptor rsdpx, *x = 0;
426 char *filename = 0;
427 char buff[80];
428 memset(select_sig, 0, 4);
429 print = 1;
430 connect = 0;
431 addr = length = 0;
432 skip = 0;
433 while (1) {
434 option_index = 0;
435 c = getopt_long(argc, argv, "a:t:o:bl:s:h",
436 long_options, &option_index);
437 if (c == -1)
438 break;
439
440 switch (c) {
441 case 0:
442 switch (option_index) {
443 case 0:
444 addr = strtoul(optarg, (char **)NULL, 16);
445 break;
446 case 1:
447 memcpy(select_sig, optarg, 4);
448 break;
449 case 2:
450 filename = optarg;
451 break;
452 case 3:
453 print = 0;
454 break;
455 case 4:
456 length = strtoul(optarg, (char **)NULL, 16);
457 break;
458 case 5:
459 skip = strtoul(optarg, (char **)NULL, 10);
460 break;
461 case 6:
462 usage(argv[0]);
463 exit(0);
464 }
465 break;
466 case 'a':
467 addr = strtoul(optarg, (char **)NULL, 16);
468 break;
469 case 't':
470 memcpy(select_sig, optarg, 4);
471 break;
472 case 'o':
473 filename = optarg;
474 break;
475 case 'b':
476 print = 0;
477 break;
478 case 'l':
479 length = strtoul(optarg, (char **)NULL, 16);
480 break;
481 case 's':
482 skip = strtoul(optarg, (char **)NULL, 10);
483 break;
484 case 'h':
485 usage(argv[0]);
486 exit(0);
487 default:
488 printf("Unknown option!\n");
489 usage(argv[0]);
490 exit(0);
491 }
492 }
493
494 fd = STDOUT_FILENO;
495 if (filename) {
496 fd = creat(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
497 if (fd < 0)
498 return fd;
499 }
500
501 if (!select_sig[0] && !print) {
502 connect = 1;
503 }
504
505 psz = sysconf(_SC_PAGESIZE);
506 if (length && addr) {
507 /* We know length and address, it means we just want a memory dump */
508 if (!(raw = acpi_map_memory(addr, length)))
509 goto not_found;
510 write(fd, raw, length);
511 acpi_unmap_memory(raw, length);
512 close(fd);
513 return 0;
514 }
515
516 length = sizeof(struct acpi_rsdp_descriptor);
517 if (!addr) {
518 addr = read_efi_systab();
519 if (!addr) {
520 addr = ACPI_HI_RSDP_WINDOW_BASE;
521 length = ACPI_HI_RSDP_WINDOW_SIZE;
522 }
523 }
524
525 if (!(raw = acpi_map_memory(addr, length)) ||
526 !(x = acpi_scan_for_rsdp(raw, length)))
527 goto not_found;
528
529 /* Find RSDP and print all found tables */
530 memcpy(&rsdpx, x, sizeof(struct acpi_rsdp_descriptor));
531 acpi_unmap_memory(raw, length);
532 if (connect) {
533 lseek(fd, sizeof(struct acpi_rsdp_descriptor), SEEK_SET);
534 }
535 if (!acpi_dump_SDT(fd, &rsdpx))
536 goto not_found;
537 if (connect) {
538 lseek(fd, 0, SEEK_SET);
539 write(fd, x, (rsdpx.revision < 2) ?
540 ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
541 } else if (!select_sig[0] || !memcmp("RSD PTR ", select_sig, 4)) {
542 addr += (long)x - (long)raw;
543 length = snprintf(buff, 80, "RSD PTR @ %p\n", (void *)addr);
544 write(fd, buff, length);
545 acpi_show_data(fd, (u8 *) & rsdpx, (rsdpx.revision < 2) ?
546 ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
547 buff[0] = '\n';
548 write(fd, buff, 1);
549 }
550 acpi_dump_dynamic_SSDT(fd);
551 close(fd);
552 return 0;
553not_found:
554 close(fd);
555 fprintf(stderr, "ACPI tables were not found. If you know location "
556 "of RSD PTR table (from dmesg, etc), "
557 "supply it with either --addr or -a option\n");
558 return 1;
559}
diff --git a/tools/power/acpi/tools/acpidump/acpidump.h b/tools/power/acpi/tools/acpidump/acpidump.h
new file mode 100644
index 000000000000..46f519597fe5
--- /dev/null
+++ b/tools/power/acpi/tools/acpidump/acpidump.h
@@ -0,0 +1,130 @@
1/******************************************************************************
2 *
3 * Module Name: acpidump.h - Include file for acpi_dump utility
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44/*
45 * Global variables. Defined in main.c only, externed in all other files
46 */
47#ifdef _DECLARE_GLOBALS
48#define EXTERN
49#define INIT_GLOBAL(a,b) a=b
50#define DEFINE_ACPI_GLOBALS 1
51#else
52#define EXTERN extern
53#define INIT_GLOBAL(a,b) a
54#endif
55
56#include <acpi/acpi.h>
57#include "accommon.h"
58#include "actables.h"
59
60#include <stdio.h>
61#include <fcntl.h>
62#include <errno.h>
63#include <sys/stat.h>
64
65/* Globals */
66
67EXTERN u8 INIT_GLOBAL(gbl_summary_mode, FALSE);
68EXTERN u8 INIT_GLOBAL(gbl_verbose_mode, FALSE);
69EXTERN u8 INIT_GLOBAL(gbl_binary_mode, FALSE);
70EXTERN u8 INIT_GLOBAL(gbl_dump_customized_tables, FALSE);
71EXTERN u8 INIT_GLOBAL(gbl_do_not_dump_xsdt, FALSE);
72EXTERN FILE INIT_GLOBAL(*gbl_output_file, NULL);
73EXTERN char INIT_GLOBAL(*gbl_output_filename, NULL);
74EXTERN u64 INIT_GLOBAL(gbl_rsdp_base, 0);
75
76/* Globals required for use with ACPICA modules */
77
78#ifdef _DECLARE_GLOBALS
79u8 acpi_gbl_integer_byte_width = 8;
80#endif
81
82/* Action table used to defer requested options */
83
84struct ap_dump_action {
85 char *argument;
86 u32 to_be_done;
87};
88
89#define AP_MAX_ACTIONS 32
90
91#define AP_DUMP_ALL_TABLES 0
92#define AP_DUMP_TABLE_BY_ADDRESS 1
93#define AP_DUMP_TABLE_BY_NAME 2
94#define AP_DUMP_TABLE_BY_FILE 3
95
96#define AP_MAX_ACPI_FILES 256 /* Prevent infinite loops */
97
98/* Minimum FADT sizes for various table addresses */
99
100#define MIN_FADT_FOR_DSDT (ACPI_FADT_OFFSET (dsdt) + sizeof (u32))
101#define MIN_FADT_FOR_FACS (ACPI_FADT_OFFSET (facs) + sizeof (u32))
102#define MIN_FADT_FOR_XDSDT (ACPI_FADT_OFFSET (Xdsdt) + sizeof (u64))
103#define MIN_FADT_FOR_XFACS (ACPI_FADT_OFFSET (Xfacs) + sizeof (u64))
104
105/*
106 * apdump - Table get/dump routines
107 */
108int ap_dump_table_from_file(char *pathname);
109
110int ap_dump_table_by_name(char *signature);
111
112int ap_dump_table_by_address(char *ascii_address);
113
114int ap_dump_all_tables(void);
115
116u8 ap_is_valid_header(struct acpi_table_header *table);
117
118u8 ap_is_valid_checksum(struct acpi_table_header *table);
119
120u32 ap_get_table_length(struct acpi_table_header *table);
121
122/*
123 * apfiles - File I/O utilities
124 */
125int ap_open_output_file(char *pathname);
126
127int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance);
128
129struct acpi_table_header *ap_get_table_from_file(char *pathname,
130 u32 *file_size);
diff --git a/tools/power/acpi/tools/acpidump/apdump.c b/tools/power/acpi/tools/acpidump/apdump.c
new file mode 100644
index 000000000000..3cac12378366
--- /dev/null
+++ b/tools/power/acpi/tools/acpidump/apdump.c
@@ -0,0 +1,451 @@
1/******************************************************************************
2 *
3 * Module Name: apdump - Dump routines for ACPI tables (acpidump)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include "acpidump.h"
45
46/* Local prototypes */
47
48static int
49ap_dump_table_buffer(struct acpi_table_header *table,
50 u32 instance, acpi_physical_address address);
51
52/******************************************************************************
53 *
54 * FUNCTION: ap_is_valid_header
55 *
56 * PARAMETERS: table - Pointer to table to be validated
57 *
58 * RETURN: TRUE if the header appears to be valid. FALSE otherwise
59 *
60 * DESCRIPTION: Check for a valid ACPI table header
61 *
62 ******************************************************************************/
63
64u8 ap_is_valid_header(struct acpi_table_header *table)
65{
66
67 if (!ACPI_VALIDATE_RSDP_SIG(table->signature)) {
68
69 /* Make sure signature is all ASCII and a valid ACPI name */
70
71 if (!acpi_ut_valid_acpi_name(table->signature)) {
72 fprintf(stderr,
73 "Table signature (0x%8.8X) is invalid\n",
74 *(u32 *)table->signature);
75 return (FALSE);
76 }
77
78 /* Check for minimum table length */
79
80 if (table->length < sizeof(struct acpi_table_header)) {
81 fprintf(stderr, "Table length (0x%8.8X) is invalid\n",
82 table->length);
83 return (FALSE);
84 }
85 }
86
87 return (TRUE);
88}
89
90/******************************************************************************
91 *
92 * FUNCTION: ap_is_valid_checksum
93 *
94 * PARAMETERS: table - Pointer to table to be validated
95 *
96 * RETURN: TRUE if the checksum appears to be valid. FALSE otherwise.
97 *
98 * DESCRIPTION: Check for a valid ACPI table checksum.
99 *
100 ******************************************************************************/
101
102u8 ap_is_valid_checksum(struct acpi_table_header *table)
103{
104 acpi_status status;
105 struct acpi_table_rsdp *rsdp;
106
107 if (ACPI_VALIDATE_RSDP_SIG(table->signature)) {
108 /*
109 * Checksum for RSDP.
110 * Note: Other checksums are computed during the table dump.
111 */
112 rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table);
113 status = acpi_tb_validate_rsdp(rsdp);
114 } else {
115 status = acpi_tb_verify_checksum(table, table->length);
116 }
117
118 if (ACPI_FAILURE(status)) {
119 fprintf(stderr, "%4.4s: Warning: wrong checksum in table\n",
120 table->signature);
121 }
122
123 return (AE_OK);
124}
125
126/******************************************************************************
127 *
128 * FUNCTION: ap_get_table_length
129 *
130 * PARAMETERS: table - Pointer to the table
131 *
132 * RETURN: Table length
133 *
134 * DESCRIPTION: Obtain table length according to table signature.
135 *
136 ******************************************************************************/
137
138u32 ap_get_table_length(struct acpi_table_header *table)
139{
140 struct acpi_table_rsdp *rsdp;
141
142 /* Check if table is valid */
143
144 if (!ap_is_valid_header(table)) {
145 return (0);
146 }
147
148 if (ACPI_VALIDATE_RSDP_SIG(table->signature)) {
149 rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table);
150 return (rsdp->length);
151 }
152
153 /* Normal ACPI table */
154
155 return (table->length);
156}
157
158/******************************************************************************
159 *
160 * FUNCTION: ap_dump_table_buffer
161 *
162 * PARAMETERS: table - ACPI table to be dumped
163 * instance - ACPI table instance no. to be dumped
164 * address - Physical address of the table
165 *
166 * RETURN: None
167 *
168 * DESCRIPTION: Dump an ACPI table in standard ASCII hex format, with a
169 * header that is compatible with the acpi_xtract utility.
170 *
171 ******************************************************************************/
172
173static int
174ap_dump_table_buffer(struct acpi_table_header *table,
175 u32 instance, acpi_physical_address address)
176{
177 u32 table_length;
178
179 table_length = ap_get_table_length(table);
180
181 /* Print only the header if requested */
182
183 if (gbl_summary_mode) {
184 acpi_tb_print_table_header(address, table);
185 return (0);
186 }
187
188 /* Dump to binary file if requested */
189
190 if (gbl_binary_mode) {
191 return (ap_write_to_binary_file(table, instance));
192 }
193
194 /*
195 * Dump the table with header for use with acpixtract utility.
196 * Note: simplest to just always emit a 64-bit address. acpi_xtract
197 * utility can handle this.
198 */
199 printf("%4.4s @ 0x%8.8X%8.8X\n", table->signature,
200 ACPI_FORMAT_UINT64(address));
201
202 acpi_ut_dump_buffer(ACPI_CAST_PTR(u8, table), table_length,
203 DB_BYTE_DISPLAY, 0);
204 printf("\n");
205 return (0);
206}
207
208/******************************************************************************
209 *
210 * FUNCTION: ap_dump_all_tables
211 *
212 * PARAMETERS: None
213 *
214 * RETURN: Status
215 *
216 * DESCRIPTION: Get all tables from the RSDT/XSDT (or at least all of the
217 * tables that we can possibly get).
218 *
219 ******************************************************************************/
220
221int ap_dump_all_tables(void)
222{
223 struct acpi_table_header *table;
224 u32 instance = 0;
225 acpi_physical_address address;
226 acpi_status status;
227 int table_status;
228 u32 i;
229
230 /* Get and dump all available ACPI tables */
231
232 for (i = 0; i < AP_MAX_ACPI_FILES; i++) {
233 status =
234 acpi_os_get_table_by_index(i, &table, &instance, &address);
235 if (ACPI_FAILURE(status)) {
236
237 /* AE_LIMIT means that no more tables are available */
238
239 if (status == AE_LIMIT) {
240 return (0);
241 } else if (i == 0) {
242 fprintf(stderr,
243 "Could not get ACPI tables, %s\n",
244 acpi_format_exception(status));
245 return (-1);
246 } else {
247 fprintf(stderr,
248 "Could not get ACPI table at index %u, %s\n",
249 i, acpi_format_exception(status));
250 continue;
251 }
252 }
253
254 table_status = ap_dump_table_buffer(table, instance, address);
255 free(table);
256
257 if (table_status) {
258 break;
259 }
260 }
261
262 /* Something seriously bad happened if the loop terminates here */
263
264 return (-1);
265}
266
267/******************************************************************************
268 *
269 * FUNCTION: ap_dump_table_by_address
270 *
271 * PARAMETERS: ascii_address - Address for requested ACPI table
272 *
273 * RETURN: Status
274 *
275 * DESCRIPTION: Get an ACPI table via a physical address and dump it.
276 *
277 ******************************************************************************/
278
279int ap_dump_table_by_address(char *ascii_address)
280{
281 acpi_physical_address address;
282 struct acpi_table_header *table;
283 acpi_status status;
284 int table_status;
285 u64 long_address;
286
287 /* Convert argument to an integer physical address */
288
289 status = acpi_ut_strtoul64(ascii_address, 0, &long_address);
290 if (ACPI_FAILURE(status)) {
291 fprintf(stderr, "%s: Could not convert to a physical address\n",
292 ascii_address);
293 return (-1);
294 }
295
296 address = (acpi_physical_address) long_address;
297 status = acpi_os_get_table_by_address(address, &table);
298 if (ACPI_FAILURE(status)) {
299 fprintf(stderr, "Could not get table at 0x%8.8X%8.8X, %s\n",
300 ACPI_FORMAT_UINT64(address),
301 acpi_format_exception(status));
302 return (-1);
303 }
304
305 table_status = ap_dump_table_buffer(table, 0, address);
306 free(table);
307 return (table_status);
308}
309
310/******************************************************************************
311 *
312 * FUNCTION: ap_dump_table_by_name
313 *
314 * PARAMETERS: signature - Requested ACPI table signature
315 *
316 * RETURN: Status
317 *
318 * DESCRIPTION: Get an ACPI table via a signature and dump it. Handles
319 * multiple tables with the same signature (SSDTs).
320 *
321 ******************************************************************************/
322
323int ap_dump_table_by_name(char *signature)
324{
325 char local_signature[ACPI_NAME_SIZE + 1];
326 u32 instance;
327 struct acpi_table_header *table;
328 acpi_physical_address address;
329 acpi_status status;
330 int table_status;
331
332 if (strlen(signature) != ACPI_NAME_SIZE) {
333 fprintf(stderr,
334 "Invalid table signature [%s]: must be exactly 4 characters\n",
335 signature);
336 return (-1);
337 }
338
339 /* Table signatures are expected to be uppercase */
340
341 strcpy(local_signature, signature);
342 acpi_ut_strupr(local_signature);
343
344 /* To be friendly, handle tables whose signatures do not match the name */
345
346 if (ACPI_COMPARE_NAME(local_signature, "FADT")) {
347 strcpy(local_signature, ACPI_SIG_FADT);
348 } else if (ACPI_COMPARE_NAME(local_signature, "MADT")) {
349 strcpy(local_signature, ACPI_SIG_MADT);
350 }
351
352 /* Dump all instances of this signature (to handle multiple SSDTs) */
353
354 for (instance = 0; instance < AP_MAX_ACPI_FILES; instance++) {
355 status = acpi_os_get_table_by_name(local_signature, instance,
356 &table, &address);
357 if (ACPI_FAILURE(status)) {
358
359 /* AE_LIMIT means that no more tables are available */
360
361 if (status == AE_LIMIT) {
362 return (0);
363 }
364
365 fprintf(stderr,
366 "Could not get ACPI table with signature [%s], %s\n",
367 local_signature, acpi_format_exception(status));
368 return (-1);
369 }
370
371 table_status = ap_dump_table_buffer(table, instance, address);
372 free(table);
373
374 if (table_status) {
375 break;
376 }
377 }
378
379 /* Something seriously bad happened if the loop terminates here */
380
381 return (-1);
382}
383
384/******************************************************************************
385 *
386 * FUNCTION: ap_dump_table_from_file
387 *
388 * PARAMETERS: pathname - File containing the binary ACPI table
389 *
390 * RETURN: Status
391 *
392 * DESCRIPTION: Dump an ACPI table from a binary file
393 *
394 ******************************************************************************/
395
396int ap_dump_table_from_file(char *pathname)
397{
398 struct acpi_table_header *table;
399 u32 file_size = 0;
400 int table_status = -1;
401
402 /* Get the entire ACPI table from the file */
403
404 table = ap_get_table_from_file(pathname, &file_size);
405 if (!table) {
406 return (-1);
407 }
408
409 /* File must be at least as long as the table length */
410
411 if (table->length > file_size) {
412 fprintf(stderr,
413 "Table length (0x%X) is too large for input file (0x%X) %s\n",
414 table->length, file_size, pathname);
415 goto exit;
416 }
417
418 if (gbl_verbose_mode) {
419 fprintf(stderr,
420 "Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n",
421 pathname, table->signature, file_size, file_size);
422 }
423
424 table_status = ap_dump_table_buffer(table, 0, 0);
425
426exit:
427 free(table);
428 return (table_status);
429}
430
431/******************************************************************************
432 *
433 * FUNCTION: acpi_os* print functions
434 *
435 * DESCRIPTION: Used for linkage with ACPICA modules
436 *
437 ******************************************************************************/
438
439void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...)
440{
441 va_list args;
442
443 va_start(args, fmt);
444 vfprintf(stdout, fmt, args);
445 va_end(args);
446}
447
448void acpi_os_vprintf(const char *fmt, va_list args)
449{
450 vfprintf(stdout, fmt, args);
451}
diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c
new file mode 100644
index 000000000000..4488accc010b
--- /dev/null
+++ b/tools/power/acpi/tools/acpidump/apfiles.c
@@ -0,0 +1,228 @@
1/******************************************************************************
2 *
3 * Module Name: apfiles - File-related functions for acpidump utility
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include "acpidump.h"
45#include "acapps.h"
46
47/******************************************************************************
48 *
49 * FUNCTION: ap_open_output_file
50 *
51 * PARAMETERS: pathname - Output filename
52 *
53 * RETURN: Open file handle
54 *
55 * DESCRIPTION: Open a text output file for acpidump. Checks if file already
56 * exists.
57 *
58 ******************************************************************************/
59
60int ap_open_output_file(char *pathname)
61{
62 struct stat stat_info;
63 FILE *file;
64
65 /* If file exists, prompt for overwrite */
66
67 if (!stat(pathname, &stat_info)) {
68 fprintf(stderr,
69 "Target path already exists, overwrite? [y|n] ");
70
71 if (getchar() != 'y') {
72 return (-1);
73 }
74 }
75
76 /* Point stdout to the file */
77
78 file = freopen(pathname, "w", stdout);
79 if (!file) {
80 perror("Could not open output file");
81 return (-1);
82 }
83
84 /* Save the file and path */
85
86 gbl_output_file = file;
87 gbl_output_filename = pathname;
88 return (0);
89}
90
91/******************************************************************************
92 *
93 * FUNCTION: ap_write_to_binary_file
94 *
95 * PARAMETERS: table - ACPI table to be written
96 * instance - ACPI table instance no. to be written
97 *
98 * RETURN: Status
99 *
100 * DESCRIPTION: Write an ACPI table to a binary file. Builds the output
101 * filename from the table signature.
102 *
103 ******************************************************************************/
104
105int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)
106{
107 char filename[ACPI_NAME_SIZE + 16];
108 char instance_str[16];
109 FILE *file;
110 size_t actual;
111 u32 table_length;
112
113 /* Obtain table length */
114
115 table_length = ap_get_table_length(table);
116
117 /* Construct lower-case filename from the table local signature */
118
119 if (ACPI_VALIDATE_RSDP_SIG(table->signature)) {
120 ACPI_MOVE_NAME(filename, ACPI_RSDP_NAME);
121 } else {
122 ACPI_MOVE_NAME(filename, table->signature);
123 }
124 filename[0] = (char)ACPI_TOLOWER(filename[0]);
125 filename[1] = (char)ACPI_TOLOWER(filename[1]);
126 filename[2] = (char)ACPI_TOLOWER(filename[2]);
127 filename[3] = (char)ACPI_TOLOWER(filename[3]);
128 filename[ACPI_NAME_SIZE] = 0;
129
130 /* Handle multiple SSDts - create different filenames for each */
131
132 if (instance > 0) {
133 sprintf(instance_str, "%u", instance);
134 strcat(filename, instance_str);
135 }
136
137 strcat(filename, ACPI_TABLE_FILE_SUFFIX);
138
139 if (gbl_verbose_mode) {
140 fprintf(stderr,
141 "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n",
142 table->signature, filename, table->length,
143 table->length);
144 }
145
146 /* Open the file and dump the entire table in binary mode */
147
148 file = fopen(filename, "wb");
149 if (!file) {
150 perror("Could not open output file");
151 return (-1);
152 }
153
154 actual = fwrite(table, 1, table_length, file);
155 if (actual != table_length) {
156 perror("Error writing binary output file");
157 fclose(file);
158 return (-1);
159 }
160
161 fclose(file);
162 return (0);
163}
164
165/******************************************************************************
166 *
167 * FUNCTION: ap_get_table_from_file
168 *
169 * PARAMETERS: pathname - File containing the binary ACPI table
170 * out_file_size - Where the file size is returned
171 *
172 * RETURN: Buffer containing the ACPI table. NULL on error.
173 *
174 * DESCRIPTION: Open a file and read it entirely into a new buffer
175 *
176 ******************************************************************************/
177
178struct acpi_table_header *ap_get_table_from_file(char *pathname,
179 u32 *out_file_size)
180{
181 struct acpi_table_header *buffer = NULL;
182 FILE *file;
183 u32 file_size;
184 size_t actual;
185
186 /* Must use binary mode */
187
188 file = fopen(pathname, "rb");
189 if (!file) {
190 perror("Could not open input file");
191 return (NULL);
192 }
193
194 /* Need file size to allocate a buffer */
195
196 file_size = cm_get_file_size(file);
197 if (file_size == ACPI_UINT32_MAX) {
198 fprintf(stderr,
199 "Could not get input file size: %s\n", pathname);
200 goto cleanup;
201 }
202
203 /* Allocate a buffer for the entire file */
204
205 buffer = calloc(1, file_size);
206 if (!buffer) {
207 fprintf(stderr,
208 "Could not allocate file buffer of size: %u\n",
209 file_size);
210 goto cleanup;
211 }
212
213 /* Read the entire file */
214
215 actual = fread(buffer, 1, file_size, file);
216 if (actual != file_size) {
217 fprintf(stderr, "Could not read input file: %s\n", pathname);
218 free(buffer);
219 buffer = NULL;
220 goto cleanup;
221 }
222
223 *out_file_size = file_size;
224
225cleanup:
226 fclose(file);
227 return (buffer);
228}
diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c
new file mode 100644
index 000000000000..51e8d638db18
--- /dev/null
+++ b/tools/power/acpi/tools/acpidump/apmain.c
@@ -0,0 +1,351 @@
1/******************************************************************************
2 *
3 * Module Name: apmain - Main module for the acpidump utility
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#define _DECLARE_GLOBALS
45#include "acpidump.h"
46#include "acapps.h"
47
48/*
49 * acpidump - A portable utility for obtaining system ACPI tables and dumping
50 * them in an ASCII hex format suitable for binary extraction via acpixtract.
51 *
52 * Obtaining the system ACPI tables is an OS-specific operation.
53 *
54 * This utility can be ported to any host operating system by providing a
55 * module containing system-specific versions of these interfaces:
56 *
57 * acpi_os_get_table_by_address
58 * acpi_os_get_table_by_index
59 * acpi_os_get_table_by_name
60 *
61 * See the ACPICA Reference Guide for the exact definitions of these
62 * interfaces. Also, see these ACPICA source code modules for example
63 * implementations:
64 *
65 * source/os_specific/service_layers/oswintbl.c
66 * source/os_specific/service_layers/oslinuxtbl.c
67 */
68
69/* Local prototypes */
70
71static void ap_display_usage(void);
72
73static int ap_do_options(int argc, char **argv);
74
75static void ap_insert_action(char *argument, u32 to_be_done);
76
77/* Table for deferred actions from command line options */
78
79struct ap_dump_action action_table[AP_MAX_ACTIONS];
80u32 current_action = 0;
81
82#define AP_UTILITY_NAME "ACPI Binary Table Dump Utility"
83#define AP_SUPPORTED_OPTIONS "?a:bcf:hn:o:r:svxz"
84
85/******************************************************************************
86 *
87 * FUNCTION: ap_display_usage
88 *
89 * DESCRIPTION: Usage message for the acpi_dump utility
90 *
91 ******************************************************************************/
92
93static void ap_display_usage(void)
94{
95
96 ACPI_USAGE_HEADER("acpidump [options]");
97
98 ACPI_OPTION("-b", "Dump tables to binary files");
99 ACPI_OPTION("-c", "Dump customized tables");
100 ACPI_OPTION("-h -?", "This help message");
101 ACPI_OPTION("-o <File>", "Redirect output to file");
102 ACPI_OPTION("-r <Address>", "Dump tables from specified RSDP");
103 ACPI_OPTION("-s", "Print table summaries only");
104 ACPI_OPTION("-v", "Display version information");
105 ACPI_OPTION("-z", "Verbose mode");
106
107 printf("\nTable Options:\n");
108
109 ACPI_OPTION("-a <Address>", "Get table via a physical address");
110 ACPI_OPTION("-f <BinaryFile>", "Get table via a binary file");
111 ACPI_OPTION("-n <Signature>", "Get table via a name/signature");
112 ACPI_OPTION("-x", "Do not use but dump XSDT");
113 ACPI_OPTION("-x -x", "Do not use or dump XSDT");
114
115 printf("\n"
116 "Invocation without parameters dumps all available tables\n"
117 "Multiple mixed instances of -a, -f, and -n are supported\n\n");
118}
119
120/******************************************************************************
121 *
122 * FUNCTION: ap_insert_action
123 *
124 * PARAMETERS: argument - Pointer to the argument for this action
125 * to_be_done - What to do to process this action
126 *
127 * RETURN: None. Exits program if action table becomes full.
128 *
129 * DESCRIPTION: Add an action item to the action table
130 *
131 ******************************************************************************/
132
133static void ap_insert_action(char *argument, u32 to_be_done)
134{
135
136 /* Insert action and check for table overflow */
137
138 action_table[current_action].argument = argument;
139 action_table[current_action].to_be_done = to_be_done;
140
141 current_action++;
142 if (current_action > AP_MAX_ACTIONS) {
143 fprintf(stderr, "Too many table options (max %u)\n",
144 AP_MAX_ACTIONS);
145 exit(-1);
146 }
147}
148
149/******************************************************************************
150 *
151 * FUNCTION: ap_do_options
152 *
153 * PARAMETERS: argc/argv - Standard argc/argv
154 *
155 * RETURN: Status
156 *
157 * DESCRIPTION: Command line option processing. The main actions for getting
158 * and dumping tables are deferred via the action table.
159 *
160 *****************************************************************************/
161
162static int ap_do_options(int argc, char **argv)
163{
164 int j;
165 acpi_status status;
166
167 /* Command line options */
168
169 while ((j = acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != EOF)
170 switch (j) {
171 /*
172 * Global options
173 */
174 case 'b': /* Dump all input tables to binary files */
175
176 gbl_binary_mode = TRUE;
177 continue;
178
179 case 'c': /* Dump customized tables */
180
181 gbl_dump_customized_tables = TRUE;
182 continue;
183
184 case 'h':
185 case '?':
186
187 ap_display_usage();
188 exit(0);
189
190 case 'o': /* Redirect output to a single file */
191
192 if (ap_open_output_file(acpi_gbl_optarg)) {
193 exit(-1);
194 }
195 continue;
196
197 case 'r': /* Dump tables from specified RSDP */
198
199 status =
200 acpi_ut_strtoul64(acpi_gbl_optarg, 0,
201 &gbl_rsdp_base);
202 if (ACPI_FAILURE(status)) {
203 fprintf(stderr,
204 "%s: Could not convert to a physical address\n",
205 acpi_gbl_optarg);
206 exit(-1);
207 }
208 continue;
209
210 case 's': /* Print table summaries only */
211
212 gbl_summary_mode = TRUE;
213 continue;
214
215 case 'x': /* Do not use XSDT */
216
217 if (!acpi_gbl_do_not_use_xsdt) {
218 acpi_gbl_do_not_use_xsdt = TRUE;
219 } else {
220 gbl_do_not_dump_xsdt = TRUE;
221 }
222 continue;
223
224 case 'v': /* Revision/version */
225
226 printf(ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
227 exit(0);
228
229 case 'z': /* Verbose mode */
230
231 gbl_verbose_mode = TRUE;
232 fprintf(stderr, ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
233 continue;
234
235 /*
236 * Table options
237 */
238 case 'a': /* Get table by physical address */
239
240 ap_insert_action(acpi_gbl_optarg,
241 AP_DUMP_TABLE_BY_ADDRESS);
242 break;
243
244 case 'f': /* Get table from a file */
245
246 ap_insert_action(acpi_gbl_optarg,
247 AP_DUMP_TABLE_BY_FILE);
248 break;
249
250 case 'n': /* Get table by input name (signature) */
251
252 ap_insert_action(acpi_gbl_optarg,
253 AP_DUMP_TABLE_BY_NAME);
254 break;
255
256 default:
257
258 ap_display_usage();
259 exit(-1);
260 }
261
262 /* If there are no actions, this means "get/dump all tables" */
263
264 if (current_action == 0) {
265 ap_insert_action(NULL, AP_DUMP_ALL_TABLES);
266 }
267
268 return (0);
269}
270
271/******************************************************************************
272 *
273 * FUNCTION: main
274 *
275 * PARAMETERS: argc/argv - Standard argc/argv
276 *
277 * RETURN: Status
278 *
279 * DESCRIPTION: C main function for acpidump utility
280 *
281 ******************************************************************************/
282
283int ACPI_SYSTEM_XFACE main(int argc, char *argv[])
284{
285 int status = 0;
286 struct ap_dump_action *action;
287 u32 file_size;
288 u32 i;
289
290 ACPI_DEBUG_INITIALIZE(); /* For debug version only */
291
292 /* Process command line options */
293
294 if (ap_do_options(argc, argv)) {
295 return (-1);
296 }
297
298 /* Get/dump ACPI table(s) as requested */
299
300 for (i = 0; i < current_action; i++) {
301 action = &action_table[i];
302 switch (action->to_be_done) {
303 case AP_DUMP_ALL_TABLES:
304
305 status = ap_dump_all_tables();
306 break;
307
308 case AP_DUMP_TABLE_BY_ADDRESS:
309
310 status = ap_dump_table_by_address(action->argument);
311 break;
312
313 case AP_DUMP_TABLE_BY_NAME:
314
315 status = ap_dump_table_by_name(action->argument);
316 break;
317
318 case AP_DUMP_TABLE_BY_FILE:
319
320 status = ap_dump_table_from_file(action->argument);
321 break;
322
323 default:
324
325 fprintf(stderr,
326 "Internal error, invalid action: 0x%X\n",
327 action->to_be_done);
328 return (-1);
329 }
330
331 if (status) {
332 return (status);
333 }
334 }
335
336 if (gbl_output_file) {
337 if (gbl_verbose_mode) {
338
339 /* Summary for the output file */
340
341 file_size = cm_get_file_size(gbl_output_file);
342 fprintf(stderr,
343 "Output file %s contains 0x%X (%u) bytes\n\n",
344 gbl_output_filename, file_size, file_size);
345 }
346
347 fclose(gbl_output_file);
348 }
349
350 return (status);
351}
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile
index cbfec92af327..2e2ba2efa0d9 100644
--- a/tools/power/cpupower/Makefile
+++ b/tools/power/cpupower/Makefile
@@ -62,7 +62,7 @@ LIB_MAJ= 0.0.0
62LIB_MIN= 0 62LIB_MIN= 0
63 63
64PACKAGE = cpupower 64PACKAGE = cpupower
65PACKAGE_BUGREPORT = cpufreq@vger.kernel.org 65PACKAGE_BUGREPORT = linux-pm@vger.kernel.org
66LANGUAGES = de fr it cs pt 66LANGUAGES = de fr it cs pt
67 67
68 68
@@ -274,6 +274,8 @@ install-man:
274 $(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1 274 $(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1
275 $(INSTALL_DATA) -D man/cpupower-frequency-set.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-set.1 275 $(INSTALL_DATA) -D man/cpupower-frequency-set.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-set.1
276 $(INSTALL_DATA) -D man/cpupower-frequency-info.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-info.1 276 $(INSTALL_DATA) -D man/cpupower-frequency-info.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-info.1
277 $(INSTALL_DATA) -D man/cpupower-idle-set.1 $(DESTDIR)${mandir}/man1/cpupower-idle-set.1
278 $(INSTALL_DATA) -D man/cpupower-idle-info.1 $(DESTDIR)${mandir}/man1/cpupower-idle-info.1
277 $(INSTALL_DATA) -D man/cpupower-set.1 $(DESTDIR)${mandir}/man1/cpupower-set.1 279 $(INSTALL_DATA) -D man/cpupower-set.1 $(DESTDIR)${mandir}/man1/cpupower-set.1
278 $(INSTALL_DATA) -D man/cpupower-info.1 $(DESTDIR)${mandir}/man1/cpupower-info.1 280 $(INSTALL_DATA) -D man/cpupower-info.1 $(DESTDIR)${mandir}/man1/cpupower-info.1
279 $(INSTALL_DATA) -D man/cpupower-monitor.1 $(DESTDIR)${mandir}/man1/cpupower-monitor.1 281 $(INSTALL_DATA) -D man/cpupower-monitor.1 $(DESTDIR)${mandir}/man1/cpupower-monitor.1
@@ -295,8 +297,12 @@ uninstall:
295 - rm -f $(DESTDIR)${libdir}/libcpupower.* 297 - rm -f $(DESTDIR)${libdir}/libcpupower.*
296 - rm -f $(DESTDIR)${includedir}/cpufreq.h 298 - rm -f $(DESTDIR)${includedir}/cpufreq.h
297 - rm -f $(DESTDIR)${bindir}/utils/cpupower 299 - rm -f $(DESTDIR)${bindir}/utils/cpupower
298 - rm -f $(DESTDIR)${mandir}/man1/cpufreq-set.1 300 - rm -f $(DESTDIR)${mandir}/man1/cpupower.1
299 - rm -f $(DESTDIR)${mandir}/man1/cpufreq-info.1 301 - rm -f $(DESTDIR)${mandir}/man1/cpupower-frequency-set.1
302 - rm -f $(DESTDIR)${mandir}/man1/cpupower-frequency-info.1
303 - rm -f $(DESTDIR)${mandir}/man1/cpupower-set.1
304 - rm -f $(DESTDIR)${mandir}/man1/cpupower-info.1
305 - rm -f $(DESTDIR)${mandir}/man1/cpupower-monitor.1
300 - for HLANG in $(LANGUAGES); do \ 306 - for HLANG in $(LANGUAGES); do \
301 rm -f $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \ 307 rm -f $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \
302 done; 308 done;
diff --git a/tools/power/cpupower/README b/tools/power/cpupower/README
index fd9d4c0d6688..1c68f47663b2 100644
--- a/tools/power/cpupower/README
+++ b/tools/power/cpupower/README
@@ -1,6 +1,4 @@
1The cpufrequtils package (homepage: 1The cpupower package consists of the following elements:
2http://www.kernel.org/pub/linux/utils/kernel/cpufreq/cpufrequtils.html )
3consists of the following elements:
4 2
5requirements 3requirements
6------------ 4------------
@@ -11,10 +9,10 @@ providing cpuid.h is needed.
11For both it's not explicitly checked for (yet). 9For both it's not explicitly checked for (yet).
12 10
13 11
14libcpufreq 12libcpupower
15---------- 13----------
16 14
17"libcpufreq" is a library which offers a unified access method for userspace 15"libcpupower" is a library which offers a unified access method for userspace
18tools and programs to the cpufreq core and drivers in the Linux kernel. This 16tools and programs to the cpufreq core and drivers in the Linux kernel. This
19allows for code reduction in userspace tools, a clean implementation of 17allows for code reduction in userspace tools, a clean implementation of
20the interaction to the cpufreq core, and support for both the sysfs and proc 18the interaction to the cpufreq core, and support for both the sysfs and proc
@@ -28,22 +26,22 @@ make
28su 26su
29make install 27make install
30 28
31should suffice on most systems. It builds default libcpufreq, 29should suffice on most systems. It builds libcpupower to put in
32cpufreq-set and cpufreq-info files and installs them in /usr/lib and 30/usr/lib; cpupower, cpufreq-bench_plot.sh to put in /usr/bin; and
33/usr/bin, respectively. If you want to set up the paths differently and/or 31cpufreq-bench to put in /usr/sbin. If you want to set up the paths
34want to configure the package to your specific needs, you need to open 32differently and/or want to configure the package to your specific
35"Makefile" with an editor of your choice and edit the block marked 33needs, you need to open "Makefile" with an editor of your choice and
36CONFIGURATION. 34edit the block marked CONFIGURATION.
37 35
38 36
39THANKS 37THANKS
40------ 38------
41Many thanks to Mattia Dongili who wrote the autotoolization and 39Many thanks to Mattia Dongili who wrote the autotoolization and
42libtoolization, the manpages and the italian language file for cpufrequtils; 40libtoolization, the manpages and the italian language file for cpupower;
43to Dave Jones for his feedback and his dump_psb tool; to Bruno Ducrot for his 41to Dave Jones for his feedback and his dump_psb tool; to Bruno Ducrot for his
44powernow-k8-decode and intel_gsic tools as well as the french language file; 42powernow-k8-decode and intel_gsic tools as well as the french language file;
45and to various others commenting on the previous (pre-)releases of 43and to various others commenting on the previous (pre-)releases of
46cpufrequtils. 44cpupower.
47 45
48 46
49 Dominik Brodowski 47 Dominik Brodowski
diff --git a/tools/power/cpupower/ToDo b/tools/power/cpupower/ToDo
index 874b78b586ee..6e8b89f282e6 100644
--- a/tools/power/cpupower/ToDo
+++ b/tools/power/cpupower/ToDo
@@ -3,7 +3,6 @@ ToDos sorted by priority:
3- Use bitmask functions to parse CPU topology more robust 3- Use bitmask functions to parse CPU topology more robust
4 (current implementation has issues on AMD) 4 (current implementation has issues on AMD)
5- Try to read out boost states and frequencies on Intel 5- Try to read out boost states and frequencies on Intel
6- Adjust README
7- Somewhere saw the ability to read power consumption of 6- Somewhere saw the ability to read power consumption of
8 RAM from HW on Intel SandyBridge -> another monitor? 7 RAM from HW on Intel SandyBridge -> another monitor?
9- Add another c1e debug idle monitor 8- Add another c1e debug idle monitor
diff --git a/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c b/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c
index 0f10b81e3322..5224ee5b392d 100644
--- a/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c
+++ b/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c
@@ -18,7 +18,7 @@
18 * 5.) if the third value, "diff_pmtmr", changes between 2. and 4., the 18 * 5.) if the third value, "diff_pmtmr", changes between 2. and 4., the
19 * TSC-based delay routine on the Linux kernel does not correctly 19 * TSC-based delay routine on the Linux kernel does not correctly
20 * handle the cpufreq transition. Please report this to 20 * handle the cpufreq transition. Please report this to
21 * cpufreq@vger.kernel.org 21 * linux-pm@vger.kernel.org
22 */ 22 */
23 23
24#include <linux/kernel.h> 24#include <linux/kernel.h>
diff --git a/tools/power/cpupower/man/cpupower-frequency-info.1 b/tools/power/cpupower/man/cpupower-frequency-info.1
index 4a1918ea8f9c..9c85a382e355 100644
--- a/tools/power/cpupower/man/cpupower-frequency-info.1
+++ b/tools/power/cpupower/man/cpupower-frequency-info.1
@@ -50,6 +50,9 @@ Prints out information like provided by the /proc/cpufreq interface in 2.4. and
50\fB\-m\fR \fB\-\-human\fR 50\fB\-m\fR \fB\-\-human\fR
51human\-readable output for the \-f, \-w, \-s and \-y parameters. 51human\-readable output for the \-f, \-w, \-s and \-y parameters.
52.TP 52.TP
53\fB\-n\fR \fB\-\-no-rounding\fR
54Output frequencies and latencies without rounding off values.
55.TP
53.SH "REMARKS" 56.SH "REMARKS"
54.LP 57.LP
55By default only values of core zero are displayed. How to display settings of 58By default only values of core zero are displayed. How to display settings of
diff --git a/tools/power/cpupower/man/cpupower-idle-set.1 b/tools/power/cpupower/man/cpupower-idle-set.1
index 6b1607272a5b..3e6799d7a79f 100644
--- a/tools/power/cpupower/man/cpupower-idle-set.1
+++ b/tools/power/cpupower/man/cpupower-idle-set.1
@@ -13,11 +13,17 @@ sleep states. This can be handy for power vs performance tuning.
13.SH "OPTIONS" 13.SH "OPTIONS"
14.LP 14.LP
15.TP 15.TP
16\fB\-d\fR \fB\-\-disable\fR 16\fB\-d\fR \fB\-\-disable\fR <STATE_NO>
17Disable a specific processor sleep state. 17Disable a specific processor sleep state.
18.TP 18.TP
19\fB\-e\fR \fB\-\-enable\fR 19\fB\-e\fR \fB\-\-enable\fR <STATE_NO>
20Enable a specific processor sleep state. 20Enable a specific processor sleep state.
21.TP
22\fB\-D\fR \fB\-\-disable-by-latency\fR <LATENCY>
23Disable all idle states with a equal or higher latency than <LATENCY>
24.TP
25\fB\-E\fR \fB\-\-enable-all\fR
26Enable all idle states if not enabled already.
21 27
22.SH "REMARKS" 28.SH "REMARKS"
23.LP 29.LP
diff --git a/tools/power/cpupower/man/cpupower-info.1 b/tools/power/cpupower/man/cpupower-info.1
index 58e21196f17f..340bcd0be7de 100644
--- a/tools/power/cpupower/man/cpupower-info.1
+++ b/tools/power/cpupower/man/cpupower-info.1
@@ -3,7 +3,7 @@
3cpupower\-info \- Shows processor power related kernel or hardware configurations 3cpupower\-info \- Shows processor power related kernel or hardware configurations
4.SH SYNOPSIS 4.SH SYNOPSIS
5.ft B 5.ft B
6.B cpupower info [ \-b ] [ \-s ] [ \-m ] 6.B cpupower info [ \-b ]
7 7
8.SH DESCRIPTION 8.SH DESCRIPTION
9\fBcpupower info \fP shows kernel configurations or processor hardware 9\fBcpupower info \fP shows kernel configurations or processor hardware
diff --git a/tools/power/cpupower/man/cpupower-set.1 b/tools/power/cpupower/man/cpupower-set.1
index 9dbd536518ab..2bcc696f4496 100644
--- a/tools/power/cpupower/man/cpupower-set.1
+++ b/tools/power/cpupower/man/cpupower-set.1
@@ -3,7 +3,7 @@
3cpupower\-set \- Set processor power related kernel or hardware configurations 3cpupower\-set \- Set processor power related kernel or hardware configurations
4.SH SYNOPSIS 4.SH SYNOPSIS
5.ft B 5.ft B
6.B cpupower set [ \-b VAL ] [ \-s VAL ] [ \-m VAL ] 6.B cpupower set [ \-b VAL ]
7 7
8 8
9.SH DESCRIPTION 9.SH DESCRIPTION
@@ -55,35 +55,6 @@ Use \fBcpupower -c all info -b\fP to verify.
55 55
56This options needs the msr kernel driver (CONFIG_X86_MSR) loaded. 56This options needs the msr kernel driver (CONFIG_X86_MSR) loaded.
57.RE 57.RE
58.PP
59\-\-sched\-mc, \-m [ VAL ]
60.RE
61\-\-sched\-smt, \-s [ VAL ]
62.RS 4
63\-\-sched\-mc utilizes cores in one processor package/socket first before
64processes are scheduled to other processor packages/sockets.
65
66\-\-sched\-smt utilizes thread siblings of one processor core first before
67processes are scheduled to other cores.
68
69The impact on power consumption and performance (positiv or negativ) heavily
70depends on processor support for deep sleep states, frequency scaling and
71frequency boost modes and their dependencies between other thread siblings
72and processor cores.
73
74Taken over from kernel documentation:
75
76Adjust the kernel's multi-core scheduler support.
77
78Possible values are:
79.RS 2
800 - No power saving load balance (default value)
81
821 - Fill one thread/core/package first for long running threads
83
842 - Also bias task wakeups to semi-idle cpu package for power
85savings
86.RE
87 58
88.SH "SEE ALSO" 59.SH "SEE ALSO"
89cpupower-info(1), cpupower-monitor(1), powertop(1) 60cpupower-info(1), cpupower-monitor(1), powertop(1)
diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c
index 28953c9a7bd5..b4b90a97662c 100644
--- a/tools/power/cpupower/utils/cpufreq-info.c
+++ b/tools/power/cpupower/utils/cpufreq-info.c
@@ -82,29 +82,42 @@ static void proc_cpufreq_output(void)
82 } 82 }
83} 83}
84 84
85static int no_rounding;
85static void print_speed(unsigned long speed) 86static void print_speed(unsigned long speed)
86{ 87{
87 unsigned long tmp; 88 unsigned long tmp;
88 89
89 if (speed > 1000000) { 90 if (no_rounding) {
90 tmp = speed % 10000; 91 if (speed > 1000000)
91 if (tmp >= 5000) 92 printf("%u.%06u GHz", ((unsigned int) speed/1000000),
92 speed += 10000; 93 ((unsigned int) speed%1000000));
93 printf("%u.%02u GHz", ((unsigned int) speed/1000000), 94 else if (speed > 100000)
94 ((unsigned int) (speed%1000000)/10000)); 95 printf("%u MHz", (unsigned int) speed);
95 } else if (speed > 100000) { 96 else if (speed > 1000)
96 tmp = speed % 1000; 97 printf("%u.%03u MHz", ((unsigned int) speed/1000),
97 if (tmp >= 500) 98 (unsigned int) (speed%1000));
98 speed += 1000; 99 else
99 printf("%u MHz", ((unsigned int) speed / 1000)); 100 printf("%lu kHz", speed);
100 } else if (speed > 1000) { 101 } else {
101 tmp = speed % 100; 102 if (speed > 1000000) {
102 if (tmp >= 50) 103 tmp = speed%10000;
103 speed += 100; 104 if (tmp >= 5000)
104 printf("%u.%01u MHz", ((unsigned int) speed/1000), 105 speed += 10000;
105 ((unsigned int) (speed%1000)/100)); 106 printf("%u.%02u GHz", ((unsigned int) speed/1000000),
106 } else 107 ((unsigned int) (speed%1000000)/10000));
107 printf("%lu kHz", speed); 108 } else if (speed > 100000) {
109 tmp = speed%1000;
110 if (tmp >= 500)
111 speed += 1000;
112 printf("%u MHz", ((unsigned int) speed/1000));
113 } else if (speed > 1000) {
114 tmp = speed%100;
115 if (tmp >= 50)
116 speed += 100;
117 printf("%u.%01u MHz", ((unsigned int) speed/1000),
118 ((unsigned int) (speed%1000)/100));
119 }
120 }
108 121
109 return; 122 return;
110} 123}
@@ -113,26 +126,38 @@ static void print_duration(unsigned long duration)
113{ 126{
114 unsigned long tmp; 127 unsigned long tmp;
115 128
116 if (duration > 1000000) { 129 if (no_rounding) {
117 tmp = duration % 10000; 130 if (duration > 1000000)
118 if (tmp >= 5000) 131 printf("%u.%06u ms", ((unsigned int) duration/1000000),
119 duration += 10000; 132 ((unsigned int) duration%1000000));
120 printf("%u.%02u ms", ((unsigned int) duration/1000000), 133 else if (duration > 100000)
121 ((unsigned int) (duration%1000000)/10000)); 134 printf("%u us", ((unsigned int) duration/1000));
122 } else if (duration > 100000) { 135 else if (duration > 1000)
123 tmp = duration % 1000; 136 printf("%u.%03u us", ((unsigned int) duration/1000),
124 if (tmp >= 500) 137 ((unsigned int) duration%1000));
125 duration += 1000; 138 else
126 printf("%u us", ((unsigned int) duration / 1000)); 139 printf("%lu ns", duration);
127 } else if (duration > 1000) { 140 } else {
128 tmp = duration % 100; 141 if (duration > 1000000) {
129 if (tmp >= 50) 142 tmp = duration%10000;
130 duration += 100; 143 if (tmp >= 5000)
131 printf("%u.%01u us", ((unsigned int) duration/1000), 144 duration += 10000;
132 ((unsigned int) (duration%1000)/100)); 145 printf("%u.%02u ms", ((unsigned int) duration/1000000),
133 } else 146 ((unsigned int) (duration%1000000)/10000));
134 printf("%lu ns", duration); 147 } else if (duration > 100000) {
135 148 tmp = duration%1000;
149 if (tmp >= 500)
150 duration += 1000;
151 printf("%u us", ((unsigned int) duration / 1000));
152 } else if (duration > 1000) {
153 tmp = duration%100;
154 if (tmp >= 50)
155 duration += 100;
156 printf("%u.%01u us", ((unsigned int) duration/1000),
157 ((unsigned int) (duration%1000)/100));
158 } else
159 printf("%lu ns", duration);
160 }
136 return; 161 return;
137} 162}
138 163
@@ -525,6 +550,7 @@ static struct option info_opts[] = {
525 { .name = "latency", .has_arg = no_argument, .flag = NULL, .val = 'y'}, 550 { .name = "latency", .has_arg = no_argument, .flag = NULL, .val = 'y'},
526 { .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'}, 551 { .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'},
527 { .name = "human", .has_arg = no_argument, .flag = NULL, .val = 'm'}, 552 { .name = "human", .has_arg = no_argument, .flag = NULL, .val = 'm'},
553 { .name = "no-rounding", .has_arg = no_argument, .flag = NULL, .val = 'n'},
528 { }, 554 { },
529}; 555};
530 556
@@ -538,7 +564,8 @@ int cmd_freq_info(int argc, char **argv)
538 int output_param = 0; 564 int output_param = 0;
539 565
540 do { 566 do {
541 ret = getopt_long(argc, argv, "oefwldpgrasmyb", info_opts, NULL); 567 ret = getopt_long(argc, argv, "oefwldpgrasmybn", info_opts,
568 NULL);
542 switch (ret) { 569 switch (ret) {
543 case '?': 570 case '?':
544 output_param = '?'; 571 output_param = '?';
@@ -575,6 +602,9 @@ int cmd_freq_info(int argc, char **argv)
575 } 602 }
576 human = 1; 603 human = 1;
577 break; 604 break;
605 case 'n':
606 no_rounding = 1;
607 break;
578 default: 608 default:
579 fprintf(stderr, "invalid or unknown argument\n"); 609 fprintf(stderr, "invalid or unknown argument\n");
580 return EXIT_FAILURE; 610 return EXIT_FAILURE;
diff --git a/tools/power/cpupower/utils/cpuidle-set.c b/tools/power/cpupower/utils/cpuidle-set.c
index c78141c5dfac..d45d8d775c02 100644
--- a/tools/power/cpupower/utils/cpuidle-set.c
+++ b/tools/power/cpupower/utils/cpuidle-set.c
@@ -13,8 +13,14 @@
13#include "helpers/sysfs.h" 13#include "helpers/sysfs.h"
14 14
15static struct option info_opts[] = { 15static struct option info_opts[] = {
16 { .name = "disable", .has_arg = required_argument, .flag = NULL, .val = 'd'}, 16 { .name = "disable",
17 { .name = "enable", .has_arg = required_argument, .flag = NULL, .val = 'e'}, 17 .has_arg = required_argument, .flag = NULL, .val = 'd'},
18 { .name = "enable",
19 .has_arg = required_argument, .flag = NULL, .val = 'e'},
20 { .name = "disable-by-latency",
21 .has_arg = required_argument, .flag = NULL, .val = 'D'},
22 { .name = "enable-all",
23 .has_arg = no_argument, .flag = NULL, .val = 'E'},
18 { }, 24 { },
19}; 25};
20 26
@@ -23,11 +29,13 @@ int cmd_idle_set(int argc, char **argv)
23{ 29{
24 extern char *optarg; 30 extern char *optarg;
25 extern int optind, opterr, optopt; 31 extern int optind, opterr, optopt;
26 int ret = 0, cont = 1, param = 0, idlestate = 0; 32 int ret = 0, cont = 1, param = 0, disabled;
27 unsigned int cpu = 0; 33 unsigned long long latency = 0, state_latency;
34 unsigned int cpu = 0, idlestate = 0, idlestates = 0;
35 char *endptr;
28 36
29 do { 37 do {
30 ret = getopt_long(argc, argv, "d:e:", info_opts, NULL); 38 ret = getopt_long(argc, argv, "d:e:ED:", info_opts, NULL);
31 if (ret == -1) 39 if (ret == -1)
32 break; 40 break;
33 switch (ret) { 41 switch (ret) {
@@ -53,6 +61,27 @@ int cmd_idle_set(int argc, char **argv)
53 param = ret; 61 param = ret;
54 idlestate = atoi(optarg); 62 idlestate = atoi(optarg);
55 break; 63 break;
64 case 'D':
65 if (param) {
66 param = -1;
67 cont = 0;
68 break;
69 }
70 param = ret;
71 latency = strtoull(optarg, &endptr, 10);
72 if (*endptr != '\0') {
73 printf(_("Bad latency value: %s\n"), optarg);
74 exit(EXIT_FAILURE);
75 }
76 break;
77 case 'E':
78 if (param) {
79 param = -1;
80 cont = 0;
81 break;
82 }
83 param = ret;
84 break;
56 case -1: 85 case -1:
57 cont = 0; 86 cont = 0;
58 break; 87 break;
@@ -79,8 +108,14 @@ int cmd_idle_set(int argc, char **argv)
79 if (!bitmask_isbitset(cpus_chosen, cpu)) 108 if (!bitmask_isbitset(cpus_chosen, cpu))
80 continue; 109 continue;
81 110
82 switch (param) { 111 if (sysfs_is_cpu_online(cpu) != 1)
112 continue;
113
114 idlestates = sysfs_get_idlestate_count(cpu);
115 if (idlestates <= 0)
116 continue;
83 117
118 switch (param) {
84 case 'd': 119 case 'd':
85 ret = sysfs_idlestate_disable(cpu, idlestate, 1); 120 ret = sysfs_idlestate_disable(cpu, idlestate, 1);
86 if (ret == 0) 121 if (ret == 0)
@@ -107,6 +142,34 @@ int cmd_idle_set(int argc, char **argv)
107 printf(_("Idlestate %u not enabled on CPU %u\n"), 142 printf(_("Idlestate %u not enabled on CPU %u\n"),
108 idlestate, cpu); 143 idlestate, cpu);
109 break; 144 break;
145 case 'D':
146 for (idlestate = 0; idlestate < idlestates; idlestate++) {
147 disabled = sysfs_is_idlestate_disabled
148 (cpu, idlestate);
149 state_latency = sysfs_get_idlestate_latency
150 (cpu, idlestate);
151 printf("CPU: %u - idlestate %u - state_latency: %llu - latency: %llu\n",
152 cpu, idlestate, state_latency, latency);
153 if (disabled == 1 || latency > state_latency)
154 continue;
155 ret = sysfs_idlestate_disable
156 (cpu, idlestate, 1);
157 if (ret == 0)
158 printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu);
159 }
160 break;
161 case 'E':
162 for (idlestate = 0; idlestate < idlestates; idlestate++) {
163 disabled = sysfs_is_idlestate_disabled
164 (cpu, idlestate);
165 if (disabled == 1) {
166 ret = sysfs_idlestate_disable
167 (cpu, idlestate, 0);
168 if (ret == 0)
169 printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu);
170 }
171 }
172 break;
110 default: 173 default:
111 /* Not reachable with proper args checking */ 174 /* Not reachable with proper args checking */
112 printf(_("Invalid or unknown argument\n")); 175 printf(_("Invalid or unknown argument\n"));
diff --git a/tools/power/cpupower/utils/cpupower-info.c b/tools/power/cpupower/utils/cpupower-info.c
index 3f68632c28c7..136d979e9586 100644
--- a/tools/power/cpupower/utils/cpupower-info.c
+++ b/tools/power/cpupower/utils/cpupower-info.c
@@ -18,8 +18,6 @@
18 18
19static struct option set_opts[] = { 19static struct option set_opts[] = {
20 { .name = "perf-bias", .has_arg = optional_argument, .flag = NULL, .val = 'b'}, 20 { .name = "perf-bias", .has_arg = optional_argument, .flag = NULL, .val = 'b'},
21 { .name = "sched-mc", .has_arg = optional_argument, .flag = NULL, .val = 'm'},
22 { .name = "sched-smt", .has_arg = optional_argument, .flag = NULL, .val = 's'},
23 { }, 21 { },
24}; 22};
25 23
@@ -37,8 +35,6 @@ int cmd_info(int argc, char **argv)
37 35
38 union { 36 union {
39 struct { 37 struct {
40 int sched_mc:1;
41 int sched_smt:1;
42 int perf_bias:1; 38 int perf_bias:1;
43 }; 39 };
44 int params; 40 int params;
@@ -49,23 +45,13 @@ int cmd_info(int argc, char **argv)
49 textdomain(PACKAGE); 45 textdomain(PACKAGE);
50 46
51 /* parameter parsing */ 47 /* parameter parsing */
52 while ((ret = getopt_long(argc, argv, "msb", set_opts, NULL)) != -1) { 48 while ((ret = getopt_long(argc, argv, "b", set_opts, NULL)) != -1) {
53 switch (ret) { 49 switch (ret) {
54 case 'b': 50 case 'b':
55 if (params.perf_bias) 51 if (params.perf_bias)
56 print_wrong_arg_exit(); 52 print_wrong_arg_exit();
57 params.perf_bias = 1; 53 params.perf_bias = 1;
58 break; 54 break;
59 case 'm':
60 if (params.sched_mc)
61 print_wrong_arg_exit();
62 params.sched_mc = 1;
63 break;
64 case 's':
65 if (params.sched_smt)
66 print_wrong_arg_exit();
67 params.sched_smt = 1;
68 break;
69 default: 55 default:
70 print_wrong_arg_exit(); 56 print_wrong_arg_exit();
71 } 57 }
@@ -78,25 +64,6 @@ int cmd_info(int argc, char **argv)
78 if (bitmask_isallclear(cpus_chosen)) 64 if (bitmask_isallclear(cpus_chosen))
79 bitmask_setbit(cpus_chosen, 0); 65 bitmask_setbit(cpus_chosen, 0);
80 66
81 if (params.sched_mc) {
82 ret = sysfs_get_sched("mc");
83 printf(_("System's multi core scheduler setting: "));
84 if (ret < 0)
85 /* if sysfs file is missing it's: errno == ENOENT */
86 printf(_("not supported\n"));
87 else
88 printf("%d\n", ret);
89 }
90 if (params.sched_smt) {
91 ret = sysfs_get_sched("smt");
92 printf(_("System's thread sibling scheduler setting: "));
93 if (ret < 0)
94 /* if sysfs file is missing it's: errno == ENOENT */
95 printf(_("not supported\n"));
96 else
97 printf("%d\n", ret);
98 }
99
100 /* Add more per cpu options here */ 67 /* Add more per cpu options here */
101 if (!params.perf_bias) 68 if (!params.perf_bias)
102 return ret; 69 return ret;
@@ -125,11 +92,12 @@ int cmd_info(int argc, char **argv)
125 if (params.perf_bias) { 92 if (params.perf_bias) {
126 ret = msr_intel_get_perf_bias(cpu); 93 ret = msr_intel_get_perf_bias(cpu);
127 if (ret < 0) { 94 if (ret < 0) {
128 printf(_("Could not read perf-bias value\n")); 95 fprintf(stderr,
129 break; 96 _("Could not read perf-bias value[%d]\n"), ret);
97 exit(EXIT_FAILURE);
130 } else 98 } else
131 printf(_("perf-bias: %d\n"), ret); 99 printf(_("perf-bias: %d\n"), ret);
132 } 100 }
133 } 101 }
134 return ret; 102 return 0;
135} 103}
diff --git a/tools/power/cpupower/utils/cpupower-set.c b/tools/power/cpupower/utils/cpupower-set.c
index bcf1d2f0b791..573c75f8e3f5 100644
--- a/tools/power/cpupower/utils/cpupower-set.c
+++ b/tools/power/cpupower/utils/cpupower-set.c
@@ -19,8 +19,6 @@
19 19
20static struct option set_opts[] = { 20static struct option set_opts[] = {
21 { .name = "perf-bias", .has_arg = required_argument, .flag = NULL, .val = 'b'}, 21 { .name = "perf-bias", .has_arg = required_argument, .flag = NULL, .val = 'b'},
22 { .name = "sched-mc", .has_arg = required_argument, .flag = NULL, .val = 'm'},
23 { .name = "sched-smt", .has_arg = required_argument, .flag = NULL, .val = 's'},
24 { }, 22 { },
25}; 23};
26 24
@@ -38,13 +36,11 @@ int cmd_set(int argc, char **argv)
38 36
39 union { 37 union {
40 struct { 38 struct {
41 int sched_mc:1;
42 int sched_smt:1;
43 int perf_bias:1; 39 int perf_bias:1;
44 }; 40 };
45 int params; 41 int params;
46 } params; 42 } params;
47 int sched_mc = 0, sched_smt = 0, perf_bias = 0; 43 int perf_bias = 0;
48 int ret = 0; 44 int ret = 0;
49 45
50 setlocale(LC_ALL, ""); 46 setlocale(LC_ALL, "");
@@ -52,7 +48,7 @@ int cmd_set(int argc, char **argv)
52 48
53 params.params = 0; 49 params.params = 0;
54 /* parameter parsing */ 50 /* parameter parsing */
55 while ((ret = getopt_long(argc, argv, "m:s:b:", 51 while ((ret = getopt_long(argc, argv, "b:",
56 set_opts, NULL)) != -1) { 52 set_opts, NULL)) != -1) {
57 switch (ret) { 53 switch (ret) {
58 case 'b': 54 case 'b':
@@ -66,28 +62,6 @@ int cmd_set(int argc, char **argv)
66 } 62 }
67 params.perf_bias = 1; 63 params.perf_bias = 1;
68 break; 64 break;
69 case 'm':
70 if (params.sched_mc)
71 print_wrong_arg_exit();
72 sched_mc = atoi(optarg);
73 if (sched_mc < 0 || sched_mc > 2) {
74 printf(_("--sched-mc param out "
75 "of range [0-%d]\n"), 2);
76 print_wrong_arg_exit();
77 }
78 params.sched_mc = 1;
79 break;
80 case 's':
81 if (params.sched_smt)
82 print_wrong_arg_exit();
83 sched_smt = atoi(optarg);
84 if (sched_smt < 0 || sched_smt > 2) {
85 printf(_("--sched-smt param out "
86 "of range [0-%d]\n"), 2);
87 print_wrong_arg_exit();
88 }
89 params.sched_smt = 1;
90 break;
91 default: 65 default:
92 print_wrong_arg_exit(); 66 print_wrong_arg_exit();
93 } 67 }
@@ -96,19 +70,6 @@ int cmd_set(int argc, char **argv)
96 if (!params.params) 70 if (!params.params)
97 print_wrong_arg_exit(); 71 print_wrong_arg_exit();
98 72
99 if (params.sched_mc) {
100 ret = sysfs_set_sched("mc", sched_mc);
101 if (ret)
102 fprintf(stderr, _("Error setting sched-mc %s\n"),
103 (ret == -ENODEV) ? "not supported" : "");
104 }
105 if (params.sched_smt) {
106 ret = sysfs_set_sched("smt", sched_smt);
107 if (ret)
108 fprintf(stderr, _("Error setting sched-smt %s\n"),
109 (ret == -ENODEV) ? "not supported" : "");
110 }
111
112 /* Default is: set all CPUs */ 73 /* Default is: set all CPUs */
113 if (bitmask_isallclear(cpus_chosen)) 74 if (bitmask_isallclear(cpus_chosen))
114 bitmask_setall(cpus_chosen); 75 bitmask_setall(cpus_chosen);
diff --git a/tools/power/cpupower/utils/cpupower.c b/tools/power/cpupower/utils/cpupower.c
index 7efc570ffbaa..7cdcf88659c7 100644
--- a/tools/power/cpupower/utils/cpupower.c
+++ b/tools/power/cpupower/utils/cpupower.c
@@ -12,6 +12,9 @@
12#include <string.h> 12#include <string.h>
13#include <unistd.h> 13#include <unistd.h>
14#include <errno.h> 14#include <errno.h>
15#include <sys/types.h>
16#include <sys/stat.h>
17#include <sys/utsname.h>
15 18
16#include "builtin.h" 19#include "builtin.h"
17#include "helpers/helpers.h" 20#include "helpers/helpers.h"
@@ -169,6 +172,8 @@ int main(int argc, const char *argv[])
169{ 172{
170 const char *cmd; 173 const char *cmd;
171 unsigned int i, ret; 174 unsigned int i, ret;
175 struct stat statbuf;
176 struct utsname uts;
172 177
173 cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF)); 178 cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
174 179
@@ -195,6 +200,15 @@ int main(int argc, const char *argv[])
195 200
196 get_cpu_info(0, &cpupower_cpu_info); 201 get_cpu_info(0, &cpupower_cpu_info);
197 run_as_root = !getuid(); 202 run_as_root = !getuid();
203 if (run_as_root) {
204 ret = uname(&uts);
205 if (!ret && !strcmp(uts.machine, "x86_64") &&
206 stat("/dev/cpu/0/msr", &statbuf) != 0) {
207 if (system("modprobe msr") == -1)
208 fprintf(stderr, _("MSR access not available.\n"));
209 }
210 }
211
198 212
199 for (i = 0; i < ARRAY_SIZE(commands); i++) { 213 for (i = 0; i < ARRAY_SIZE(commands); i++) {
200 struct cmd_struct *p = commands + i; 214 struct cmd_struct *p = commands + i;
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 7c9d8e71eb9e..d0396af99fa0 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -1971,13 +1971,13 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk
1971 if (get_msr(0, MSR_IA32_TEMPERATURE_TARGET, &msr)) 1971 if (get_msr(0, MSR_IA32_TEMPERATURE_TARGET, &msr))
1972 goto guess; 1972 goto guess;
1973 1973
1974 target_c_local = (msr >> 16) & 0x7F; 1974 target_c_local = (msr >> 16) & 0xFF;
1975 1975
1976 if (verbose) 1976 if (verbose)
1977 fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n", 1977 fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
1978 cpu, msr, target_c_local); 1978 cpu, msr, target_c_local);
1979 1979
1980 if (target_c_local < 85 || target_c_local > 127) 1980 if (!target_c_local)
1981 goto guess; 1981 goto guess;
1982 1982
1983 tcc_activation_temp = target_c_local; 1983 tcc_activation_temp = target_c_local;