dttemplate.c revision 1.1.1.9 1 /******************************************************************************
2 *
3 * Module Name: dttemplate - ACPI table template generation
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2017, 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 "acapps.h"
46 #include "dttemplate.h" /* Contains the hex ACPI table templates */
47
48 #define _COMPONENT DT_COMPILER
49 ACPI_MODULE_NAME ("dttemplate")
50
51
52 /* Local prototypes */
53
54 static BOOLEAN
55 AcpiUtIsSpecialTable (
56 char *Signature);
57
58 static ACPI_STATUS
59 DtCreateOneTemplateFile (
60 char *Signature,
61 UINT32 TableCount);
62
63 static ACPI_STATUS
64 DtCreateOneTemplate (
65 char *Signature,
66 UINT32 TableCount,
67 const ACPI_DMTABLE_DATA *TableData);
68
69 static ACPI_STATUS
70 DtCreateAllTemplates (
71 void);
72
73 static int
74 DtEmitDefinitionBlock (
75 FILE *File,
76 char *Filename,
77 char *Signature,
78 UINT32 Instance);
79
80
81 /*******************************************************************************
82 *
83 * FUNCTION: AcpiUtIsSpecialTable
84 *
85 * PARAMETERS: Signature - ACPI table signature
86 *
87 * RETURN: TRUE if signature is a special ACPI table
88 *
89 * DESCRIPTION: Check for valid ACPI tables that are not in the main ACPI
90 * table data structure (AcpiDmTableData).
91 *
92 ******************************************************************************/
93
94 static BOOLEAN
95 AcpiUtIsSpecialTable (
96 char *Signature)
97 {
98
99 if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT) ||
100 ACPI_COMPARE_NAME (Signature, ACPI_SIG_OSDT) ||
101 ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT) ||
102 ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS) ||
103 ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME))
104 {
105 return (TRUE);
106 }
107
108 return (FALSE);
109 }
110
111
112 /*******************************************************************************
113 *
114 * FUNCTION: DtCreateTemplates
115 *
116 * PARAMETERS: argv - Standard command line arguments
117 *
118 * RETURN: Status
119 *
120 * DESCRIPTION: Create one or more template files.
121 *
122 ******************************************************************************/
123
124 ACPI_STATUS
125 DtCreateTemplates (
126 char **argv)
127 {
128 char *Signature;
129 char *End;
130 unsigned long TableCount;
131 ACPI_STATUS Status = AE_OK;
132
133
134 AslInitializeGlobals ();
135
136 Status = AdInitialize ();
137 if (ACPI_FAILURE (Status))
138 {
139 return (Status);
140 }
141
142 /*
143 * Special cases for DSDT, ALL, and '*'
144 */
145
146 /* Default (no signature option) is DSDT */
147
148 if (AcpiGbl_Optind < 3)
149 {
150 Status = DtCreateOneTemplateFile (ACPI_SIG_DSDT, 0);
151 goto Exit;
152 }
153
154 AcpiGbl_Optind--;
155 Signature = argv[AcpiGbl_Optind];
156 AcpiUtStrupr (Signature);
157
158 /*
159 * Multiple SSDT support (-T <ssdt count>)
160 */
161 TableCount = strtoul (Signature, &End, 0);
162 if (Signature != End)
163 {
164 /* The count is used for table ID and method name - max is 254(+1) */
165
166 if (TableCount > 254)
167 {
168 fprintf (stderr, "%u SSDTs requested, maximum is 254\n",
169 (unsigned int) TableCount);
170
171 Status = AE_LIMIT;
172 goto Exit;
173 }
174
175 Status = DtCreateOneTemplateFile (ACPI_SIG_DSDT, TableCount);
176 goto Exit;
177 }
178
179 if (!strcmp (Signature, "ALL"))
180 {
181 /* Create all available/known templates */
182
183 Status = DtCreateAllTemplates ();
184 goto Exit;
185 }
186
187 /*
188 * Normal case: Create template for each signature
189 */
190 while (argv[AcpiGbl_Optind])
191 {
192 Signature = argv[AcpiGbl_Optind];
193 AcpiUtStrupr (Signature);
194
195 Status = DtCreateOneTemplateFile (Signature, 0);
196 if (ACPI_FAILURE (Status))
197 {
198 goto Exit;
199 }
200
201 AcpiGbl_Optind++;
202 }
203
204
205 Exit:
206 /* Shutdown ACPICA subsystem */
207
208 (void) AcpiTerminate ();
209 UtDeleteLocalCaches ();
210 return (Status);
211 }
212
213
214 /*******************************************************************************
215 *
216 * FUNCTION: DtCreateOneTemplateFile
217 *
218 * PARAMETERS: Signature - ACPI table signature
219 *
220 * RETURN: Status
221 *
222 * DESCRIPTION: Create one template file of the requested signature.
223 *
224 ******************************************************************************/
225
226 static ACPI_STATUS
227 DtCreateOneTemplateFile (
228 char *Signature,
229 UINT32 TableCount)
230 {
231 const ACPI_DMTABLE_DATA *TableData;
232 ACPI_STATUS Status;
233
234
235 /*
236 * Validate signature and get the template data:
237 * 1) Signature must be 4 characters
238 * 2) Signature must be a recognized ACPI table
239 * 3) There must be a template associated with the signature
240 */
241 if (strlen (Signature) != ACPI_NAME_SIZE)
242 {
243 fprintf (stderr,
244 "%s: Invalid ACPI table signature "
245 "(length must be 4 characters)\n", Signature);
246 return (AE_ERROR);
247 }
248
249 /*
250 * Some slack for the two strange tables whose name is different than
251 * their signatures: MADT->APIC and FADT->FACP.
252 */
253 if (!strcmp (Signature, "MADT"))
254 {
255 Signature = "APIC";
256 }
257 else if (!strcmp (Signature, "FADT"))
258 {
259 Signature = "FACP";
260 }
261
262 /* TableData will point to the template */
263
264 TableData = AcpiDmGetTableData (Signature);
265 if (TableData)
266 {
267 if (!TableData->Template)
268 {
269 fprintf (stderr, "%4.4s: No template available\n", Signature);
270 return (AE_ERROR);
271 }
272 }
273 else if (!AcpiUtIsSpecialTable (Signature))
274 {
275 fprintf (stderr,
276 "%4.4s: Unrecognized ACPI table signature\n", Signature);
277 return (AE_ERROR);
278 }
279
280 Status = DtCreateOneTemplate (Signature, TableCount, TableData);
281 return (Status);
282 }
283
284
285 /*******************************************************************************
286 *
287 * FUNCTION: DtCreateAllTemplates
288 *
289 * PARAMETERS: None
290 *
291 * RETURN: Status
292 *
293 * DESCRIPTION: Create all currently defined template files
294 *
295 ******************************************************************************/
296
297 static ACPI_STATUS
298 DtCreateAllTemplates (
299 void)
300 {
301 const ACPI_DMTABLE_DATA *TableData;
302 ACPI_STATUS Status;
303
304
305 fprintf (stderr, "Creating all supported Template files\n");
306
307 /* Walk entire ACPI table data structure */
308
309 for (TableData = AcpiDmTableData; TableData->Signature; TableData++)
310 {
311 /* If table has a template, create the template file */
312
313 if (TableData->Template)
314 {
315 Status = DtCreateOneTemplate (TableData->Signature,
316 0, TableData);
317 if (ACPI_FAILURE (Status))
318 {
319 return (Status);
320 }
321 }
322 }
323
324 /*
325 * Create the special ACPI tables:
326 * 1) DSDT/SSDT are AML tables, not data tables
327 * 2) FACS and RSDP have non-standard headers
328 */
329 Status = DtCreateOneTemplate (ACPI_SIG_DSDT, 0, NULL);
330 if (ACPI_FAILURE (Status))
331 {
332 return (Status);
333 }
334
335 Status = DtCreateOneTemplate (ACPI_SIG_SSDT, 0, NULL);
336 if (ACPI_FAILURE (Status))
337 {
338 return (Status);
339 }
340
341 Status = DtCreateOneTemplate (ACPI_SIG_OSDT, 0, NULL);
342 if (ACPI_FAILURE (Status))
343 {
344 return (Status);
345 }
346
347 Status = DtCreateOneTemplate (ACPI_SIG_FACS, 0, NULL);
348 if (ACPI_FAILURE (Status))
349 {
350 return (Status);
351 }
352
353 Status = DtCreateOneTemplate (ACPI_RSDP_NAME, 0, NULL);
354 if (ACPI_FAILURE (Status))
355 {
356 return (Status);
357 }
358
359 return (AE_OK);
360 }
361
362
363 /*******************************************************************************
364 *
365 * FUNCTION: DtCreateOneTemplate
366 *
367 * PARAMETERS: Signature - ACPI signature, NULL terminated.
368 * TableCount - Used for SSDTs in same file as DSDT
369 * TableData - Entry in ACPI table data structure.
370 * NULL if a special ACPI table.
371 *
372 * RETURN: Status
373 *
374 * DESCRIPTION: Create one template source file for the requested ACPI table.
375 *
376 ******************************************************************************/
377
378 static ACPI_STATUS
379 DtCreateOneTemplate (
380 char *Signature,
381 UINT32 TableCount,
382 const ACPI_DMTABLE_DATA *TableData)
383 {
384 char *DisasmFilename;
385 FILE *File;
386 ACPI_STATUS Status = AE_OK;
387 int Actual;
388 UINT32 i;
389
390
391 /* New file will have a .asl suffix */
392
393 DisasmFilename = FlGenerateFilename (
394 Signature, FILE_SUFFIX_ASL_CODE);
395 if (!DisasmFilename)
396 {
397 fprintf (stderr, "Could not generate output filename\n");
398 return (AE_ERROR);
399 }
400
401 AcpiUtStrlwr (DisasmFilename);
402 if (!UtQueryForOverwrite (DisasmFilename))
403 {
404 return (AE_ERROR);
405 }
406
407 File = fopen (DisasmFilename, "w+");
408 if (!File)
409 {
410 fprintf (stderr, "Could not open output file %s\n",
411 DisasmFilename);
412 return (AE_ERROR);
413 }
414
415 /* Emit the common file header */
416
417 AcpiOsRedirectOutput (File);
418
419 AcpiOsPrintf ("/*\n");
420 AcpiOsPrintf (ACPI_COMMON_HEADER ("iASL Compiler/Disassembler", " * "));
421
422 if (TableCount == 0)
423 {
424 AcpiOsPrintf (" * Template for [%4.4s] ACPI Table",
425 Signature);
426 }
427 else
428 {
429 AcpiOsPrintf (" * Template for [%4.4s] and %u [SSDT] ACPI Tables",
430 Signature, TableCount);
431 }
432
433 /* Dump the actual ACPI table */
434
435 if (TableData)
436 {
437 /* Normal case, tables that appear in AcpiDmTableData */
438
439 AcpiOsPrintf (" (static data table)\n");
440
441 if (Gbl_VerboseTemplates)
442 {
443 AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]"
444 " FieldName : HexFieldValue\n */\n\n");
445 }
446 else
447 {
448 AcpiOsPrintf (" * Format: [ByteLength]"
449 " FieldName : HexFieldValue\n */\n");
450 }
451
452 AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
453 TableData->Template));
454 }
455 else
456 {
457 /* Special ACPI tables - DSDT, SSDT, OSDT, FACS, RSDP */
458
459 AcpiOsPrintf (" (AML byte code table)\n");
460 AcpiOsPrintf (" */\n");
461
462 if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT))
463 {
464 Actual = DtEmitDefinitionBlock (
465 File, DisasmFilename, ACPI_SIG_DSDT, 1);
466 if (Actual < 0)
467 {
468 Status = AE_ERROR;
469 goto Cleanup;
470 }
471
472 /* Emit any requested SSDTs into the same file */
473
474 for (i = 1; i <= TableCount; i++)
475 {
476 Actual = DtEmitDefinitionBlock (
477 File, DisasmFilename, ACPI_SIG_SSDT, i + 1);
478 if (Actual < 0)
479 {
480 Status = AE_ERROR;
481 goto Cleanup;
482 }
483 }
484 }
485 else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT))
486 {
487 Actual = DtEmitDefinitionBlock (
488 File, DisasmFilename, ACPI_SIG_SSDT, 1);
489 if (Actual < 0)
490 {
491 Status = AE_ERROR;
492 goto Cleanup;
493 }
494 }
495 else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_OSDT))
496 {
497 Actual = DtEmitDefinitionBlock (
498 File, DisasmFilename, ACPI_SIG_OSDT, 1);
499 if (Actual < 0)
500 {
501 Status = AE_ERROR;
502 goto Cleanup;
503 }
504 }
505 else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
506 {
507 AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
508 TemplateFacs));
509 }
510 else if (ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME))
511 {
512 AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,
513 TemplateRsdp));
514 }
515 else
516 {
517 fprintf (stderr,
518 "%4.4s, Unrecognized ACPI table signature\n", Signature);
519 Status = AE_ERROR;
520 goto Cleanup;
521 }
522 }
523
524 if (TableCount == 0)
525 {
526 fprintf (stderr,
527 "Created ACPI table template for [%4.4s], "
528 "written to \"%s\"\n",
529 Signature, DisasmFilename);
530 }
531 else
532 {
533 fprintf (stderr,
534 "Created ACPI table templates for [%4.4s] "
535 "and %u [SSDT], written to \"%s\"\n",
536 Signature, TableCount, DisasmFilename);
537 }
538
539 Cleanup:
540 fclose (File);
541 AcpiOsRedirectOutput (stdout);
542 return (Status);
543 }
544
545
546 /*******************************************************************************
547 *
548 * FUNCTION: DtEmitDefinitionBlock
549 *
550 * PARAMETERS: File - An open file for the block
551 * Filename - Filename for same, for error msg(s)
552 * Signature - ACPI signature for the block
553 * Instance - Used for multiple SSDTs in the same file
554 *
555 * RETURN: Status from fprintf
556 *
557 * DESCRIPTION: Emit the raw ASL for a complete Definition Block (DSDT or SSDT)
558 *
559 * Note: The AMLFileName parameter for DefinitionBlock is left as a NULL
560 * string. This allows the compiler to create the output AML filename from
561 * the input filename.
562 *
563 ******************************************************************************/
564
565 static int
566 DtEmitDefinitionBlock (
567 FILE *File,
568 char *Filename,
569 char *Signature,
570 UINT32 Instance)
571 {
572 int Status;
573
574
575 Status = fprintf (File,
576 "DefinitionBlock (\"\", \"%4.4s\", 2, \"Intel\", \"_%4.4s_%.2X\", 0x00000001)\n"
577 "{\n"
578 " Method (%2.2s%.2X)\n"
579 " {\n"
580 " }\n"
581 "}\n\n",
582 Signature, Signature, Instance, Signature, Instance);
583
584 if (Status < 0)
585 {
586 fprintf (stderr,
587 "Could not write %4.4s to output file %s\n",
588 Signature, Filename);
589 }
590
591 return (Status);
592 }
593