-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
acpi_validate
201 lines (183 loc) · 6.38 KB
/
acpi_validate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#!/bin/bash
#
# Copyright (c) 2012 SUSE Linux Products GmbH
# Thomas Renninger <[email protected]>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
# version 2, as published by the Free Software Foundation.
#
# This program is distributed in the hope it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
#
OUTPUT_DIR="$PWD"
VERBOSE=0
# Disable remarks and resource checks. The latter often/mostly generates
# false positive warnings. Can be overridden via -c option
COMPILE_OPTIONS="-sa -cr -vr -in"
DISASSEMBLE_OPTIONS="-in"
OUTPUT="/dev/null"
ACPIDUMP=""
MUST_BE_ROOT=1
function usage()
{
echo "acpi_validate [ -o output_dir ] [ -v ] [ -a acpidump ]"
echo " [ -c compile_options ] [ -d disassemble_options ]"
echo
echo "This tool extracts, disassembles and recompiles ACPI BIOS tables."
echo "The disassembled files will be copied into the local or specified"
echo "output directory (-o option)."
echo
echo "The underlying iasl compiler verifies and may complain about"
echo "correctness of some of the BIOS tables."
echo "These can give a pointer to possible malfunction of the system."
echo
echo "If you think you found a bug in the iasl compiler or related tools,"
echo "you can ask here for help: [email protected]"
echo "You may also want to ask there if you are not sure whether it really"
echo "is a BIOS bug."
echo
echo "If you are sure you found a BIOS issue, complain to your hardware vendor."
echo "The iasl compiler typically provides a description of the warning/error in a way,"
echo "so that BIOS authors can easily fix it."
echo
echo "Options"
echo " -o output_dir: Copy tables to this directory instead of local one"
echo " -v: : be more verbose"
echo " -a acpidump : Use this acpidump file"
echo " instead of the tables from the local machine"
echo " -d options : Pass iasl disassemble options"
echo " -c options : Pass iasl compile options"
echo " will override -sa -cr -vr (default options)"
echo " -h : Show help"
exit 1
}
while getopts hva:o:c:d: name ; do
case $name in
o)
OUTPUT_DIR="$OPTARG"
if [ ! -d "$OUTPUT_DIR" ];then
mkdir "$OUTPUT_DIR"
if [[ $? != 0 ]];then
echo "Cannot create directory $OUTPUT_DIR"
exit 1
fi
elif [ ! -w "$OUTPUT_DIR" ];then
echo "Cannot write into directory $OUTPUT_DIR"
exit 1
fi
[[ $VERBOSE == 1 ]] && echo "Installing for architecture: $OUTPUT_DIR"
;;
a)
ACPIDUMP="$OPTARG"
if [ ! -r "$ACPIDUMP" ];then
echo "$ACPIDUMP does not exist"
exit 1
fi
[[ $VERBOSE == 1 ]] && echo "acpidump file: $ACPIDUMP"
MUST_BE_ROOT=0
;;
c)
COMPILE_OPTIONS="$OPTARG"
[[ $VERBOSE == 1 ]] && echo "Compile options: $COMPILE_OPTIONS"
;;
c)
DISASSEMBLE_OPTIONS="$OPTARG"
[[ $VERBOSE == 1 ]] && echo "Disassemble options: $DISASSEMBLE_OPTIONS"
;;
v)
VERBOSE=1
OUTPUT="1"
;;
?)
usage
;;
esac
done
shift $(($OPTIND -1))
if [[ $MUST_BE_ROOT == 1 ]] && [ "$(id -u)" != "0" ]; then
echo "This script must be run as root"
echo "(or use -a acpidump option and pass already dumped acpi tables)"
exit 1
fi
shopt -s nocasematch
TEMP_DIR=$(mktemp -d)
[[ $VERBOSE == 1 ]] && echo "Using temporary directory: $TEMP_DIR"
if [ -r "$ACPIDUMP" ];then
cp "$ACPIDUMP" "$TEMP_DIR"/acpidump
fi
pushd "$TEMP_DIR" >/dev/null
mkdir log
mkdir err
if [ ! -r acpidump ];then
acpidump >acpidump
fi
acpixtract -a acpidump >&$OUTPUT 2>&1
# ACPICA changed from uppercase to lowercase, try to find both:
SDTs=$(ls [SD]DST*.dat 2>/dev/null)
SDTs="${SDTs}$(ls [sd]sdt*.dat 2>/dev/null)"
for file in *.dat;do
table=${file/.dat/}
# Enable case insensitive pattern matching
case $file in
[DS]SDT*.dat | [sd]sdt*.dat)
# Use other [sd]sdt*.dat tables to reference possible
# external symbols. Pass the table itself for disassembling
# comma separted.
# For example you we have:
# dsdt.dat ssdt1 ssdt2.dat
# and the current table to disassemble is ssdt1.dat the
# command has to be:
# iasl -e dsdt.dat,ssdt2.dat -d ssdt1.dat
# Get rid of the table which gets disassembled
# could have leading or trailing whitespace depending whether
# it is at the end or the beginning of the list
REF_TABLE_LIST=${SDTs/[[:space:]]$file/}
REF_TABLE_LIST=${REF_TABLE_LIST/$file[[:space:]]/}
# Convert the whitespace list into a comma separated one:
REF_TABLE_LIST=${REF_TABLE_LIST//[[:space:]]/,}
if [ "$REF_TABLE_LIST" != "" ];then
FINAL_DISASSEMBLE_OPTIONS="-e ${REF_TABLE_LIST} $DISASSEMBLE_OPTIONS"
else
FINAL_DISASSEMBLE_OPTIONS="$DISASSEMBLE_OPTIONS"
fi
echo "stdout and stderr of $file disassembling:" >log/${table}.log
[[ $VERBOSE == 1 ]] && echo "iasl $FINAL_DISASSEMBLE_OPTIONS -d $file 1>>log/${table}.log 2>&1"
iasl $FINAL_DISASSEMBLE_OPTIONS -d $file 1>>log/${table}.log 2>&1
[[ $VERBOSE == 1 ]] && echo "iasl $COMPILE_OPTIONS ${table}.dsl 1>>log/${table}.log 2>>err/${table}.err"
iasl $COMPILE_OPTIONS ${table}.dsl 1>>log/${table}.log 2>>err/${table}.err
;;
*.dat)
iasl -d $file 1>log/${table}.log 2>&1
iasl -sa ${table}.dsl 1>log/${table}.log 2>err/${table}.err
;;
esac
done
# remove empty error files
rm $(find err -size 0)
ERR_TABLES=$(ls err)
ERR_TABLES=${ERR_TABLES//.err/}
popd >/dev/null
cp -r "$TEMP_DIR"/* "$OUTPUT_DIR"
if [[ $VERBOSE == 1 ]];then
echo "Temporary directory (undeleted): $TEMP_DIR"
else
rm -rf "$TEMP_DIR"
fi
if [ "$ERR_TABLES" = "" ];then
echo "No errors or warnings detected"
exit 0
else
echo "These tables have warnings or errors (details in "$OUTPUT_DIR"/err directory):"
for err in $ERR_TABLES;do
echo -n $err $'\t'
sed -n -e 's/Compilation complete. \(.* Errors, .* Warnings\).*/\1/p' "$OUTPUT_DIR"/log/$err.log
done
exit 1
fi