1 /****************************************************************************** 2 * 3 * Module Name: dtfield.c - Code generation for individual source fields 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 ***************************************************************************** 115 * 116 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 #include <contrib/dev/acpica/compiler/aslcompiler.h> 153 #include <contrib/dev/acpica/compiler/dtcompiler.h> 154 155 #define _COMPONENT DT_COMPILER 156 ACPI_MODULE_NAME ("dtfield") 157 158 159 /* Local prototypes */ 160 161 static void 162 DtCompileString ( 163 UINT8 *Buffer, 164 DT_FIELD *Field, 165 UINT32 ByteLength); 166 167 static void 168 DtCompileUnicode ( 169 UINT8 *Buffer, 170 DT_FIELD *Field, 171 UINT32 ByteLength); 172 173 static ACPI_STATUS 174 DtCompileUuid ( 175 UINT8 *Buffer, 176 DT_FIELD *Field, 177 UINT32 ByteLength); 178 179 static char * 180 DtNormalizeBuffer ( 181 char *Buffer, 182 UINT32 *Count); 183 184 185 /****************************************************************************** 186 * 187 * FUNCTION: DtCompileOneField 188 * 189 * PARAMETERS: Buffer - Output buffer 190 * Field - Field to be compiled 191 * ByteLength - Byte length of the field 192 * Type - Field type 193 * 194 * RETURN: None 195 * 196 * DESCRIPTION: Compile a field value to binary 197 * 198 *****************************************************************************/ 199 200 void 201 DtCompileOneField ( 202 UINT8 *Buffer, 203 DT_FIELD *Field, 204 UINT32 ByteLength, 205 UINT8 Type, 206 UINT8 Flags) 207 { 208 ACPI_STATUS Status; 209 210 211 switch (Type) 212 { 213 case DT_FIELD_TYPE_INTEGER: 214 215 DtCompileInteger (Buffer, Field, ByteLength, Flags); 216 break; 217 218 case DT_FIELD_TYPE_STRING: 219 220 DtCompileString (Buffer, Field, ByteLength); 221 break; 222 223 case DT_FIELD_TYPE_UUID: 224 225 Status = DtCompileUuid (Buffer, Field, ByteLength); 226 if (ACPI_SUCCESS (Status)) 227 { 228 break; 229 } 230 231 /* Fall through. */ 232 233 case DT_FIELD_TYPE_BUFFER: 234 235 DtCompileBuffer (Buffer, Field->Value, Field, ByteLength); 236 break; 237 238 case DT_FIELD_TYPE_UNICODE: 239 240 DtCompileUnicode (Buffer, Field, ByteLength); 241 break; 242 243 case DT_FIELD_TYPE_DEVICE_PATH: 244 245 break; 246 247 default: 248 249 DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid field type"); 250 break; 251 } 252 } 253 254 255 /****************************************************************************** 256 * 257 * FUNCTION: DtCompileString 258 * 259 * PARAMETERS: Buffer - Output buffer 260 * Field - String to be copied to buffer 261 * ByteLength - Maximum length of string 262 * 263 * RETURN: None 264 * 265 * DESCRIPTION: Copy string to the buffer 266 * 267 *****************************************************************************/ 268 269 static void 270 DtCompileString ( 271 UINT8 *Buffer, 272 DT_FIELD *Field, 273 UINT32 ByteLength) 274 { 275 UINT32 Length; 276 277 278 Length = strlen (Field->Value); 279 280 /* Check if the string is too long for the field */ 281 282 if (Length > ByteLength) 283 { 284 sprintf (MsgBuffer, "Maximum %u characters", ByteLength); 285 DtError (ASL_ERROR, ASL_MSG_STRING_LENGTH, Field, MsgBuffer); 286 Length = ByteLength; 287 } 288 289 memcpy (Buffer, Field->Value, Length); 290 } 291 292 293 /****************************************************************************** 294 * 295 * FUNCTION: DtCompileUnicode 296 * 297 * PARAMETERS: Buffer - Output buffer 298 * Field - String to be copied to buffer 299 * ByteLength - Maximum length of string 300 * 301 * RETURN: None 302 * 303 * DESCRIPTION: Convert ASCII string to Unicode string 304 * 305 * Note: The Unicode string is 16 bits per character, no leading signature, 306 * with a 16-bit terminating NULL. 307 * 308 *****************************************************************************/ 309 310 static void 311 DtCompileUnicode ( 312 UINT8 *Buffer, 313 DT_FIELD *Field, 314 UINT32 ByteLength) 315 { 316 UINT32 Count; 317 UINT32 i; 318 char *AsciiString; 319 UINT16 *UnicodeString; 320 321 322 AsciiString = Field->Value; 323 UnicodeString = (UINT16 *) Buffer; 324 Count = strlen (AsciiString) + 1; 325 326 /* Convert to Unicode string (including null terminator) */ 327 328 for (i = 0; i < Count; i++) 329 { 330 UnicodeString[i] = (UINT16) AsciiString[i]; 331 } 332 } 333 334 335 /******************************************************************************* 336 * 337 * FUNCTION: DtCompileUuid 338 * 339 * PARAMETERS: Buffer - Output buffer 340 * Field - String to be copied to buffer 341 * ByteLength - Maximum length of string 342 * 343 * RETURN: None 344 * 345 * DESCRIPTION: Convert UUID string to 16-byte buffer 346 * 347 ******************************************************************************/ 348 349 static ACPI_STATUS 350 DtCompileUuid ( 351 UINT8 *Buffer, 352 DT_FIELD *Field, 353 UINT32 ByteLength) 354 { 355 char *InString; 356 ACPI_STATUS Status; 357 358 359 InString = Field->Value; 360 361 Status = AuValidateUuid (InString); 362 if (ACPI_FAILURE (Status)) 363 { 364 sprintf (MsgBuffer, "%s", Field->Value); 365 DtNameError (ASL_ERROR, ASL_MSG_INVALID_UUID, Field, MsgBuffer); 366 } 367 else 368 { 369 AcpiUtConvertStringToUuid (InString, Buffer); 370 } 371 372 return (Status); 373 } 374 375 376 /****************************************************************************** 377 * 378 * FUNCTION: DtCompileInteger 379 * 380 * PARAMETERS: Buffer - Output buffer 381 * Field - Field obj with Integer to be compiled 382 * ByteLength - Byte length of the integer 383 * Flags - Additional compile info 384 * 385 * RETURN: None 386 * 387 * DESCRIPTION: Compile an integer. Supports integer expressions with C-style 388 * operators. 389 * 390 *****************************************************************************/ 391 392 void 393 DtCompileInteger ( 394 UINT8 *Buffer, 395 DT_FIELD *Field, 396 UINT32 ByteLength, 397 UINT8 Flags) 398 { 399 UINT64 Value; 400 UINT64 MaxValue; 401 ACPI_STATUS Status; 402 403 404 /* Output buffer byte length must be in range 1-8 */ 405 406 if ((ByteLength > 8) || (ByteLength == 0)) 407 { 408 DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, 409 "Invalid internal Byte length"); 410 return; 411 } 412 413 /* Resolve integer expression to a single integer value */ 414 415 Status = DtResolveIntegerExpression (Field, &Value); 416 if (ACPI_FAILURE (Status)) 417 { 418 return; 419 } 420 421 /* 422 * Ensure that reserved fields are set properly. Note: uses 423 * the DT_NON_ZERO flag to indicate that the reserved value 424 * must be exactly one. Otherwise, the value must be zero. 425 * This is sufficient for now. 426 */ 427 428 /* TBD: Should use a flag rather than compare "Reserved" */ 429 430 if (!strcmp (Field->Name, "Reserved")) 431 { 432 if (Flags & DT_NON_ZERO) 433 { 434 if (Value != 1) 435 { 436 DtError (ASL_WARNING, ASL_MSG_RESERVED_VALUE, Field, 437 "Must be one, setting to one"); 438 Value = 1; 439 } 440 } 441 else if (Value != 0) 442 { 443 DtError (ASL_WARNING, ASL_MSG_RESERVED_VALUE, Field, 444 "Must be zero, setting to zero"); 445 Value = 0; 446 } 447 } 448 449 /* Check if the value must be non-zero */ 450 451 else if ((Flags & DT_NON_ZERO) && (Value == 0)) 452 { 453 DtError (ASL_ERROR, ASL_MSG_ZERO_VALUE, Field, NULL); 454 } 455 456 /* 457 * Generate the maximum value for the data type (ByteLength) 458 * Note: construct chosen for maximum portability 459 */ 460 MaxValue = ((UINT64) (-1)) >> (64 - (ByteLength * 8)); 461 462 /* Validate that the input value is within range of the target */ 463 464 if (Value > MaxValue) 465 { 466 sprintf (MsgBuffer, "%8.8X%8.8X - max %u bytes", 467 ACPI_FORMAT_UINT64 (Value), ByteLength); 468 DtError (ASL_ERROR, ASL_MSG_INTEGER_SIZE, Field, MsgBuffer); 469 } 470 471 memcpy (Buffer, &Value, ByteLength); 472 return; 473 } 474 475 476 /****************************************************************************** 477 * 478 * FUNCTION: DtNormalizeBuffer 479 * 480 * PARAMETERS: Buffer - Input buffer 481 * Count - Output the count of hex numbers in 482 * the Buffer 483 * 484 * RETURN: The normalized buffer, must be freed by caller 485 * 486 * DESCRIPTION: [1A,2B,3C,4D] or 1A, 2B, 3C, 4D will be normalized 487 * to 1A 2B 3C 4D 488 * 489 *****************************************************************************/ 490 491 static char * 492 DtNormalizeBuffer ( 493 char *Buffer, 494 UINT32 *Count) 495 { 496 char *NewBuffer; 497 char *TmpBuffer; 498 UINT32 BufferCount = 0; 499 BOOLEAN Separator = TRUE; 500 char c; 501 502 503 NewBuffer = UtLocalCalloc (strlen (Buffer) + 1); 504 TmpBuffer = NewBuffer; 505 506 while ((c = *Buffer++)) 507 { 508 switch (c) 509 { 510 /* Valid separators */ 511 512 case '[': 513 case ']': 514 case ' ': 515 case ',': 516 517 Separator = TRUE; 518 break; 519 520 default: 521 522 if (Separator) 523 { 524 /* Insert blank as the standard separator */ 525 526 if (NewBuffer[0]) 527 { 528 *TmpBuffer++ = ' '; 529 BufferCount++; 530 } 531 532 Separator = FALSE; 533 } 534 535 *TmpBuffer++ = c; 536 break; 537 } 538 } 539 540 *Count = BufferCount + 1; 541 return (NewBuffer); 542 } 543 544 545 /****************************************************************************** 546 * 547 * FUNCTION: DtCompileBuffer 548 * 549 * PARAMETERS: Buffer - Output buffer 550 * StringValue - Integer list to be compiled 551 * Field - Current field object 552 * ByteLength - Byte length of the integer list 553 * 554 * RETURN: Count of remaining data in the input list 555 * 556 * DESCRIPTION: Compile and pack an integer list, for example 557 * "AA 1F 20 3B" ==> Buffer[] = {0xAA,0x1F,0x20,0x3B} 558 * 559 *****************************************************************************/ 560 561 UINT32 562 DtCompileBuffer ( 563 UINT8 *Buffer, 564 char *StringValue, 565 DT_FIELD *Field, 566 UINT32 ByteLength) 567 { 568 char *Substring; 569 ACPI_STATUS Status; 570 UINT32 Count; 571 UINT32 i; 572 573 574 /* Allow several different types of value separators */ 575 576 StringValue = DtNormalizeBuffer (StringValue, &Count); 577 Substring = StringValue; 578 579 /* Each element of StringValue is now three chars (2 hex + 1 space) */ 580 581 for (i = 0; i < Count; i++, Substring += 3) 582 { 583 /* Check for byte value too long */ 584 585 if (*(&Substring[2]) && 586 (*(&Substring[2]) != ' ')) 587 { 588 DtError (ASL_ERROR, ASL_MSG_BUFFER_ELEMENT, Field, Substring); 589 goto Exit; 590 } 591 592 /* Convert two ASCII characters to one hex byte */ 593 594 Status = AcpiUtAsciiToHexByte (Substring, &Buffer[i]); 595 if (ACPI_FAILURE (Status)) 596 { 597 DtError (ASL_ERROR, ASL_MSG_BUFFER_ELEMENT, Field, Substring); 598 goto Exit; 599 } 600 } 601 602 Exit: 603 ACPI_FREE (StringValue); 604 return (ByteLength - Count); 605 } 606 607 608 /****************************************************************************** 609 * 610 * FUNCTION: DtCompileFlag 611 * 612 * PARAMETERS: Buffer - Output buffer 613 * Field - Field to be compiled 614 * Info - Flag info 615 * 616 * RETURN: None 617 * 618 * DESCRIPTION: Compile a flag field. Handles flags up to 64 bits. 619 * 620 *****************************************************************************/ 621 622 void 623 DtCompileFlag ( 624 UINT8 *Buffer, 625 DT_FIELD *Field, 626 ACPI_DMTABLE_INFO *Info) 627 { 628 UINT64 Value = 0; 629 UINT32 BitLength = 1; 630 UINT8 BitPosition = 0; 631 ACPI_STATUS Status; 632 633 634 Status = AcpiUtStrtoul64 (Field->Value, 635 (ACPI_STRTOUL_64BIT | ACPI_STRTOUL_BASE16), &Value); 636 if (ACPI_FAILURE (Status)) 637 { 638 DtError (ASL_ERROR, ASL_MSG_INVALID_HEX_INTEGER, Field, NULL); 639 } 640 641 switch (Info->Opcode) 642 { 643 case ACPI_DMT_FLAG0: 644 case ACPI_DMT_FLAG1: 645 case ACPI_DMT_FLAG2: 646 case ACPI_DMT_FLAG3: 647 case ACPI_DMT_FLAG4: 648 case ACPI_DMT_FLAG5: 649 case ACPI_DMT_FLAG6: 650 case ACPI_DMT_FLAG7: 651 652 BitPosition = Info->Opcode; 653 BitLength = 1; 654 break; 655 656 case ACPI_DMT_FLAGS0: 657 658 BitPosition = 0; 659 BitLength = 2; 660 break; 661 662 663 case ACPI_DMT_FLAGS1: 664 665 BitPosition = 1; 666 BitLength = 2; 667 break; 668 669 670 case ACPI_DMT_FLAGS2: 671 672 BitPosition = 2; 673 BitLength = 2; 674 break; 675 676 case ACPI_DMT_FLAGS4: 677 678 BitPosition = 4; 679 BitLength = 2; 680 break; 681 682 default: 683 684 DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid flag opcode"); 685 break; 686 } 687 688 /* Check range of the input flag value */ 689 690 if (Value >= ((UINT64) 1 << BitLength)) 691 { 692 sprintf (MsgBuffer, "Maximum %u bit", BitLength); 693 DtError (ASL_ERROR, ASL_MSG_FLAG_VALUE, Field, MsgBuffer); 694 Value = 0; 695 } 696 697 *Buffer |= (UINT8) (Value << BitPosition); 698 } 699