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