1
2
3
4
5
6
7
8
9
10#include "acpidump.h"
11
12
13
14static int
15ap_dump_table_buffer(struct acpi_table_header *table,
16 u32 instance, acpi_physical_address address);
17
18
19
20
21
22
23
24
25
26
27
28
29
30u8 ap_is_valid_header(struct acpi_table_header *table)
31{
32
33 if (!ACPI_VALIDATE_RSDP_SIG(table->signature)) {
34
35
36
37 if (!acpi_ut_valid_nameseg(table->signature)) {
38 fprintf(stderr,
39 "Table signature (0x%8.8X) is invalid\n",
40 *(u32 *)table->signature);
41 return (FALSE);
42 }
43
44
45
46 if (table->length < sizeof(struct acpi_table_header)) {
47 fprintf(stderr, "Table length (0x%8.8X) is invalid\n",
48 table->length);
49 return (FALSE);
50 }
51 }
52
53 return (TRUE);
54}
55
56
57
58
59
60
61
62
63
64
65
66
67
68u8 ap_is_valid_checksum(struct acpi_table_header *table)
69{
70 acpi_status status;
71 struct acpi_table_rsdp *rsdp;
72
73 if (ACPI_VALIDATE_RSDP_SIG(table->signature)) {
74
75
76
77
78 rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table);
79 status = acpi_tb_validate_rsdp(rsdp);
80 } else {
81 status = acpi_tb_verify_checksum(table, table->length);
82 }
83
84 if (ACPI_FAILURE(status)) {
85 fprintf(stderr, "%4.4s: Warning: wrong checksum in table\n",
86 table->signature);
87 }
88
89 return (AE_OK);
90}
91
92
93
94
95
96
97
98
99
100
101
102
103
104u32 ap_get_table_length(struct acpi_table_header *table)
105{
106 struct acpi_table_rsdp *rsdp;
107
108
109
110 if (!ap_is_valid_header(table)) {
111 return (0);
112 }
113
114 if (ACPI_VALIDATE_RSDP_SIG(table->signature)) {
115 rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table);
116 return (acpi_tb_get_rsdp_length(rsdp));
117 }
118
119
120
121 return (table->length);
122}
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139static int
140ap_dump_table_buffer(struct acpi_table_header *table,
141 u32 instance, acpi_physical_address address)
142{
143 u32 table_length;
144
145 table_length = ap_get_table_length(table);
146
147
148
149 if (gbl_summary_mode) {
150 acpi_tb_print_table_header(address, table);
151 return (0);
152 }
153
154
155
156 if (gbl_binary_mode) {
157 return (ap_write_to_binary_file(table, instance));
158 }
159
160
161
162
163
164
165 fprintf(gbl_output_file, "%4.4s @ 0x%8.8X%8.8X\n",
166 table->signature, ACPI_FORMAT_UINT64(address));
167
168 acpi_ut_dump_buffer_to_file(gbl_output_file,
169 ACPI_CAST_PTR(u8, table), table_length,
170 DB_BYTE_DISPLAY, 0);
171 fprintf(gbl_output_file, "\n");
172 return (0);
173}
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188int ap_dump_all_tables(void)
189{
190 struct acpi_table_header *table;
191 u32 instance = 0;
192 acpi_physical_address address;
193 acpi_status status;
194 int table_status;
195 u32 i;
196
197
198
199 for (i = 0; i < AP_MAX_ACPI_FILES; i++) {
200 status =
201 acpi_os_get_table_by_index(i, &table, &instance, &address);
202 if (ACPI_FAILURE(status)) {
203
204
205
206 if (status == AE_LIMIT) {
207 return (0);
208 } else if (i == 0) {
209 fprintf(stderr,
210 "Could not get ACPI tables, %s\n",
211 acpi_format_exception(status));
212 return (-1);
213 } else {
214 fprintf(stderr,
215 "Could not get ACPI table at index %u, %s\n",
216 i, acpi_format_exception(status));
217 continue;
218 }
219 }
220
221 table_status = ap_dump_table_buffer(table, instance, address);
222 ACPI_FREE(table);
223
224 if (table_status) {
225 break;
226 }
227 }
228
229
230
231 return (-1);
232}
233
234
235
236
237
238
239
240
241
242
243
244
245
246int ap_dump_table_by_address(char *ascii_address)
247{
248 acpi_physical_address address;
249 struct acpi_table_header *table;
250 acpi_status status;
251 int table_status;
252 u64 long_address;
253
254
255
256 status = acpi_ut_strtoul64(ascii_address, &long_address);
257 if (ACPI_FAILURE(status)) {
258 fprintf(stderr, "%s: Could not convert to a physical address\n",
259 ascii_address);
260 return (-1);
261 }
262
263 address = (acpi_physical_address)long_address;
264 status = acpi_os_get_table_by_address(address, &table);
265 if (ACPI_FAILURE(status)) {
266 fprintf(stderr, "Could not get table at 0x%8.8X%8.8X, %s\n",
267 ACPI_FORMAT_UINT64(address),
268 acpi_format_exception(status));
269 return (-1);
270 }
271
272 table_status = ap_dump_table_buffer(table, 0, address);
273 ACPI_FREE(table);
274 return (table_status);
275}
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290int ap_dump_table_by_name(char *signature)
291{
292 char local_signature[ACPI_NAMESEG_SIZE + 1];
293 u32 instance;
294 struct acpi_table_header *table;
295 acpi_physical_address address;
296 acpi_status status;
297 int table_status;
298
299 if (strlen(signature) != ACPI_NAMESEG_SIZE) {
300 fprintf(stderr,
301 "Invalid table signature [%s]: must be exactly 4 characters\n",
302 signature);
303 return (-1);
304 }
305
306
307
308 strcpy(local_signature, signature);
309 acpi_ut_strupr(local_signature);
310
311
312
313 if (ACPI_COMPARE_NAMESEG(local_signature, "FADT")) {
314 strcpy(local_signature, ACPI_SIG_FADT);
315 } else if (ACPI_COMPARE_NAMESEG(local_signature, "MADT")) {
316 strcpy(local_signature, ACPI_SIG_MADT);
317 }
318
319
320
321 for (instance = 0; instance < AP_MAX_ACPI_FILES; instance++) {
322 status = acpi_os_get_table_by_name(local_signature, instance,
323 &table, &address);
324 if (ACPI_FAILURE(status)) {
325
326
327
328 if (status == AE_LIMIT) {
329 return (0);
330 }
331
332 fprintf(stderr,
333 "Could not get ACPI table with signature [%s], %s\n",
334 local_signature, acpi_format_exception(status));
335 return (-1);
336 }
337
338 table_status = ap_dump_table_buffer(table, instance, address);
339 ACPI_FREE(table);
340
341 if (table_status) {
342 break;
343 }
344 }
345
346
347
348 return (-1);
349}
350
351
352
353
354
355
356
357
358
359
360
361
362
363int ap_dump_table_from_file(char *pathname)
364{
365 struct acpi_table_header *table;
366 u32 file_size = 0;
367 int table_status = -1;
368
369
370
371 table = ap_get_table_from_file(pathname, &file_size);
372 if (!table) {
373 return (-1);
374 }
375
376 if (!acpi_ut_valid_nameseg(table->signature)) {
377 fprintf(stderr,
378 "No valid ACPI signature was found in input file %s\n",
379 pathname);
380 }
381
382
383
384 if (table->length > file_size) {
385 fprintf(stderr,
386 "Table length (0x%X) is too large for input file (0x%X) %s\n",
387 table->length, file_size, pathname);
388 goto exit;
389 }
390
391 if (gbl_verbose_mode) {
392 fprintf(stderr,
393 "Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n",
394 pathname, table->signature, file_size, file_size);
395 }
396
397 table_status = ap_dump_table_buffer(table, 0, 0);
398
399exit:
400 ACPI_FREE(table);
401 return (table_status);
402}
403