Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/drivers/acpica/exnames.c need to be fixed.

0001 
0002 /******************************************************************************
0003  *
0004  * Module Name: exnames - interpreter/scanner name load/execute
0005  *
0006  *****************************************************************************/
0007 
0008 /******************************************************************************
0009  *
0010  * 1. Copyright Notice
0011  *
0012  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
0013  * All rights reserved.
0014  *
0015  * 2. License
0016  *
0017  * 2.1. This is your license from Intel Corp. under its intellectual property
0018  * rights.  You may have additional license terms from the party that provided
0019  * you this software, covering your right to use that party's intellectual
0020  * property rights.
0021  *
0022  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0023  * copy of the source code appearing in this file ("Covered Code") an
0024  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0025  * base code distributed originally by Intel ("Original Intel Code") to copy,
0026  * make derivatives, distribute, use and display any portion of the Covered
0027  * Code in any form, with the right to sublicense such rights; and
0028  *
0029  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0030  * license (with the right to sublicense), under only those claims of Intel
0031  * patents that are infringed by the Original Intel Code, to make, use, sell,
0032  * offer to sell, and import the Covered Code and derivative works thereof
0033  * solely to the minimum extent necessary to exercise the above copyright
0034  * license, and in no event shall the patent license extend to any additions
0035  * to or modifications of the Original Intel Code.  No other license or right
0036  * is granted directly or by implication, estoppel or otherwise;
0037  *
0038  * The above copyright and patent license is granted only if the following
0039  * conditions are met:
0040  *
0041  * 3. Conditions
0042  *
0043  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0044  * Redistribution of source code of any substantial portion of the Covered
0045  * Code or modification with rights to further distribute source must include
0046  * the above Copyright Notice, the above License, this list of Conditions,
0047  * and the following Disclaimer and Export Compliance provision.  In addition,
0048  * Licensee must cause all Covered Code to which Licensee contributes to
0049  * contain a file documenting the changes Licensee made to create that Covered
0050  * Code and the date of any change.  Licensee must include in that file the
0051  * documentation of any changes made by any predecessor Licensee.  Licensee
0052  * must include a prominent statement that the modification is derived,
0053  * directly or indirectly, from Original Intel Code.
0054  *
0055  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0056  * Redistribution of source code of any substantial portion of the Covered
0057  * Code or modification without rights to further distribute source must
0058  * include the following Disclaimer and Export Compliance provision in the
0059  * documentation and/or other materials provided with distribution.  In
0060  * addition, Licensee may not authorize further sublicense of source of any
0061  * portion of the Covered Code, and must include terms to the effect that the
0062  * license from Licensee to its licensee is limited to the intellectual
0063  * property embodied in the software Licensee provides to its licensee, and
0064  * not to intellectual property embodied in modifications its licensee may
0065  * make.
0066  *
0067  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0068  * substantial portion of the Covered Code or modification must reproduce the
0069  * above Copyright Notice, and the following Disclaimer and Export Compliance
0070  * provision in the documentation and/or other materials provided with the
0071  * distribution.
0072  *
0073  * 3.4. Intel retains all right, title, and interest in and to the Original
0074  * Intel Code.
0075  *
0076  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0077  * Intel shall be used in advertising or otherwise to promote the sale, use or
0078  * other dealings in products derived from or relating to the Covered Code
0079  * without prior written authorization from Intel.
0080  *
0081  * 4. Disclaimer and Export Compliance
0082  *
0083  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0084  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0085  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
0086  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
0087  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
0088  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0089  * PARTICULAR PURPOSE.
0090  *
0091  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0092  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0093  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0094  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0095  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0096  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
0097  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0098  * LIMITED REMEDY.
0099  *
0100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0101  * software or system incorporating such software without first obtaining any
0102  * required license or other approval from the U. S. Department of Commerce or
0103  * any other agency or department of the United States Government.  In the
0104  * event Licensee exports any such software from the United States or
0105  * re-exports any such software from a foreign destination, Licensee shall
0106  * ensure that the distribution and export/re-export of the software is in
0107  * compliance with all laws, regulations, orders, or other restrictions of the
0108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0109  * any of its subsidiaries will export/re-export any technical data, process,
0110  * software, or service, directly or indirectly, to any country for which the
0111  * United States government or any agency thereof requires an export license,
0112  * other governmental approval, or letter of assurance, without first obtaining
0113  * such license, approval or letter.
0114  *
0115  *****************************************************************************/
0116 
0117 #define __EXNAMES_C__
0118 
0119 #include "acpi.h"
0120 #include "accommon.h"
0121 #include "acinterp.h"
0122 #include "amlcode.h"
0123 
0124 #define _COMPONENT          ACPI_EXECUTER
0125         ACPI_MODULE_NAME    ("exnames")
0126 
0127 /* Local prototypes */
0128 
0129 static char *
0130 AcpiExAllocateNameString (
0131     UINT32                  PrefixCount,
0132     UINT32                  NumNameSegs);
0133 
0134 static ACPI_STATUS
0135 AcpiExNameSegment (
0136     UINT8                   **InAmlAddress,
0137     char                    *NameString);
0138 
0139 
0140 /*******************************************************************************
0141  *
0142  * FUNCTION:    AcpiExAllocateNameString
0143  *
0144  * PARAMETERS:  PrefixCount         - Count of parent levels. Special cases:
0145  *                                    (-1)==root,  0==none
0146  *              NumNameSegs         - count of 4-character name segments
0147  *
0148  * RETURN:      A pointer to the allocated string segment.  This segment must
0149  *              be deleted by the caller.
0150  *
0151  * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
0152  *              string is long enough, and set up prefix if any.
0153  *
0154  ******************************************************************************/
0155 
0156 static char *
0157 AcpiExAllocateNameString (
0158     UINT32                  PrefixCount,
0159     UINT32                  NumNameSegs)
0160 {
0161     char                    *TempPtr;
0162     char                    *NameString;
0163     UINT32                   SizeNeeded;
0164 
0165     ACPI_FUNCTION_TRACE (ExAllocateNameString);
0166 
0167 
0168     /*
0169      * Allow room for all \ and ^ prefixes, all segments and a MultiNamePrefix.
0170      * Also, one byte for the null terminator.
0171      * This may actually be somewhat longer than needed.
0172      */
0173     if (PrefixCount == ACPI_UINT32_MAX)
0174     {
0175         /* Special case for root */
0176 
0177         SizeNeeded = 1 + (ACPI_NAME_SIZE * NumNameSegs) + 2 + 1;
0178     }
0179     else
0180     {
0181         SizeNeeded = PrefixCount + (ACPI_NAME_SIZE * NumNameSegs) + 2 + 1;
0182     }
0183 
0184     /*
0185      * Allocate a buffer for the name.
0186      * This buffer must be deleted by the caller!
0187      */
0188     NameString = ACPI_ALLOCATE (SizeNeeded);
0189     if (!NameString)
0190     {
0191         ACPI_ERROR ((AE_INFO,
0192             "Could not allocate size %d", SizeNeeded));
0193         return_PTR (NULL);
0194     }
0195 
0196     TempPtr = NameString;
0197 
0198     /* Set up Root or Parent prefixes if needed */
0199 
0200     if (PrefixCount == ACPI_UINT32_MAX)
0201     {
0202         *TempPtr++ = AML_ROOT_PREFIX;
0203     }
0204     else
0205     {
0206         while (PrefixCount--)
0207         {
0208             *TempPtr++ = AML_PARENT_PREFIX;
0209         }
0210     }
0211 
0212 
0213     /* Set up Dual or Multi prefixes if needed */
0214 
0215     if (NumNameSegs > 2)
0216     {
0217         /* Set up multi prefixes   */
0218 
0219         *TempPtr++ = AML_MULTI_NAME_PREFIX_OP;
0220         *TempPtr++ = (char) NumNameSegs;
0221     }
0222     else if (2 == NumNameSegs)
0223     {
0224         /* Set up dual prefixes */
0225 
0226         *TempPtr++ = AML_DUAL_NAME_PREFIX;
0227     }
0228 
0229     /*
0230      * Terminate string following prefixes. AcpiExNameSegment() will
0231      * append the segment(s)
0232      */
0233     *TempPtr = 0;
0234 
0235     return_PTR (NameString);
0236 }
0237 
0238 /*******************************************************************************
0239  *
0240  * FUNCTION:    AcpiExNameSegment
0241  *
0242  * PARAMETERS:  InAmlAddress    - Pointer to the name in the AML code
0243  *              NameString      - Where to return the name. The name is appended
0244  *                                to any existing string to form a namepath
0245  *
0246  * RETURN:      Status
0247  *
0248  * DESCRIPTION: Extract an ACPI name (4 bytes) from the AML byte stream
0249  *
0250  ******************************************************************************/
0251 
0252 static ACPI_STATUS
0253 AcpiExNameSegment (
0254     UINT8                   **InAmlAddress,
0255     char                    *NameString)
0256 {
0257     char                    *AmlAddress = (void *) *InAmlAddress;
0258     ACPI_STATUS             Status = AE_OK;
0259     UINT32                  Index;
0260     char                    CharBuf[5];
0261 
0262 
0263     ACPI_FUNCTION_TRACE (ExNameSegment);
0264 
0265 
0266     /*
0267      * If first character is a digit, then we know that we aren't looking at a
0268      * valid name segment
0269      */
0270     CharBuf[0] = *AmlAddress;
0271 
0272     if ('0' <= CharBuf[0] && CharBuf[0] <= '9')
0273     {
0274         ACPI_ERROR ((AE_INFO, "Invalid leading digit: %c", CharBuf[0]));
0275         return_ACPI_STATUS (AE_CTRL_PENDING);
0276     }
0277 
0278     ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Bytes from stream:\n"));
0279 
0280     for (Index = 0;
0281         (Index < ACPI_NAME_SIZE) && (AcpiUtValidAcpiChar (*AmlAddress, 0));
0282         Index++)
0283     {
0284         CharBuf[Index] = *AmlAddress++;
0285         ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "%c\n", CharBuf[Index]));
0286     }
0287 
0288 
0289     /* Valid name segment  */
0290 
0291     if (Index == 4)
0292     {
0293         /* Found 4 valid characters */
0294 
0295         CharBuf[4] = '\0';
0296 
0297         if (NameString)
0298         {
0299             ACPI_STRCAT (NameString, CharBuf);
0300             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
0301                 "Appended to - %s\n", NameString));
0302         }
0303         else
0304         {
0305             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
0306                 "No Name string - %s\n", CharBuf));
0307         }
0308     }
0309     else if (Index == 0)
0310     {
0311         /*
0312          * First character was not a valid name character,
0313          * so we are looking at something other than a name.
0314          */
0315         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
0316             "Leading character is not alpha: %02Xh (not a name)\n",
0317             CharBuf[0]));
0318         Status = AE_CTRL_PENDING;
0319     }
0320     else
0321     {
0322         /*
0323          * Segment started with one or more valid characters, but fewer than
0324          * the required 4
0325          */
0326         Status = AE_AML_BAD_NAME;
0327         ACPI_ERROR ((AE_INFO,
0328             "Bad character %02x in name, at %p",
0329             *AmlAddress, AmlAddress));
0330     }
0331 
0332     *InAmlAddress = ACPI_CAST_PTR (UINT8, AmlAddress);
0333     return_ACPI_STATUS (Status);
0334 }
0335 
0336 
0337 /*******************************************************************************
0338  *
0339  * FUNCTION:    AcpiExGetNameString
0340  *
0341  * PARAMETERS:  DataType            - Object type to be associated with this
0342  *                                    name
0343  *              InAmlAddress        - Pointer to the namestring in the AML code
0344  *              OutNameString       - Where the namestring is returned
0345  *              OutNameLength       - Length of the returned string
0346  *
0347  * RETURN:      Status, namestring and length
0348  *
0349  * DESCRIPTION: Extract a full namepath from the AML byte stream,
0350  *              including any prefixes.
0351  *
0352  ******************************************************************************/
0353 
0354 ACPI_STATUS
0355 AcpiExGetNameString (
0356     ACPI_OBJECT_TYPE        DataType,
0357     UINT8                   *InAmlAddress,
0358     char                    **OutNameString,
0359     UINT32                  *OutNameLength)
0360 {
0361     ACPI_STATUS             Status = AE_OK;
0362     UINT8                   *AmlAddress = InAmlAddress;
0363     char                    *NameString = NULL;
0364     UINT32                  NumSegments;
0365     UINT32                  PrefixCount = 0;
0366     BOOLEAN                 HasPrefix = FALSE;
0367 
0368 
0369     ACPI_FUNCTION_TRACE_PTR (ExGetNameString, AmlAddress);
0370 
0371 
0372     if (ACPI_TYPE_LOCAL_REGION_FIELD == DataType   ||
0373         ACPI_TYPE_LOCAL_BANK_FIELD == DataType     ||
0374         ACPI_TYPE_LOCAL_INDEX_FIELD == DataType)
0375     {
0376         /* Disallow prefixes for types associated with FieldUnit names */
0377 
0378         NameString = AcpiExAllocateNameString (0, 1);
0379         if (!NameString)
0380         {
0381             Status = AE_NO_MEMORY;
0382         }
0383         else
0384         {
0385             Status = AcpiExNameSegment (&AmlAddress, NameString);
0386         }
0387     }
0388     else
0389     {
0390         /*
0391          * DataType is not a field name.
0392          * Examine first character of name for root or parent prefix operators
0393          */
0394         switch (*AmlAddress)
0395         {
0396         case AML_ROOT_PREFIX:
0397 
0398             ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "RootPrefix(\\) at %p\n",
0399                 AmlAddress));
0400 
0401             /*
0402              * Remember that we have a RootPrefix --
0403              * see comment in AcpiExAllocateNameString()
0404              */
0405             AmlAddress++;
0406             PrefixCount = ACPI_UINT32_MAX;
0407             HasPrefix = TRUE;
0408             break;
0409 
0410 
0411         case AML_PARENT_PREFIX:
0412 
0413             /* Increment past possibly multiple parent prefixes */
0414 
0415             do
0416             {
0417                 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "ParentPrefix (^) at %p\n",
0418                     AmlAddress));
0419 
0420                 AmlAddress++;
0421                 PrefixCount++;
0422 
0423             } while (*AmlAddress == AML_PARENT_PREFIX);
0424 
0425             HasPrefix = TRUE;
0426             break;
0427 
0428 
0429         default:
0430 
0431             /* Not a prefix character */
0432 
0433             break;
0434         }
0435 
0436         /* Examine first character of name for name segment prefix operator */
0437 
0438         switch (*AmlAddress)
0439         {
0440         case AML_DUAL_NAME_PREFIX:
0441 
0442             ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "DualNamePrefix at %p\n",
0443                 AmlAddress));
0444 
0445             AmlAddress++;
0446             NameString = AcpiExAllocateNameString (PrefixCount, 2);
0447             if (!NameString)
0448             {
0449                 Status = AE_NO_MEMORY;
0450                 break;
0451             }
0452 
0453             /* Indicate that we processed a prefix */
0454 
0455             HasPrefix = TRUE;
0456 
0457             Status = AcpiExNameSegment (&AmlAddress, NameString);
0458             if (ACPI_SUCCESS (Status))
0459             {
0460                 Status = AcpiExNameSegment (&AmlAddress, NameString);
0461             }
0462             break;
0463 
0464 
0465         case AML_MULTI_NAME_PREFIX_OP:
0466 
0467             ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "MultiNamePrefix at %p\n",
0468                 AmlAddress));
0469 
0470             /* Fetch count of segments remaining in name path */
0471 
0472             AmlAddress++;
0473             NumSegments = *AmlAddress;
0474 
0475             NameString = AcpiExAllocateNameString (PrefixCount, NumSegments);
0476             if (!NameString)
0477             {
0478                 Status = AE_NO_MEMORY;
0479                 break;
0480             }
0481 
0482             /* Indicate that we processed a prefix */
0483 
0484             AmlAddress++;
0485             HasPrefix = TRUE;
0486 
0487             while (NumSegments &&
0488                     (Status = AcpiExNameSegment (&AmlAddress, NameString)) ==
0489                         AE_OK)
0490             {
0491                 NumSegments--;
0492             }
0493 
0494             break;
0495 
0496 
0497         case 0:
0498 
0499             /* NullName valid as of 8-12-98 ASL/AML Grammar Update */
0500 
0501             if (PrefixCount == ACPI_UINT32_MAX)
0502             {
0503                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
0504                     "NameSeg is \"\\\" followed by NULL\n"));
0505             }
0506 
0507             /* Consume the NULL byte */
0508 
0509             AmlAddress++;
0510             NameString = AcpiExAllocateNameString (PrefixCount, 0);
0511             if (!NameString)
0512             {
0513                 Status = AE_NO_MEMORY;
0514                 break;
0515             }
0516 
0517             break;
0518 
0519 
0520         default:
0521 
0522             /* Name segment string */
0523 
0524             NameString = AcpiExAllocateNameString (PrefixCount, 1);
0525             if (!NameString)
0526             {
0527                 Status = AE_NO_MEMORY;
0528                 break;
0529             }
0530 
0531             Status = AcpiExNameSegment (&AmlAddress, NameString);
0532             break;
0533         }
0534     }
0535 
0536     if (AE_CTRL_PENDING == Status && HasPrefix)
0537     {
0538         /* Ran out of segments after processing a prefix */
0539 
0540         ACPI_ERROR ((AE_INFO,
0541             "Malformed Name at %p", NameString));
0542         Status = AE_AML_BAD_NAME;
0543     }
0544 
0545     if (ACPI_FAILURE (Status))
0546     {
0547         if (NameString)
0548         {
0549             ACPI_FREE (NameString);
0550         }
0551         return_ACPI_STATUS (Status);
0552     }
0553 
0554     *OutNameString = NameString;
0555     *OutNameLength = (UINT32) (AmlAddress - InAmlAddress);
0556 
0557     return_ACPI_STATUS (Status);
0558 }
0559 
0560