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