1 /****************************************************************************** 2 * 3 * Module Name: dttemplate - ACPI table template generation 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, 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