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 ACPI_AML_SIZE_LARGE(struct aml_resource_pin_group), 358 ACPI_AML_SIZE_LARGE(struct aml_resource_pin_group_function), 359 }; 360 361 const u8 acpi_gbl_resource_aml_serial_bus_sizes[] = { 362 0, 363 ACPI_AML_SIZE_LARGE(struct aml_resource_i2c_serialbus), 364 ACPI_AML_SIZE_LARGE(struct aml_resource_spi_serialbus), 365 ACPI_AML_SIZE_LARGE(struct aml_resource_uart_serialbus), 366 }; 367 368 /* 369 * Resource types, used to validate the resource length field. 370 * The length of fixed-length types must match exactly, variable 371 * lengths must meet the minimum required length, etc. 372 * Zero indicates a reserved (and therefore invalid) resource type. 373 */ 374 static const u8 acpi_gbl_resource_types[] = { 375 /* Small descriptors */ 376 377 0, 378 0, 379 0, 380 0, 381 ACPI_SMALL_VARIABLE_LENGTH, /* 04 IRQ */ 382 ACPI_FIXED_LENGTH, /* 05 DMA */ 383 ACPI_SMALL_VARIABLE_LENGTH, /* 06 start_dependent_functions */ 384 ACPI_FIXED_LENGTH, /* 07 end_dependent_functions */ 385 ACPI_FIXED_LENGTH, /* 08 IO */ 386 ACPI_FIXED_LENGTH, /* 09 fixed_IO */ 387 ACPI_FIXED_LENGTH, /* 0A fixed_DMA */ 388 0, 389 0, 390 0, 391 ACPI_VARIABLE_LENGTH, /* 0E vendor_short */ 392 ACPI_FIXED_LENGTH, /* 0F end_tag */ 393 394 /* Large descriptors */ 395 396 0, 397 ACPI_FIXED_LENGTH, /* 01 Memory24 */ 398 ACPI_FIXED_LENGTH, /* 02 generic_register */ 399 0, 400 ACPI_VARIABLE_LENGTH, /* 04 vendor_long */ 401 ACPI_FIXED_LENGTH, /* 05 Memory32 */ 402 ACPI_FIXED_LENGTH, /* 06 memory32_fixed */ 403 ACPI_VARIABLE_LENGTH, /* 07 Dword* address */ 404 ACPI_VARIABLE_LENGTH, /* 08 Word* address */ 405 ACPI_VARIABLE_LENGTH, /* 09 extended_IRQ */ 406 ACPI_VARIABLE_LENGTH, /* 0A Qword* address */ 407 ACPI_FIXED_LENGTH, /* 0B Extended* address */ 408 ACPI_VARIABLE_LENGTH, /* 0C Gpio* */ 409 ACPI_VARIABLE_LENGTH, /* 0D pin_function */ 410 ACPI_VARIABLE_LENGTH, /* 0E *serial_bus */ 411 ACPI_VARIABLE_LENGTH, /* 0F pin_config */ 412 ACPI_VARIABLE_LENGTH, /* 10 pin_group */ 413 ACPI_VARIABLE_LENGTH, /* 11 pin_group_function */ 414 }; 415 416 /******************************************************************************* 417 * 418 * FUNCTION: acpi_ut_walk_aml_resources 419 * 420 * PARAMETERS: walk_state - Current walk info 421 * PARAMETERS: aml - Pointer to the raw AML resource template 422 * aml_length - Length of the entire template 423 * user_function - Called once for each descriptor found. If 424 * NULL, a pointer to the end_tag is returned 425 * context - Passed to user_function 426 * 427 * RETURN: Status 428 * 429 * DESCRIPTION: Walk a raw AML resource list(buffer). User function called 430 * once for each resource found. 431 * 432 ******************************************************************************/ 433 434 acpi_status 435 acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state, 436 u8 *aml, 437 acpi_size aml_length, 438 acpi_walk_aml_callback user_function, void **context) 439 { 440 acpi_status status; 441 u8 *end_aml; 442 u8 resource_index; 443 u32 length; 444 u32 offset = 0; 445 u8 end_tag[2] = { 0x79, 0x00 }; 446 447 ACPI_FUNCTION_TRACE(ut_walk_aml_resources); 448 449 /* The absolute minimum resource template is one end_tag descriptor */ 450 451 if (aml_length < sizeof(struct aml_resource_end_tag)) { 452 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); 453 } 454 455 /* Point to the end of the resource template buffer */ 456 457 end_aml = aml + aml_length; 458 459 /* Walk the byte list, abort on any invalid descriptor type or length */ 460 461 while (aml < end_aml) { 462 463 /* Validate the Resource Type and Resource Length */ 464 465 status = 466 acpi_ut_validate_resource(walk_state, aml, &resource_index); 467 if (ACPI_FAILURE(status)) { 468 /* 469 * Exit on failure. Cannot continue because the descriptor 470 * length may be bogus also. 471 */ 472 return_ACPI_STATUS(status); 473 } 474 475 /* Get the length of this descriptor */ 476 477 length = acpi_ut_get_descriptor_length(aml); 478 479 /* Invoke the user function */ 480 481 if (user_function) { 482 status = 483 user_function(aml, length, offset, resource_index, 484 context); 485 if (ACPI_FAILURE(status)) { 486 return_ACPI_STATUS(status); 487 } 488 } 489 490 /* An end_tag descriptor terminates this resource template */ 491 492 if (acpi_ut_get_resource_type(aml) == 493 ACPI_RESOURCE_NAME_END_TAG) { 494 /* 495 * There must be at least one more byte in the buffer for 496 * the 2nd byte of the end_tag 497 */ 498 if ((aml + 1) >= end_aml) { 499 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); 500 } 501 502 /* 503 * The end_tag opcode must be followed by a zero byte. 504 * Although this byte is technically defined to be a checksum, 505 * in practice, all ASL compilers set this byte to zero. 506 */ 507 if (*(aml + 1) != 0) { 508 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); 509 } 510 511 /* Return the pointer to the end_tag if requested */ 512 513 if (!user_function) { 514 *context = aml; 515 } 516 517 /* Normal exit */ 518 519 return_ACPI_STATUS(AE_OK); 520 } 521 522 aml += length; 523 offset += length; 524 } 525 526 /* Did not find an end_tag descriptor */ 527 528 if (user_function) { 529 530 /* Insert an end_tag anyway. acpi_rs_get_list_length always leaves room */ 531 532 (void)acpi_ut_validate_resource(walk_state, end_tag, 533 &resource_index); 534 status = 535 user_function(end_tag, 2, offset, resource_index, context); 536 if (ACPI_FAILURE(status)) { 537 return_ACPI_STATUS(status); 538 } 539 } 540 541 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); 542 } 543 544 /******************************************************************************* 545 * 546 * FUNCTION: acpi_ut_validate_resource 547 * 548 * PARAMETERS: walk_state - Current walk info 549 * aml - Pointer to the raw AML resource descriptor 550 * return_index - Where the resource index is returned. NULL 551 * if the index is not required. 552 * 553 * RETURN: Status, and optionally the Index into the global resource tables 554 * 555 * DESCRIPTION: Validate an AML resource descriptor by checking the Resource 556 * Type and Resource Length. Returns an index into the global 557 * resource information/dispatch tables for later use. 558 * 559 ******************************************************************************/ 560 561 acpi_status 562 acpi_ut_validate_resource(struct acpi_walk_state *walk_state, 563 void *aml, u8 *return_index) 564 { 565 union aml_resource *aml_resource; 566 u8 resource_type; 567 u8 resource_index; 568 acpi_rs_length resource_length; 569 acpi_rs_length minimum_resource_length; 570 571 ACPI_FUNCTION_ENTRY(); 572 573 /* 574 * 1) Validate the resource_type field (Byte 0) 575 */ 576 resource_type = ACPI_GET8(aml); 577 578 /* 579 * Byte 0 contains the descriptor name (Resource Type) 580 * Examine the large/small bit in the resource header 581 */ 582 if (resource_type & ACPI_RESOURCE_NAME_LARGE) { 583 584 /* Verify the large resource type (name) against the max */ 585 586 if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { 587 goto invalid_resource; 588 } 589 590 /* 591 * Large Resource Type -- bits 6:0 contain the name 592 * Translate range 0x80-0x8B to index range 0x10-0x1B 593 */ 594 resource_index = (u8) (resource_type - 0x70); 595 } else { 596 /* 597 * Small Resource Type -- bits 6:3 contain the name 598 * Shift range to index range 0x00-0x0F 599 */ 600 resource_index = (u8) 601 ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3); 602 } 603 604 /* 605 * Check validity of the resource type, via acpi_gbl_resource_types. 606 * Zero indicates an invalid resource. 607 */ 608 if (!acpi_gbl_resource_types[resource_index]) { 609 goto invalid_resource; 610 } 611 612 /* 613 * Validate the resource_length field. This ensures that the length 614 * is at least reasonable, and guarantees that it is non-zero. 615 */ 616 resource_length = acpi_ut_get_resource_length(aml); 617 minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index]; 618 619 /* Validate based upon the type of resource - fixed length or variable */ 620 621 switch (acpi_gbl_resource_types[resource_index]) { 622 case ACPI_FIXED_LENGTH: 623 624 /* Fixed length resource, length must match exactly */ 625 626 if (resource_length != minimum_resource_length) { 627 goto bad_resource_length; 628 } 629 break; 630 631 case ACPI_VARIABLE_LENGTH: 632 633 /* Variable length resource, length must be at least the minimum */ 634 635 if (resource_length < minimum_resource_length) { 636 goto bad_resource_length; 637 } 638 break; 639 640 case ACPI_SMALL_VARIABLE_LENGTH: 641 642 /* Small variable length resource, length can be (Min) or (Min-1) */ 643 644 if ((resource_length > minimum_resource_length) || 645 (resource_length < (minimum_resource_length - 1))) { 646 goto bad_resource_length; 647 } 648 break; 649 650 default: 651 652 /* Shouldn't happen (because of validation earlier), but be sure */ 653 654 goto invalid_resource; 655 } 656 657 aml_resource = ACPI_CAST_PTR(union aml_resource, aml); 658 if (resource_type == ACPI_RESOURCE_NAME_SERIAL_BUS) { 659 660 /* Validate the bus_type field */ 661 662 if ((aml_resource->common_serial_bus.type == 0) || 663 (aml_resource->common_serial_bus.type > 664 AML_RESOURCE_MAX_SERIALBUSTYPE)) { 665 if (walk_state) { 666 ACPI_ERROR((AE_INFO, 667 "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X", 668 aml_resource->common_serial_bus. 669 type)); 670 } 671 return (AE_AML_INVALID_RESOURCE_TYPE); 672 } 673 } 674 675 /* Optionally return the resource table index */ 676 677 if (return_index) { 678 *return_index = resource_index; 679 } 680 681 return (AE_OK); 682 683 invalid_resource: 684 685 if (walk_state) { 686 ACPI_ERROR((AE_INFO, 687 "Invalid/unsupported resource descriptor: Type 0x%2.2X", 688 resource_type)); 689 } 690 return (AE_AML_INVALID_RESOURCE_TYPE); 691 692 bad_resource_length: 693 694 if (walk_state) { 695 ACPI_ERROR((AE_INFO, 696 "Invalid resource descriptor length: Type " 697 "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X", 698 resource_type, resource_length, 699 minimum_resource_length)); 700 } 701 return (AE_AML_BAD_RESOURCE_LENGTH); 702 } 703 704 /******************************************************************************* 705 * 706 * FUNCTION: acpi_ut_get_resource_type 707 * 708 * PARAMETERS: aml - Pointer to the raw AML resource descriptor 709 * 710 * RETURN: The Resource Type with no extraneous bits (except the 711 * Large/Small descriptor bit -- this is left alone) 712 * 713 * DESCRIPTION: Extract the Resource Type/Name from the first byte of 714 * a resource descriptor. 715 * 716 ******************************************************************************/ 717 718 u8 acpi_ut_get_resource_type(void *aml) 719 { 720 ACPI_FUNCTION_ENTRY(); 721 722 /* 723 * Byte 0 contains the descriptor name (Resource Type) 724 * Examine the large/small bit in the resource header 725 */ 726 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) { 727 728 /* Large Resource Type -- bits 6:0 contain the name */ 729 730 return (ACPI_GET8(aml)); 731 } else { 732 /* Small Resource Type -- bits 6:3 contain the name */ 733 734 return ((u8) (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_SMALL_MASK)); 735 } 736 } 737 738 /******************************************************************************* 739 * 740 * FUNCTION: acpi_ut_get_resource_length 741 * 742 * PARAMETERS: aml - Pointer to the raw AML resource descriptor 743 * 744 * RETURN: Byte Length 745 * 746 * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By 747 * definition, this does not include the size of the descriptor 748 * header or the length field itself. 749 * 750 ******************************************************************************/ 751 752 u16 acpi_ut_get_resource_length(void *aml) 753 { 754 acpi_rs_length resource_length; 755 756 ACPI_FUNCTION_ENTRY(); 757 758 /* 759 * Byte 0 contains the descriptor name (Resource Type) 760 * Examine the large/small bit in the resource header 761 */ 762 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) { 763 764 /* Large Resource type -- bytes 1-2 contain the 16-bit length */ 765 766 ACPI_MOVE_16_TO_16(&resource_length, ACPI_ADD_PTR(u8, aml, 1)); 767 768 } else { 769 /* Small Resource type -- bits 2:0 of byte 0 contain the length */ 770 771 resource_length = (u16) (ACPI_GET8(aml) & 772 ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); 773 } 774 775 return (resource_length); 776 } 777 778 /******************************************************************************* 779 * 780 * FUNCTION: acpi_ut_get_resource_header_length 781 * 782 * PARAMETERS: aml - Pointer to the raw AML resource descriptor 783 * 784 * RETURN: Length of the AML header (depends on large/small descriptor) 785 * 786 * DESCRIPTION: Get the length of the header for this resource. 787 * 788 ******************************************************************************/ 789 790 u8 acpi_ut_get_resource_header_length(void *aml) 791 { 792 ACPI_FUNCTION_ENTRY(); 793 794 /* Examine the large/small bit in the resource header */ 795 796 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) { 797 return (sizeof(struct aml_resource_large_header)); 798 } else { 799 return (sizeof(struct aml_resource_small_header)); 800 } 801 } 802 803 /******************************************************************************* 804 * 805 * FUNCTION: acpi_ut_get_descriptor_length 806 * 807 * PARAMETERS: aml - Pointer to the raw AML resource descriptor 808 * 809 * RETURN: Byte length 810 * 811 * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the 812 * length of the descriptor header and the length field itself. 813 * Used to walk descriptor lists. 814 * 815 ******************************************************************************/ 816 817 u32 acpi_ut_get_descriptor_length(void *aml) 818 { 819 ACPI_FUNCTION_ENTRY(); 820 821 /* 822 * Get the Resource Length (does not include header length) and add 823 * the header length (depends on if this is a small or large resource) 824 */ 825 return (acpi_ut_get_resource_length(aml) + 826 acpi_ut_get_resource_header_length(aml)); 827 } 828 829 /******************************************************************************* 830 * 831 * FUNCTION: acpi_ut_get_resource_end_tag 832 * 833 * PARAMETERS: obj_desc - The resource template buffer object 834 * end_tag - Where the pointer to the end_tag is returned 835 * 836 * RETURN: Status, pointer to the end tag 837 * 838 * DESCRIPTION: Find the end_tag resource descriptor in an AML resource template 839 * Note: allows a buffer length of zero. 840 * 841 ******************************************************************************/ 842 843 acpi_status 844 acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc, u8 **end_tag) 845 { 846 acpi_status status; 847 848 ACPI_FUNCTION_TRACE(ut_get_resource_end_tag); 849 850 /* Allow a buffer length of zero */ 851 852 if (!obj_desc->buffer.length) { 853 *end_tag = obj_desc->buffer.pointer; 854 return_ACPI_STATUS(AE_OK); 855 } 856 857 /* Validate the template and get a pointer to the end_tag */ 858 859 status = acpi_ut_walk_aml_resources(NULL, obj_desc->buffer.pointer, 860 obj_desc->buffer.length, NULL, 861 (void **)end_tag); 862 863 return_ACPI_STATUS(status); 864 } 865