exnames.c revision 84491
1
2/******************************************************************************
3 *
4 * Module Name: exnames - interpreter/scanner name load/execute
5 *              $Revision: 83 $
6 *
7 *****************************************************************************/
8
9/******************************************************************************
10 *
11 * 1. Copyright Notice
12 *
13 * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
14 * All rights reserved.
15 *
16 * 2. License
17 *
18 * 2.1. This is your license from Intel Corp. under its intellectual property
19 * rights.  You may have additional license terms from the party that provided
20 * you this software, covering your right to use that party's intellectual
21 * property rights.
22 *
23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24 * copy of the source code appearing in this file ("Covered Code") an
25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26 * base code distributed originally by Intel ("Original Intel Code") to copy,
27 * make derivatives, distribute, use and display any portion of the Covered
28 * Code in any form, with the right to sublicense such rights; and
29 *
30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31 * license (with the right to sublicense), under only those claims of Intel
32 * patents that are infringed by the Original Intel Code, to make, use, sell,
33 * offer to sell, and import the Covered Code and derivative works thereof
34 * solely to the minimum extent necessary to exercise the above copyright
35 * license, and in no event shall the patent license extend to any additions
36 * to or modifications of the Original Intel Code.  No other license or right
37 * is granted directly or by implication, estoppel or otherwise;
38 *
39 * The above copyright and patent license is granted only if the following
40 * conditions are met:
41 *
42 * 3. Conditions
43 *
44 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45 * Redistribution of source code of any substantial portion of the Covered
46 * Code or modification with rights to further distribute source must include
47 * the above Copyright Notice, the above License, this list of Conditions,
48 * and the following Disclaimer and Export Compliance provision.  In addition,
49 * Licensee must cause all Covered Code to which Licensee contributes to
50 * contain a file documenting the changes Licensee made to create that Covered
51 * Code and the date of any change.  Licensee must include in that file the
52 * documentation of any changes made by any predecessor Licensee.  Licensee
53 * must include a prominent statement that the modification is derived,
54 * directly or indirectly, from Original Intel Code.
55 *
56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57 * Redistribution of source code of any substantial portion of the Covered
58 * Code or modification without rights to further distribute source must
59 * include the following Disclaimer and Export Compliance provision in the
60 * documentation and/or other materials provided with distribution.  In
61 * addition, Licensee may not authorize further sublicense of source of any
62 * portion of the Covered Code, and must include terms to the effect that the
63 * license from Licensee to its licensee is limited to the intellectual
64 * property embodied in the software Licensee provides to its licensee, and
65 * not to intellectual property embodied in modifications its licensee may
66 * make.
67 *
68 * 3.3. Redistribution of Executable. Redistribution in executable form of any
69 * substantial portion of the Covered Code or modification must reproduce the
70 * above Copyright Notice, and the following Disclaimer and Export Compliance
71 * provision in the documentation and/or other materials provided with the
72 * distribution.
73 *
74 * 3.4. Intel retains all right, title, and interest in and to the Original
75 * Intel Code.
76 *
77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78 * Intel shall be used in advertising or otherwise to promote the sale, use or
79 * other dealings in products derived from or relating to the Covered Code
80 * without prior written authorization from Intel.
81 *
82 * 4. Disclaimer and Export Compliance
83 *
84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90 * PARTICULAR PURPOSE.
91 *
92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99 * LIMITED REMEDY.
100 *
101 * 4.3. Licensee shall not export, either directly or indirectly, any of this
102 * software or system incorporating such software without first obtaining any
103 * required license or other approval from the U. S. Department of Commerce or
104 * any other agency or department of the United States Government.  In the
105 * event Licensee exports any such software from the United States or
106 * re-exports any such software from a foreign destination, Licensee shall
107 * ensure that the distribution and export/re-export of the software is in
108 * compliance with all laws, regulations, orders, or other restrictions of the
109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110 * any of its subsidiaries will export/re-export any technical data, process,
111 * software, or service, directly or indirectly, to any country for which the
112 * United States government or any agency thereof requires an export license,
113 * other governmental approval, or letter of assurance, without first obtaining
114 * such license, approval or letter.
115 *
116 *****************************************************************************/
117
118#define __EXNAMES_C__
119
120#include "acpi.h"
121#include "acinterp.h"
122#include "amlcode.h"
123#include "acnamesp.h"
124
125#define _COMPONENT          ACPI_EXECUTER
126        MODULE_NAME         ("exnames")
127
128
129/* AML Package Length encodings */
130
131#define ACPI_AML_PACKAGE_TYPE1   0x40
132#define ACPI_AML_PACKAGE_TYPE2   0x4000
133#define ACPI_AML_PACKAGE_TYPE3   0x400000
134#define ACPI_AML_PACKAGE_TYPE4   0x40000000
135
136
137/*******************************************************************************
138 *
139 * FUNCTION:    AcpiExAllocateNameString
140 *
141 * PARAMETERS:  PrefixCount         - Count of parent levels. Special cases:
142 *                                    (-1) = root,  0 = none
143 *              NumNameSegs         - count of 4-character name segments
144 *
145 * RETURN:      A pointer to the allocated string segment.  This segment must
146 *              be deleted by the caller.
147 *
148 * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
149 *              string is long enough, and set up prefix if any.
150 *
151 ******************************************************************************/
152
153NATIVE_CHAR *
154AcpiExAllocateNameString (
155    UINT32                  PrefixCount,
156    UINT32                  NumNameSegs)
157{
158    NATIVE_CHAR             *TempPtr;
159    NATIVE_CHAR             *NameString;
160    UINT32                   SizeNeeded;
161
162    FUNCTION_TRACE ("ExAllocateNameString");
163
164
165    /*
166     * Allow room for all \ and ^ prefixes, all segments, and a MultiNamePrefix.
167     * Also, one byte for the null terminator.
168     * This may actually be somewhat longer than needed.
169     */
170    if (PrefixCount == (UINT32) -1)
171    {
172        /* Special case for root */
173
174        SizeNeeded = 1 + (ACPI_NAME_SIZE * NumNameSegs) + 2 + 1;
175    }
176    else
177    {
178        SizeNeeded = PrefixCount + (ACPI_NAME_SIZE * NumNameSegs) + 2 + 1;
179    }
180
181    /*
182     * Allocate a buffer for the name.
183     * This buffer must be deleted by the caller!
184     */
185    NameString = ACPI_MEM_ALLOCATE (SizeNeeded);
186    if (!NameString)
187    {
188        REPORT_ERROR (("ExAllocateNameString: Could not allocate size %d\n", SizeNeeded));
189        return_PTR (NULL);
190    }
191
192    TempPtr = NameString;
193
194    /* Set up Root or Parent prefixes if needed */
195
196    if (PrefixCount == (UINT32) -1)
197    {
198        *TempPtr++ = AML_ROOT_PREFIX;
199    }
200
201    else
202    {
203        while (PrefixCount--)
204        {
205            *TempPtr++ = AML_PARENT_PREFIX;
206        }
207    }
208
209
210    /* Set up Dual or Multi prefixes if needed */
211
212    if (NumNameSegs > 2)
213    {
214        /* Set up multi prefixes   */
215
216        *TempPtr++ = AML_MULTI_NAME_PREFIX_OP;
217        *TempPtr++ = (char) NumNameSegs;
218    }
219
220    else if (2 == NumNameSegs)
221    {
222        /* Set up dual prefixes */
223
224        *TempPtr++ = AML_DUAL_NAME_PREFIX;
225    }
226
227    /*
228     * Terminate string following prefixes. AcpiExNameSegment() will
229     * append the segment(s)
230     */
231    *TempPtr = 0;
232
233    return_PTR (NameString);
234}
235
236/*******************************************************************************
237 *
238 * FUNCTION:    AcpiExNameSegment
239 *
240 * PARAMETERS:  InterpreterMode     - Current running mode (load1/Load2/Exec)
241 *
242 * RETURN:      Status
243 *
244 * DESCRIPTION: Execute a name segment (4 bytes)
245 *
246 ******************************************************************************/
247
248ACPI_STATUS
249AcpiExNameSegment (
250    UINT8                   **InAmlAddress,
251    NATIVE_CHAR             *NameString)
252{
253    UINT8                   *AmlAddress = *InAmlAddress;
254    ACPI_STATUS             Status = AE_OK;
255    UINT32                  Index;
256    NATIVE_CHAR             CharBuf[5];
257
258
259    FUNCTION_TRACE ("ExNameSegment");
260
261
262    /*
263     * If first character is a digit, then we know that we aren't looking at a
264     * valid name segment
265     */
266    CharBuf[0] = *AmlAddress;
267
268    if ('0' <= CharBuf[0] && CharBuf[0] <= '9')
269    {
270        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "leading digit: %c\n", CharBuf[0]));
271        return_ACPI_STATUS (AE_CTRL_PENDING);
272    }
273
274    ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Bytes from stream:\n"));
275
276    for (Index = 4;
277        (Index > 0) && (AcpiUtValidAcpiCharacter (*AmlAddress));
278        --Index)
279    {
280        CharBuf[4 - Index] = *AmlAddress++;
281        ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "%c\n", CharBuf[4 - Index]));
282    }
283
284
285    /* Valid name segment  */
286
287    if (0 == Index)
288    {
289        /* Found 4 valid characters */
290
291        CharBuf[4] = '\0';
292
293        if (NameString)
294        {
295            STRCAT (NameString, CharBuf);
296            ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
297                "Appended to - %s \n", NameString));
298        }
299
300        else
301        {
302            ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
303                "No Name string - %s \n", CharBuf));
304        }
305    }
306
307    else if (4 == Index)
308    {
309        /*
310         * First character was not a valid name character,
311         * so we are looking at something other than a name.
312         */
313        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
314            "Leading character is not alpha: %02Xh (not a name)\n",
315            CharBuf[0]));
316        Status = AE_CTRL_PENDING;
317    }
318
319    else
320    {
321        /* Segment started with one or more valid characters, but fewer than 4 */
322
323        Status = AE_AML_BAD_NAME;
324        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad character %02x in name, at %p\n",
325            *AmlAddress, AmlAddress));
326    }
327
328    *InAmlAddress = AmlAddress;
329    return_ACPI_STATUS (Status);
330}
331
332
333/*******************************************************************************
334 *
335 * FUNCTION:    AcpiExGetNameString
336 *
337 * PARAMETERS:  DataType            - Data type to be associated with this name
338 *
339 * RETURN:      Status
340 *
341 * DESCRIPTION: Get a name, including any prefixes.
342 *
343 ******************************************************************************/
344
345
346ACPI_STATUS
347AcpiExGetNameString (
348    ACPI_OBJECT_TYPE8       DataType,
349    UINT8                   *InAmlAddress,
350    NATIVE_CHAR             **OutNameString,
351    UINT32                  *OutNameLength)
352{
353    ACPI_STATUS             Status = AE_OK;
354    UINT8                   *AmlAddress = InAmlAddress;
355    NATIVE_CHAR             *NameString = NULL;
356    UINT32                  NumSegments;
357    UINT32                  PrefixCount = 0;
358    UINT8                   Prefix = 0;
359    BOOLEAN                 HasPrefix = FALSE;
360
361
362    FUNCTION_TRACE_PTR ("ExGetNameString", AmlAddress);
363
364
365    if (INTERNAL_TYPE_REGION_FIELD == DataType   ||
366        INTERNAL_TYPE_BANK_FIELD == DataType     ||
367        INTERNAL_TYPE_INDEX_FIELD == DataType)
368    {
369        /* Disallow prefixes for types associated with FieldUnit names */
370
371        NameString = AcpiExAllocateNameString (0, 1);
372        if (!NameString)
373        {
374            Status = AE_NO_MEMORY;
375        }
376        else
377        {
378            Status = AcpiExNameSegment (&AmlAddress, NameString);
379        }
380    }
381
382    else
383    {
384        /*
385         * DataType is not a field name.
386         * Examine first character of name for root or parent prefix operators
387         */
388        switch (*AmlAddress)
389        {
390
391        case AML_ROOT_PREFIX:
392
393            Prefix = *AmlAddress++;
394            ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "RootPrefix: %x\n", Prefix));
395
396            /*
397             * Remember that we have a RootPrefix --
398             * see comment in AcpiExAllocateNameString()
399             */
400            PrefixCount = (UINT32) -1;
401            HasPrefix = TRUE;
402            break;
403
404
405        case AML_PARENT_PREFIX:
406
407            /* Increment past possibly multiple parent prefixes */
408
409            do
410            {
411                Prefix = *AmlAddress++;
412                ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "ParentPrefix: %x\n", Prefix));
413
414                ++PrefixCount;
415
416            } while (*AmlAddress == AML_PARENT_PREFIX);
417            HasPrefix = TRUE;
418            break;
419
420
421        default:
422
423            break;
424        }
425
426
427        /* Examine first character of name for name segment prefix operator */
428
429        switch (*AmlAddress)
430        {
431
432        case AML_DUAL_NAME_PREFIX:
433
434            Prefix = *AmlAddress++;
435            ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "DualNamePrefix: %x\n", Prefix));
436
437            NameString = AcpiExAllocateNameString (PrefixCount, 2);
438            if (!NameString)
439            {
440                Status = AE_NO_MEMORY;
441                break;
442            }
443
444            /* Indicate that we processed a prefix */
445
446            HasPrefix = TRUE;
447
448            Status = AcpiExNameSegment (&AmlAddress, NameString);
449            if (ACPI_SUCCESS (Status))
450            {
451                Status = AcpiExNameSegment (&AmlAddress, NameString);
452            }
453            break;
454
455
456        case AML_MULTI_NAME_PREFIX_OP:
457
458            Prefix = *AmlAddress++;
459            ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "MultiNamePrefix: %x\n", Prefix));
460
461            /* Fetch count of segments remaining in name path */
462
463            NumSegments = *AmlAddress++;
464
465            NameString = AcpiExAllocateNameString (PrefixCount, NumSegments);
466            if (!NameString)
467            {
468                Status = AE_NO_MEMORY;
469                break;
470            }
471
472            /* Indicate that we processed a prefix */
473
474            HasPrefix = TRUE;
475
476            while (NumSegments &&
477                    (Status = AcpiExNameSegment (&AmlAddress, NameString)) == AE_OK)
478            {
479                --NumSegments;
480            }
481
482            break;
483
484
485        case 0:
486
487            /* NullName valid as of 8-12-98 ASL/AML Grammar Update */
488
489            if (-1 == PrefixCount)
490            {
491                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "NameSeg is \"\\\" followed by NULL\n"));
492            }
493
494            /* Consume the NULL byte */
495
496            AmlAddress++;
497            NameString = AcpiExAllocateNameString (PrefixCount, 0);
498            if (!NameString)
499            {
500                Status = AE_NO_MEMORY;
501                break;
502            }
503
504            break;
505
506
507        default:
508
509            /* Name segment string */
510
511            NameString = AcpiExAllocateNameString (PrefixCount, 1);
512            if (!NameString)
513            {
514                Status = AE_NO_MEMORY;
515                break;
516            }
517
518            Status = AcpiExNameSegment (&AmlAddress, NameString);
519            break;
520
521        }   /* Switch (PeekOp ())    */
522    }
523
524
525    if (AE_CTRL_PENDING == Status && HasPrefix)
526    {
527        /* Ran out of segments after processing a prefix */
528
529        REPORT_ERROR (
530            ("ExDoName: Malformed Name at %p\n", NameString));
531        Status = AE_AML_BAD_NAME;
532    }
533
534
535    *OutNameString = NameString;
536    *OutNameLength = (UINT32) (AmlAddress - InAmlAddress);
537
538    return_ACPI_STATUS (Status);
539}
540
541
542