1 /******************************************************************************* 2 * 3 * Module Name: utresrc - Resource management utilities 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 <acpi/acpi.h> 45 #include "accommon.h" 46 #include "acresrc.h" 47 48 #define _COMPONENT ACPI_UTILITIES 49 ACPI_MODULE_NAME("utresrc") 50 51 #if defined(ACPI_DEBUG_OUTPUT) || defined (ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER) 52 /* 53 * Strings used to decode resource descriptors. 54 * Used by both the disassembler and the debugger resource dump routines 55 */ 56 const char *acpi_gbl_bm_decode[] = { 57 "NotBusMaster", 58 "BusMaster" 59 }; 60 61 const char *acpi_gbl_config_decode[] = { 62 "0 - Good Configuration", 63 "1 - Acceptable Configuration", 64 "2 - Suboptimal Configuration", 65 "3 - ***Invalid Configuration***", 66 }; 67 68 const char *acpi_gbl_consume_decode[] = { 69 "ResourceProducer", 70 "ResourceConsumer" 71 }; 72 73 const char *acpi_gbl_dec_decode[] = { 74 "PosDecode", 75 "SubDecode" 76 }; 77 78 const char *acpi_gbl_he_decode[] = { 79 "Level", 80 "Edge" 81 }; 82 83 const char *acpi_gbl_io_decode[] = { 84 "Decode10", 85 "Decode16" 86 }; 87 88 const char *acpi_gbl_ll_decode[] = { 89 "ActiveHigh", 90 "ActiveLow", 91 "ActiveBoth", 92 "Reserved" 93 }; 94 95 const char *acpi_gbl_max_decode[] = { 96 "MaxNotFixed", 97 "MaxFixed" 98 }; 99 100 const char *acpi_gbl_mem_decode[] = { 101 "NonCacheable", 102 "Cacheable", 103 "WriteCombining", 104 "Prefetchable" 105 }; 106 107 const char *acpi_gbl_min_decode[] = { 108 "MinNotFixed", 109 "MinFixed" 110 }; 111 112 const char *acpi_gbl_mtp_decode[] = { 113 "AddressRangeMemory", 114 "AddressRangeReserved", 115 "AddressRangeACPI", 116 "AddressRangeNVS" 117 }; 118 119 const char *acpi_gbl_rng_decode[] = { 120 "InvalidRanges", 121 "NonISAOnlyRanges", 122 "ISAOnlyRanges", 123 "EntireRange" 124 }; 125 126 const char *acpi_gbl_rw_decode[] = { 127 "ReadOnly", 128 "ReadWrite" 129 }; 130 131 const char *acpi_gbl_shr_decode[] = { 132 "Exclusive", 133 "Shared", 134 "ExclusiveAndWake", /* ACPI 5.0 */ 135 "SharedAndWake" /* ACPI 5.0 */ 136 }; 137 138 const char *acpi_gbl_siz_decode[] = { 139 "Transfer8", 140 "Transfer8_16", 141 "Transfer16", 142 "InvalidSize" 143 }; 144 145 const char *acpi_gbl_trs_decode[] = { 146 "DenseTranslation", 147 "SparseTranslation" 148 }; 149 150 const char *acpi_gbl_ttp_decode[] = { 151 "TypeStatic", 152 "TypeTranslation" 153 }; 154 155 const char *acpi_gbl_typ_decode[] = { 156 "Compatibility", 157 "TypeA", 158 "TypeB", 159 "TypeF" 160 }; 161 162 const char *acpi_gbl_ppc_decode[] = { 163 "PullDefault", 164 "PullUp", 165 "PullDown", 166 "PullNone" 167 }; 168 169 const char *acpi_gbl_ior_decode[] = { 170 "IoRestrictionNone", 171 "IoRestrictionInputOnly", 172 "IoRestrictionOutputOnly", 173 "IoRestrictionNoneAndPreserve" 174 }; 175 176 const char *acpi_gbl_dts_decode[] = { 177 "Width8bit", 178 "Width16bit", 179 "Width32bit", 180 "Width64bit", 181 "Width128bit", 182 "Width256bit", 183 }; 184 185 /* GPIO connection type */ 186 187 const char *acpi_gbl_ct_decode[] = { 188 "Interrupt", 189 "I/O" 190 }; 191 192 /* Serial bus type */ 193 194 const char *acpi_gbl_sbt_decode[] = { 195 "/* UNKNOWN serial bus type */", 196 "I2C", 197 "SPI", 198 "UART" 199 }; 200 201 /* I2C serial bus access mode */ 202 203 const char *acpi_gbl_am_decode[] = { 204 "AddressingMode7Bit", 205 "AddressingMode10Bit" 206 }; 207 208 /* I2C serial bus slave mode */ 209 210 const char *acpi_gbl_sm_decode[] = { 211 "ControllerInitiated", 212 "DeviceInitiated" 213 }; 214 215 /* SPI serial bus wire mode */ 216 217 const char *acpi_gbl_wm_decode[] = { 218 "FourWireMode", 219 "ThreeWireMode" 220 }; 221 222 /* SPI serial clock phase */ 223 224 const char *acpi_gbl_cph_decode[] = { 225 "ClockPhaseFirst", 226 "ClockPhaseSecond" 227 }; 228 229 /* SPI serial bus clock polarity */ 230 231 const char *acpi_gbl_cpo_decode[] = { 232 "ClockPolarityLow", 233 "ClockPolarityHigh" 234 }; 235 236 /* SPI serial bus device polarity */ 237 238 const char *acpi_gbl_dp_decode[] = { 239 "PolarityLow", 240 "PolarityHigh" 241 }; 242 243 /* UART serial bus endian */ 244 245 const char *acpi_gbl_ed_decode[] = { 246 "LittleEndian", 247 "BigEndian" 248 }; 249 250 /* UART serial bus bits per byte */ 251 252 const char *acpi_gbl_bpb_decode[] = { 253 "DataBitsFive", 254 "DataBitsSix", 255 "DataBitsSeven", 256 "DataBitsEight", 257 "DataBitsNine", 258 "/* UNKNOWN Bits per byte */", 259 "/* UNKNOWN Bits per byte */", 260 "/* UNKNOWN Bits per byte */" 261 }; 262 263 /* UART serial bus stop bits */ 264 265 const char *acpi_gbl_sb_decode[] = { 266 "StopBitsZero", 267 "StopBitsOne", 268 "StopBitsOnePlusHalf", 269 "StopBitsTwo" 270 }; 271 272 /* UART serial bus flow control */ 273 274 const char *acpi_gbl_fc_decode[] = { 275 "FlowControlNone", 276 "FlowControlHardware", 277 "FlowControlXON", 278 "/* UNKNOWN flow control keyword */" 279 }; 280 281 /* UART serial bus parity type */ 282 283 const char *acpi_gbl_pt_decode[] = { 284 "ParityTypeNone", 285 "ParityTypeEven", 286 "ParityTypeOdd", 287 "ParityTypeMark", 288 "ParityTypeSpace", 289 "/* UNKNOWN parity keyword */", 290 "/* UNKNOWN parity keyword */", 291 "/* UNKNOWN parity keyword */" 292 }; 293 294 /* pin_config type */ 295 296 const char *acpi_gbl_ptyp_decode[] = { 297 "Default", 298 "Bias Pull-up", 299 "Bias Pull-down", 300 "Bias Default", 301 "Bias Disable", 302 "Bias High Impedance", 303 "Bias Bus Hold", 304 "Drive Open Drain", 305 "Drive Open Source", 306 "Drive Push Pull", 307 "Drive Strength", 308 "Slew Rate", 309 "Input Debounce", 310 "Input Schmitt Trigger", 311 }; 312 313 #endif 314 315 /* 316 * Base sizes of the raw AML resource descriptors, indexed by resource type. 317 * Zero indicates a reserved (and therefore invalid) resource type. 318 */ 319 const u8 acpi_gbl_resource_aml_sizes[] = { 320 /* Small descriptors */ 321 322 0, 323 0, 324 0, 325 0, 326 ACPI_AML_SIZE_SMALL(struct aml_resource_irq), 327 ACPI_AML_SIZE_SMALL(struct aml_resource_dma), 328 ACPI_AML_SIZE_SMALL(struct aml_resource_start_dependent), 329 ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent), 330 ACPI_AML_SIZE_SMALL(struct aml_resource_io), 331 ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io), 332 ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_dma), 333 0, 334 0, 335 0, 336 ACPI_AML_SIZE_SMALL(struct aml_resource_vendor_small), 337 ACPI_AML_SIZE_SMALL(struct aml_resource_end_tag), 338 339 /* Large descriptors */ 340 341 0, 342 ACPI_AML_SIZE_LARGE(struct aml_resource_memory24), 343 ACPI_AML_SIZE_LARGE(struct aml_resource_generic_register), 344 0, 345 ACPI_AML_SIZE_LARGE(struct aml_resource_vendor_large), 346 ACPI_AML_SIZE_LARGE(struct aml_resource_memory32), 347 ACPI_AML_SIZE_LARGE(struct aml_resource_fixed_memory32), 348 ACPI_AML_SIZE_LARGE(struct aml_resource_address32), 349 ACPI_AML_SIZE_LARGE(struct aml_resource_address16), 350 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq), 351 ACPI_AML_SIZE_LARGE(struct aml_resource_address64), 352 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64), 353 ACPI_AML_SIZE_LARGE(struct aml_resource_gpio), 354 ACPI_AML_SIZE_LARGE(struct aml_resource_pin_function), 355 ACPI_AML_SIZE_LARGE(struct aml_resource_common_serialbus), 356 ACPI_AML_SIZE_LARGE(struct aml_resource_pin_config), 357 }; 358 359 const u8 acpi_gbl_resource_aml_serial_bus_sizes[] = { 360 0, 361 ACPI_AML_SIZE_LARGE(struct aml_resource_i2c_serialbus), 362 ACPI_AML_SIZE_LARGE(struct aml_resource_spi_serialbus), 363 ACPI_AML_SIZE_LARGE(struct aml_resource_uart_serialbus), 364 }; 365 366 /* 367 * Resource types, used to validate the resource length field. 368 * The length of fixed-length types must match exactly, variable 369 * lengths must meet the minimum required length, etc. 370 * Zero indicates a reserved (and therefore invalid) resource type. 371 */ 372 static const u8 acpi_gbl_resource_types[] = { 373 /* Small descriptors */ 374 375 0, 376 0, 377 0, 378 0, 379 ACPI_SMALL_VARIABLE_LENGTH, /* 04 IRQ */ 380 ACPI_FIXED_LENGTH, /* 05 DMA */ 381 ACPI_SMALL_VARIABLE_LENGTH, /* 06 start_dependent_functions */ 382 ACPI_FIXED_LENGTH, /* 07 end_dependent_functions */ 383 ACPI_FIXED_LENGTH, /* 08 IO */ 384 ACPI_FIXED_LENGTH, /* 09 fixed_IO */ 385 ACPI_FIXED_LENGTH, /* 0A fixed_DMA */ 386 0, 387 0, 388 0, 389 ACPI_VARIABLE_LENGTH, /* 0E vendor_short */ 390 ACPI_FIXED_LENGTH, /* 0F end_tag */ 391 392 /* Large descriptors */ 393 394 0, 395 ACPI_FIXED_LENGTH, /* 01 Memory24 */ 396 ACPI_FIXED_LENGTH, /* 02 generic_register */ 397 0, 398 ACPI_VARIABLE_LENGTH, /* 04 vendor_long */ 399 ACPI_FIXED_LENGTH, /* 05 Memory32 */ 400 ACPI_FIXED_LENGTH, /* 06 memory32_fixed */ 401 ACPI_VARIABLE_LENGTH, /* 07 Dword* address */ 402 ACPI_VARIABLE_LENGTH, /* 08 Word* address */ 403 ACPI_VARIABLE_LENGTH, /* 09 extended_IRQ */ 404 ACPI_VARIABLE_LENGTH, /* 0A Qword* address */ 405 ACPI_FIXED_LENGTH, /* 0B Extended* address */ 406 ACPI_VARIABLE_LENGTH, /* 0C Gpio* */ 407 ACPI_VARIABLE_LENGTH, /* 0D pin_function */ 408 ACPI_VARIABLE_LENGTH, /* 0E *serial_bus */ 409 ACPI_VARIABLE_LENGTH, /* 0F pin_config */ 410 }; 411 412 /******************************************************************************* 413 * 414 * FUNCTION: acpi_ut_walk_aml_resources 415 * 416 * PARAMETERS: walk_state - Current walk info 417 * PARAMETERS: aml - Pointer to the raw AML resource template 418 * aml_length - Length of the entire template 419 * user_function - Called once for each descriptor found. If 420 * NULL, a pointer to the end_tag is returned 421 * context - Passed to user_function 422 * 423 * RETURN: Status 424 * 425 * DESCRIPTION: Walk a raw AML resource list(buffer). User function called 426 * once for each resource found. 427 * 428 ******************************************************************************/ 429 430 acpi_status 431 acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state, 432 u8 *aml, 433 acpi_size aml_length, 434 acpi_walk_aml_callback user_function, void **context) 435 { 436 acpi_status status; 437 u8 *end_aml; 438 u8 resource_index; 439 u32 length; 440 u32 offset = 0; 441 u8 end_tag[2] = { 0x79, 0x00 }; 442 443 ACPI_FUNCTION_TRACE(ut_walk_aml_resources); 444 445 /* The absolute minimum resource template is one end_tag descriptor */ 446 447 if (aml_length < sizeof(struct aml_resource_end_tag)) { 448 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); 449 } 450 451 /* Point to the end of the resource template buffer */ 452 453 end_aml = aml + aml_length; 454 455 /* Walk the byte list, abort on any invalid descriptor type or length */ 456 457 while (aml < end_aml) { 458 459 /* Validate the Resource Type and Resource Length */ 460 461 status = 462 acpi_ut_validate_resource(walk_state, aml, &resource_index); 463 if (ACPI_FAILURE(status)) { 464 /* 465 * Exit on failure. Cannot continue because the descriptor 466 * length may be bogus also. 467 */ 468 return_ACPI_STATUS(status); 469 } 470 471 /* Get the length of this descriptor */ 472 473 length = acpi_ut_get_descriptor_length(aml); 474 475 /* Invoke the user function */ 476 477 if (user_function) { 478 status = 479 user_function(aml, length, offset, resource_index, 480 context); 481 if (ACPI_FAILURE(status)) { 482 return_ACPI_STATUS(status); 483 } 484 } 485 486 /* An end_tag descriptor terminates this resource template */ 487 488 if (acpi_ut_get_resource_type(aml) == 489 ACPI_RESOURCE_NAME_END_TAG) { 490 /* 491 * There must be at least one more byte in the buffer for 492 * the 2nd byte of the end_tag 493 */ 494 if ((aml + 1) >= end_aml) { 495 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); 496 } 497 498 /* 499 * The end_tag opcode must be followed by a zero byte. 500 * Although this byte is technically defined to be a checksum, 501 * in practice, all ASL compilers set this byte to zero. 502 */ 503 if (*(aml + 1) != 0) { 504 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); 505 } 506 507 /* Return the pointer to the end_tag if requested */ 508 509 if (!user_function) { 510 *context = aml; 511 } 512 513 /* Normal exit */ 514 515 return_ACPI_STATUS(AE_OK); 516 } 517 518 aml += length; 519 offset += length; 520 } 521 522 /* Did not find an end_tag descriptor */ 523 524 if (user_function) { 525 526 /* Insert an end_tag anyway. acpi_rs_get_list_length always leaves room */ 527 528 (void)acpi_ut_validate_resource(walk_state, end_tag, 529 &resource_index); 530 status = 531 user_function(end_tag, 2, offset, resource_index, context); 532 if (ACPI_FAILURE(status)) { 533 return_ACPI_STATUS(status); 534 } 535 } 536 537 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); 538 } 539 540 /******************************************************************************* 541 * 542 * FUNCTION: acpi_ut_validate_resource 543 * 544 * PARAMETERS: walk_state - Current walk info 545 * aml - Pointer to the raw AML resource descriptor 546 * return_index - Where the resource index is returned. NULL 547 * if the index is not required. 548 * 549 * RETURN: Status, and optionally the Index into the global resource tables 550 * 551 * DESCRIPTION: Validate an AML resource descriptor by checking the Resource 552 * Type and Resource Length. Returns an index into the global 553 * resource information/dispatch tables for later use. 554 * 555 ******************************************************************************/ 556 557 acpi_status 558 acpi_ut_validate_resource(struct acpi_walk_state *walk_state, 559 void *aml, u8 *return_index) 560 { 561 union aml_resource *aml_resource; 562 u8 resource_type; 563 u8 resource_index; 564 acpi_rs_length resource_length; 565 acpi_rs_length minimum_resource_length; 566 567 ACPI_FUNCTION_ENTRY(); 568 569 /* 570 * 1) Validate the resource_type field (Byte 0) 571 */ 572 resource_type = ACPI_GET8(aml); 573 574 /* 575 * Byte 0 contains the descriptor name (Resource Type) 576 * Examine the large/small bit in the resource header 577 */ 578 if (resource_type & ACPI_RESOURCE_NAME_LARGE) { 579 580 /* Verify the large resource type (name) against the max */ 581 582 if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { 583 goto invalid_resource; 584 } 585 586 /* 587 * Large Resource Type -- bits 6:0 contain the name 588 * Translate range 0x80-0x8B to index range 0x10-0x1B 589 */ 590 resource_index = (u8) (resource_type - 0x70); 591 } else { 592 /* 593 * Small Resource Type -- bits 6:3 contain the name 594 * Shift range to index range 0x00-0x0F 595 */ 596 resource_index = (u8) 597 ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3); 598 } 599 600 /* 601 * Check validity of the resource type, via acpi_gbl_resource_types. 602 * Zero indicates an invalid resource. 603 */ 604 if (!acpi_gbl_resource_types[resource_index]) { 605 goto invalid_resource; 606 } 607 608 /* 609 * Validate the resource_length field. This ensures that the length 610 * is at least reasonable, and guarantees that it is non-zero. 611 */ 612 resource_length = acpi_ut_get_resource_length(aml); 613 minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index]; 614 615 /* Validate based upon the type of resource - fixed length or variable */ 616 617 switch (acpi_gbl_resource_types[resource_index]) { 618 case ACPI_FIXED_LENGTH: 619 620 /* Fixed length resource, length must match exactly */ 621 622 if (resource_length != minimum_resource_length) { 623 goto bad_resource_length; 624 } 625 break; 626 627 case ACPI_VARIABLE_LENGTH: 628 629 /* Variable length resource, length must be at least the minimum */ 630 631 if (resource_length < minimum_resource_length) { 632 goto bad_resource_length; 633 } 634 break; 635 636 case ACPI_SMALL_VARIABLE_LENGTH: 637 638 /* Small variable length resource, length can be (Min) or (Min-1) */ 639 640 if ((resource_length > minimum_resource_length) || 641 (resource_length < (minimum_resource_length - 1))) { 642 goto bad_resource_length; 643 } 644 break; 645 646 default: 647 648 /* Shouldn't happen (because of validation earlier), but be sure */ 649 650 goto invalid_resource; 651 } 652 653 aml_resource = ACPI_CAST_PTR(union aml_resource, aml); 654 if (resource_type == ACPI_RESOURCE_NAME_SERIAL_BUS) { 655 656 /* Validate the bus_type field */ 657 658 if ((aml_resource->common_serial_bus.type == 0) || 659 (aml_resource->common_serial_bus.type > 660 AML_RESOURCE_MAX_SERIALBUSTYPE)) { 661 if (walk_state) { 662 ACPI_ERROR((AE_INFO, 663 "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X", 664 aml_resource->common_serial_bus. 665 type)); 666 } 667 return (AE_AML_INVALID_RESOURCE_TYPE); 668 } 669 } 670 671 /* Optionally return the resource table index */ 672 673 if (return_index) { 674 *return_index = resource_index; 675 } 676 677 return (AE_OK); 678 679 invalid_resource: 680 681 if (walk_state) { 682 ACPI_ERROR((AE_INFO, 683 "Invalid/unsupported resource descriptor: Type 0x%2.2X", 684 resource_type)); 685 } 686 return (AE_AML_INVALID_RESOURCE_TYPE); 687 688 bad_resource_length: 689 690 if (walk_state) { 691 ACPI_ERROR((AE_INFO, 692 "Invalid resource descriptor length: Type " 693 "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X", 694 resource_type, resource_length, 695 minimum_resource_length)); 696 } 697 return (AE_AML_BAD_RESOURCE_LENGTH); 698 } 699 700 /******************************************************************************* 701 * 702 * FUNCTION: acpi_ut_get_resource_type 703 * 704 * PARAMETERS: aml - Pointer to the raw AML resource descriptor 705 * 706 * RETURN: The Resource Type with no extraneous bits (except the 707 * Large/Small descriptor bit -- this is left alone) 708 * 709 * DESCRIPTION: Extract the Resource Type/Name from the first byte of 710 * a resource descriptor. 711 * 712 ******************************************************************************/ 713 714 u8 acpi_ut_get_resource_type(void *aml) 715 { 716 ACPI_FUNCTION_ENTRY(); 717 718 /* 719 * Byte 0 contains the descriptor name (Resource Type) 720 * Examine the large/small bit in the resource header 721 */ 722 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) { 723 724 /* Large Resource Type -- bits 6:0 contain the name */ 725 726 return (ACPI_GET8(aml)); 727 } else { 728 /* Small Resource Type -- bits 6:3 contain the name */ 729 730 return ((u8) (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_SMALL_MASK)); 731 } 732 } 733 734 /******************************************************************************* 735 * 736 * FUNCTION: acpi_ut_get_resource_length 737 * 738 * PARAMETERS: aml - Pointer to the raw AML resource descriptor 739 * 740 * RETURN: Byte Length 741 * 742 * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By 743 * definition, this does not include the size of the descriptor 744 * header or the length field itself. 745 * 746 ******************************************************************************/ 747 748 u16 acpi_ut_get_resource_length(void *aml) 749 { 750 acpi_rs_length resource_length; 751 752 ACPI_FUNCTION_ENTRY(); 753 754 /* 755 * Byte 0 contains the descriptor name (Resource Type) 756 * Examine the large/small bit in the resource header 757 */ 758 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) { 759 760 /* Large Resource type -- bytes 1-2 contain the 16-bit length */ 761 762 ACPI_MOVE_16_TO_16(&resource_length, ACPI_ADD_PTR(u8, aml, 1)); 763 764 } else { 765 /* Small Resource type -- bits 2:0 of byte 0 contain the length */ 766 767 resource_length = (u16) (ACPI_GET8(aml) & 768 ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); 769 } 770 771 return (resource_length); 772 } 773 774 /******************************************************************************* 775 * 776 * FUNCTION: acpi_ut_get_resource_header_length 777 * 778 * PARAMETERS: aml - Pointer to the raw AML resource descriptor 779 * 780 * RETURN: Length of the AML header (depends on large/small descriptor) 781 * 782 * DESCRIPTION: Get the length of the header for this resource. 783 * 784 ******************************************************************************/ 785 786 u8 acpi_ut_get_resource_header_length(void *aml) 787 { 788 ACPI_FUNCTION_ENTRY(); 789 790 /* Examine the large/small bit in the resource header */ 791 792 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) { 793 return (sizeof(struct aml_resource_large_header)); 794 } else { 795 return (sizeof(struct aml_resource_small_header)); 796 } 797 } 798 799 /******************************************************************************* 800 * 801 * FUNCTION: acpi_ut_get_descriptor_length 802 * 803 * PARAMETERS: aml - Pointer to the raw AML resource descriptor 804 * 805 * RETURN: Byte length 806 * 807 * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the 808 * length of the descriptor header and the length field itself. 809 * Used to walk descriptor lists. 810 * 811 ******************************************************************************/ 812 813 u32 acpi_ut_get_descriptor_length(void *aml) 814 { 815 ACPI_FUNCTION_ENTRY(); 816 817 /* 818 * Get the Resource Length (does not include header length) and add 819 * the header length (depends on if this is a small or large resource) 820 */ 821 return (acpi_ut_get_resource_length(aml) + 822 acpi_ut_get_resource_header_length(aml)); 823 } 824 825 /******************************************************************************* 826 * 827 * FUNCTION: acpi_ut_get_resource_end_tag 828 * 829 * PARAMETERS: obj_desc - The resource template buffer object 830 * end_tag - Where the pointer to the end_tag is returned 831 * 832 * RETURN: Status, pointer to the end tag 833 * 834 * DESCRIPTION: Find the end_tag resource descriptor in an AML resource template 835 * Note: allows a buffer length of zero. 836 * 837 ******************************************************************************/ 838 839 acpi_status 840 acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc, u8 **end_tag) 841 { 842 acpi_status status; 843 844 ACPI_FUNCTION_TRACE(ut_get_resource_end_tag); 845 846 /* Allow a buffer length of zero */ 847 848 if (!obj_desc->buffer.length) { 849 *end_tag = obj_desc->buffer.pointer; 850 return_ACPI_STATUS(AE_OK); 851 } 852 853 /* Validate the template and get a pointer to the end_tag */ 854 855 status = acpi_ut_walk_aml_resources(NULL, obj_desc->buffer.pointer, 856 obj_desc->buffer.length, NULL, 857 (void **)end_tag); 858 859 return_ACPI_STATUS(status); 860 } 861