dmtables.c revision 1.1.1.3 1 /******************************************************************************
2 *
3 * Module Name: dmtables - disassembler ACPI table support
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2016, 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 "aslcompiler.h"
45 #include "acdispat.h"
46 #include "acnamesp.h"
47 #include "actables.h"
48 #include "acparser.h"
49 #include "acapps.h"
50
51
52 #define _COMPONENT ACPI_TOOLS
53 ACPI_MODULE_NAME ("dmtables")
54
55
56 /* Local prototypes */
57
58 static void
59 AdCreateTableHeader (
60 char *Filename,
61 ACPI_TABLE_HEADER *Table);
62
63 static ACPI_STATUS
64 AdStoreTable (
65 ACPI_TABLE_HEADER *Table,
66 UINT32 *TableIndex);
67
68
69 extern ACPI_TABLE_DESC LocalTables[1];
70 extern ACPI_PARSE_OBJECT *AcpiGbl_ParseOpRoot;
71
72
73 /******************************************************************************
74 *
75 * FUNCTION: AdDisassemblerHeader
76 *
77 * PARAMETERS: Filename - Input file for the table
78 * TableType - Either AML or DataTable
79 *
80 * RETURN: None
81 *
82 * DESCRIPTION: Create the disassembler header, including ACPICA signon with
83 * current time and date.
84 *
85 *****************************************************************************/
86
87 void
88 AdDisassemblerHeader (
89 char *Filename,
90 UINT8 TableType)
91 {
92 time_t Timer;
93
94
95 time (&Timer);
96
97 /* Header and input table info */
98
99 AcpiOsPrintf ("/*\n");
100 AcpiOsPrintf (ACPI_COMMON_HEADER (AML_DISASSEMBLER_NAME, " * "));
101
102 if (TableType == ACPI_IS_AML_TABLE)
103 {
104 if (AcpiGbl_CstyleDisassembly)
105 {
106 AcpiOsPrintf (
107 " * Disassembling to symbolic ASL+ operators\n"
108 " *\n");
109 }
110 else
111 {
112 AcpiOsPrintf (
113 " * Disassembling to non-symbolic legacy ASL operators\n"
114 " *\n");
115 }
116 }
117
118 AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer));
119 AcpiOsPrintf (" *\n");
120 }
121
122
123 /******************************************************************************
124 *
125 * FUNCTION: AdCreateTableHeader
126 *
127 * PARAMETERS: Filename - Input file for the table
128 * Table - Pointer to the raw table
129 *
130 * RETURN: None
131 *
132 * DESCRIPTION: Create the ASL table header, including ACPICA signon with
133 * current time and date.
134 *
135 *****************************************************************************/
136
137 static void
138 AdCreateTableHeader (
139 char *Filename,
140 ACPI_TABLE_HEADER *Table)
141 {
142 UINT8 Checksum;
143
144
145 /* Reset globals for External statements */
146
147 AcpiGbl_NumExternalMethods = 0;
148 AcpiGbl_ResolvedExternalMethods = 0;
149
150 /*
151 * Print file header and dump original table header
152 */
153 AdDisassemblerHeader (Filename, ACPI_IS_AML_TABLE);
154
155 AcpiOsPrintf (" * Original Table Header:\n");
156 AcpiOsPrintf (" * Signature \"%4.4s\"\n", Table->Signature);
157 AcpiOsPrintf (" * Length 0x%8.8X (%u)\n", Table->Length, Table->Length);
158
159 /* Print and validate the revision */
160
161 AcpiOsPrintf (" * Revision 0x%2.2X", Table->Revision);
162
163 switch (Table->Revision)
164 {
165 case 0:
166
167 AcpiOsPrintf (" **** Invalid Revision");
168 break;
169
170 case 1:
171
172 /* Revision of DSDT controls the ACPI integer width */
173
174 if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT))
175 {
176 AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support");
177 }
178 break;
179
180 default:
181
182 break;
183 }
184
185 /* Print and validate the table checksum */
186
187 AcpiOsPrintf ("\n * Checksum 0x%2.2X", Table->Checksum);
188
189 Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length);
190 if (Checksum)
191 {
192 AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X",
193 (UINT8) (Table->Checksum - Checksum));
194 }
195
196 AcpiOsPrintf ("\n");
197 AcpiOsPrintf (" * OEM ID \"%.6s\"\n", Table->OemId);
198 AcpiOsPrintf (" * OEM Table ID \"%.8s\"\n", Table->OemTableId);
199 AcpiOsPrintf (" * OEM Revision 0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision);
200 AcpiOsPrintf (" * Compiler ID \"%.4s\"\n", Table->AslCompilerId);
201 AcpiOsPrintf (" * Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision);
202 AcpiOsPrintf (" */\n");
203
204 /*
205 * Open the ASL definition block.
206 *
207 * Note: the AMLFilename string is left zero-length in order to just let
208 * the compiler create it when the disassembled file is compiled. This
209 * makes it easier to rename the disassembled ASL file if needed.
210 */
211 AcpiOsPrintf (
212 "DefinitionBlock (\"\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n",
213 Table->Signature, Table->Revision,
214 Table->OemId, Table->OemTableId, Table->OemRevision);
215 }
216
217
218 /******************************************************************************
219 *
220 * FUNCTION: AdDisplayTables
221 *
222 * PARAMETERS: Filename - Input file for the table
223 * Table - Pointer to the raw table
224 *
225 * RETURN: Status
226 *
227 * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables
228 *
229 *****************************************************************************/
230
231 ACPI_STATUS
232 AdDisplayTables (
233 char *Filename,
234 ACPI_TABLE_HEADER *Table)
235 {
236
237
238 if (!AcpiGbl_ParseOpRoot)
239 {
240 return (AE_NOT_EXIST);
241 }
242
243 if (!AcpiGbl_DmOpt_Listing)
244 {
245 AdCreateTableHeader (Filename, Table);
246 }
247
248 AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX);
249 MpEmitMappingInfo ();
250
251 if (AcpiGbl_DmOpt_Listing)
252 {
253 AcpiOsPrintf ("\n\nTable Header:\n");
254 AcpiUtDebugDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER),
255 DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
256
257 AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length);
258 AcpiUtDebugDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)),
259 Table->Length, DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
260 }
261
262 return (AE_OK);
263 }
264
265
266 /*******************************************************************************
267 *
268 * FUNCTION: AdStoreTable
269 *
270 * PARAMETERS: Table - Table header
271 * TableIndex - Where the table index is returned
272 *
273 * RETURN: Status and table index.
274 *
275 * DESCRIPTION: Add an ACPI table to the global table list
276 *
277 ******************************************************************************/
278
279 static ACPI_STATUS
280 AdStoreTable (
281 ACPI_TABLE_HEADER *Table,
282 UINT32 *TableIndex)
283 {
284 ACPI_STATUS Status;
285 ACPI_TABLE_DESC *TableDesc;
286
287
288 Status = AcpiTbGetNextTableDescriptor (TableIndex, &TableDesc);
289 if (ACPI_FAILURE (Status))
290 {
291 return (Status);
292 }
293
294 /* Initialize added table */
295
296 AcpiTbInitTableDescriptor (TableDesc, ACPI_PTR_TO_PHYSADDR (Table),
297 ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, Table);
298 Status = AcpiTbValidateTable (TableDesc);
299 return (Status);
300 }
301
302
303 /******************************************************************************
304 *
305 * FUNCTION: AdGetLocalTables
306 *
307 * PARAMETERS: None
308 *
309 * RETURN: Status
310 *
311 * DESCRIPTION: Get the ACPI tables from either memory or a file
312 *
313 *****************************************************************************/
314
315 ACPI_STATUS
316 AdGetLocalTables (
317 void)
318 {
319 ACPI_STATUS Status;
320 ACPI_TABLE_HEADER TableHeader;
321 ACPI_TABLE_HEADER *NewTable;
322 UINT32 TableIndex;
323
324
325 /* Get the DSDT via table override */
326
327 ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT);
328 AcpiOsTableOverride (&TableHeader, &NewTable);
329 if (!NewTable)
330 {
331 fprintf (stderr, "Could not obtain DSDT\n");
332 return (AE_NO_ACPI_TABLES);
333 }
334
335 AdWriteTable (NewTable, NewTable->Length,
336 ACPI_SIG_DSDT, NewTable->OemTableId);
337
338 /* Store DSDT in the Table Manager */
339
340 Status = AdStoreTable (NewTable, &TableIndex);
341 if (ACPI_FAILURE (Status))
342 {
343 fprintf (stderr, "Could not store DSDT\n");
344 return (AE_NO_ACPI_TABLES);
345 }
346
347 return (AE_OK);
348 }
349
350
351 /******************************************************************************
352 *
353 * FUNCTION: AdParseTable
354 *
355 * PARAMETERS: Table - Pointer to the raw table
356 * OwnerId - Returned OwnerId of the table
357 * LoadTable - If add table to the global table list
358 * External - If this is an external table
359 *
360 * RETURN: Status
361 *
362 * DESCRIPTION: Parse an ACPI AML table
363 *
364 *****************************************************************************/
365
366 ACPI_STATUS
367 AdParseTable (
368 ACPI_TABLE_HEADER *Table,
369 ACPI_OWNER_ID *OwnerId,
370 BOOLEAN LoadTable,
371 BOOLEAN External)
372 {
373 ACPI_STATUS Status = AE_OK;
374 ACPI_WALK_STATE *WalkState;
375 UINT8 *AmlStart;
376 UINT32 AmlLength;
377 UINT32 TableIndex;
378
379
380 if (!Table)
381 {
382 return (AE_NOT_EXIST);
383 }
384
385 /* Pass 1: Parse everything except control method bodies */
386
387 fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature);
388
389 AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
390 AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER));
391
392 /* Create the root object */
393
394 AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp (AmlStart);
395 if (!AcpiGbl_ParseOpRoot)
396 {
397 return (AE_NO_MEMORY);
398 }
399
400 /* Create and initialize a new walk state */
401
402 WalkState = AcpiDsCreateWalkState (0, AcpiGbl_ParseOpRoot, NULL, NULL);
403 if (!WalkState)
404 {
405 return (AE_NO_MEMORY);
406 }
407
408 Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot,
409 NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
410 if (ACPI_FAILURE (Status))
411 {
412 return (Status);
413 }
414
415 WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
416 WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
417
418 Status = AcpiPsParseAml (WalkState);
419 if (ACPI_FAILURE (Status))
420 {
421 return (Status);
422 }
423
424 /* If LoadTable is FALSE, we are parsing the last loaded table */
425
426 TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1;
427
428 /* Pass 2 */
429
430 if (LoadTable)
431 {
432 Status = AdStoreTable (Table, &TableIndex);
433 if (ACPI_FAILURE (Status))
434 {
435 return (Status);
436 }
437 Status = AcpiTbAllocateOwnerId (TableIndex);
438 if (ACPI_FAILURE (Status))
439 {
440 return (Status);
441 }
442 if (OwnerId)
443 {
444 Status = AcpiTbGetOwnerId (TableIndex, OwnerId);
445 if (ACPI_FAILURE (Status))
446 {
447 return (Status);
448 }
449 }
450 }
451
452 fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature);
453
454 Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL);
455 if (ACPI_FAILURE (Status))
456 {
457 return (Status);
458 }
459
460 /* No need to parse control methods of external table */
461
462 if (External)
463 {
464 return (AE_OK);
465 }
466
467 /*
468 * Pass 3: Parse control methods and link their parse trees
469 * into the main parse tree
470 */
471 fprintf (stderr,
472 "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n");
473
474 Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot);
475 fprintf (stderr, "\n");
476
477 /* Process Resource Templates */
478
479 AcpiDmFindResources (AcpiGbl_ParseOpRoot);
480
481 fprintf (stderr, "Parsing completed\n");
482 return (AE_OK);
483 }
484