Subversion Repositories Kolibri OS

Rev

Rev 1498 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 1
/*******************************************************************************
2
 *
3
 * Module Name: utmisc - common utility procedures
4
 *
5
 ******************************************************************************/
6
 
7
/******************************************************************************
8
 *
9
 * 1. Copyright Notice
10
 *
2216 Serge 11
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
1498 serge 12
 * All rights reserved.
13
 *
14
 * 2. License
15
 *
16
 * 2.1. This is your license from Intel Corp. under its intellectual property
17
 * rights.  You may have additional license terms from the party that provided
18
 * you this software, covering your right to use that party's intellectual
19
 * property rights.
20
 *
21
 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
 * copy of the source code appearing in this file ("Covered Code") an
23
 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
 * base code distributed originally by Intel ("Original Intel Code") to copy,
25
 * make derivatives, distribute, use and display any portion of the Covered
26
 * Code in any form, with the right to sublicense such rights; and
27
 *
28
 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
 * license (with the right to sublicense), under only those claims of Intel
30
 * patents that are infringed by the Original Intel Code, to make, use, sell,
31
 * offer to sell, and import the Covered Code and derivative works thereof
32
 * solely to the minimum extent necessary to exercise the above copyright
33
 * license, and in no event shall the patent license extend to any additions
34
 * to or modifications of the Original Intel Code.  No other license or right
35
 * is granted directly or by implication, estoppel or otherwise;
36
 *
37
 * The above copyright and patent license is granted only if the following
38
 * conditions are met:
39
 *
40
 * 3. Conditions
41
 *
42
 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
 * Redistribution of source code of any substantial portion of the Covered
44
 * Code or modification with rights to further distribute source must include
45
 * the above Copyright Notice, the above License, this list of Conditions,
46
 * and the following Disclaimer and Export Compliance provision.  In addition,
47
 * Licensee must cause all Covered Code to which Licensee contributes to
48
 * contain a file documenting the changes Licensee made to create that Covered
49
 * Code and the date of any change.  Licensee must include in that file the
50
 * documentation of any changes made by any predecessor Licensee.  Licensee
51
 * must include a prominent statement that the modification is derived,
52
 * directly or indirectly, from Original Intel Code.
53
 *
54
 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
 * Redistribution of source code of any substantial portion of the Covered
56
 * Code or modification without rights to further distribute source must
57
 * include the following Disclaimer and Export Compliance provision in the
58
 * documentation and/or other materials provided with distribution.  In
59
 * addition, Licensee may not authorize further sublicense of source of any
60
 * portion of the Covered Code, and must include terms to the effect that the
61
 * license from Licensee to its licensee is limited to the intellectual
62
 * property embodied in the software Licensee provides to its licensee, and
63
 * not to intellectual property embodied in modifications its licensee may
64
 * make.
65
 *
66
 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67
 * substantial portion of the Covered Code or modification must reproduce the
68
 * above Copyright Notice, and the following Disclaimer and Export Compliance
69
 * provision in the documentation and/or other materials provided with the
70
 * distribution.
71
 *
72
 * 3.4. Intel retains all right, title, and interest in and to the Original
73
 * Intel Code.
74
 *
75
 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
 * Intel shall be used in advertising or otherwise to promote the sale, use or
77
 * other dealings in products derived from or relating to the Covered Code
78
 * without prior written authorization from Intel.
79
 *
80
 * 4. Disclaimer and Export Compliance
81
 *
82
 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85
 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86
 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87
 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
 * PARTICULAR PURPOSE.
89
 *
90
 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96
 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
 * LIMITED REMEDY.
98
 *
99
 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100
 * software or system incorporating such software without first obtaining any
101
 * required license or other approval from the U. S. Department of Commerce or
102
 * any other agency or department of the United States Government.  In the
103
 * event Licensee exports any such software from the United States or
104
 * re-exports any such software from a foreign destination, Licensee shall
105
 * ensure that the distribution and export/re-export of the software is in
106
 * compliance with all laws, regulations, orders, or other restrictions of the
107
 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
 * any of its subsidiaries will export/re-export any technical data, process,
109
 * software, or service, directly or indirectly, to any country for which the
110
 * United States government or any agency thereof requires an export license,
111
 * other governmental approval, or letter of assurance, without first obtaining
112
 * such license, approval or letter.
113
 *
114
 *****************************************************************************/
115
 
116
 
117
#define __UTMISC_C__
118
 
119
#include "acpi.h"
120
#include "accommon.h"
121
#include "acnamesp.h"
122
 
123
 
124
#define _COMPONENT          ACPI_UTILITIES
125
        ACPI_MODULE_NAME    ("utmisc")
126
 
127
 
128
/*******************************************************************************
129
 *
130
 * FUNCTION:    AcpiUtValidateException
131
 *
132
 * PARAMETERS:  Status       - The ACPI_STATUS code to be formatted
133
 *
134
 * RETURN:      A string containing the exception text. NULL if exception is
135
 *              not valid.
136
 *
137
 * DESCRIPTION: This function validates and translates an ACPI exception into
138
 *              an ASCII string.
139
 *
140
 ******************************************************************************/
141
 
142
const char *
143
AcpiUtValidateException (
144
    ACPI_STATUS             Status)
145
{
146
    UINT32                  SubStatus;
147
    const char              *Exception = NULL;
148
 
149
 
150
    ACPI_FUNCTION_ENTRY ();
151
 
152
 
153
    /*
154
     * Status is composed of two parts, a "type" and an actual code
155
     */
156
    SubStatus = (Status & ~AE_CODE_MASK);
157
 
158
    switch (Status & AE_CODE_MASK)
159
    {
160
    case AE_CODE_ENVIRONMENTAL:
161
 
162
        if (SubStatus <= AE_CODE_ENV_MAX)
163
        {
164
            Exception = AcpiGbl_ExceptionNames_Env [SubStatus];
165
        }
166
        break;
167
 
168
    case AE_CODE_PROGRAMMER:
169
 
170
        if (SubStatus <= AE_CODE_PGM_MAX)
171
        {
172
            Exception = AcpiGbl_ExceptionNames_Pgm [SubStatus];
173
        }
174
        break;
175
 
176
    case AE_CODE_ACPI_TABLES:
177
 
178
        if (SubStatus <= AE_CODE_TBL_MAX)
179
        {
180
            Exception = AcpiGbl_ExceptionNames_Tbl [SubStatus];
181
        }
182
        break;
183
 
184
    case AE_CODE_AML:
185
 
186
        if (SubStatus <= AE_CODE_AML_MAX)
187
        {
188
            Exception = AcpiGbl_ExceptionNames_Aml [SubStatus];
189
        }
190
        break;
191
 
192
    case AE_CODE_CONTROL:
193
 
194
        if (SubStatus <= AE_CODE_CTRL_MAX)
195
        {
196
            Exception = AcpiGbl_ExceptionNames_Ctrl [SubStatus];
197
        }
198
        break;
199
 
200
    default:
201
        break;
202
    }
203
 
204
    return (ACPI_CAST_PTR (const char, Exception));
205
}
206
 
207
 
208
/*******************************************************************************
209
 *
210
 * FUNCTION:    AcpiUtIsPciRootBridge
211
 *
212
 * PARAMETERS:  Id              - The HID/CID in string format
213
 *
214
 * RETURN:      TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
215
 *
216
 * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
217
 *
218
 ******************************************************************************/
219
 
220
BOOLEAN
221
AcpiUtIsPciRootBridge (
222
    char                    *Id)
223
{
224
 
225
    /*
226
     * Check if this is a PCI root bridge.
227
     * ACPI 3.0+: check for a PCI Express root also.
228
     */
229
    if (!(ACPI_STRCMP (Id,
230
            PCI_ROOT_HID_STRING)) ||
231
 
232
        !(ACPI_STRCMP (Id,
233
            PCI_EXPRESS_ROOT_HID_STRING)))
234
    {
235
        return (TRUE);
236
    }
237
 
238
    return (FALSE);
239
}
240
 
241
 
242
/*******************************************************************************
243
 *
244
 * FUNCTION:    AcpiUtIsAmlTable
245
 *
246
 * PARAMETERS:  Table               - An ACPI table
247
 *
248
 * RETURN:      TRUE if table contains executable AML; FALSE otherwise
249
 *
250
 * DESCRIPTION: Check ACPI Signature for a table that contains AML code.
251
 *              Currently, these are DSDT,SSDT,PSDT. All other table types are
252
 *              data tables that do not contain AML code.
253
 *
254
 ******************************************************************************/
255
 
256
BOOLEAN
257
AcpiUtIsAmlTable (
258
    ACPI_TABLE_HEADER       *Table)
259
{
260
 
261
    /* These are the only tables that contain executable AML */
262
 
263
    if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) ||
264
        ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) ||
265
        ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT))
266
    {
267
        return (TRUE);
268
    }
269
 
270
    return (FALSE);
271
}
272
 
273
 
274
/*******************************************************************************
275
 *
276
 * FUNCTION:    AcpiUtAllocateOwnerId
277
 *
278
 * PARAMETERS:  OwnerId         - Where the new owner ID is returned
279
 *
280
 * RETURN:      Status
281
 *
282
 * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to
283
 *              track objects created by the table or method, to be deleted
284
 *              when the method exits or the table is unloaded.
285
 *
286
 ******************************************************************************/
287
 
288
ACPI_STATUS
289
AcpiUtAllocateOwnerId (
290
    ACPI_OWNER_ID           *OwnerId)
291
{
292
    UINT32                  i;
293
    UINT32                  j;
294
    UINT32                  k;
295
    ACPI_STATUS             Status;
296
 
297
 
298
    ACPI_FUNCTION_TRACE (UtAllocateOwnerId);
299
 
300
 
301
    /* Guard against multiple allocations of ID to the same location */
302
 
303
    if (*OwnerId)
304
    {
305
        ACPI_ERROR ((AE_INFO, "Owner ID [0x%2.2X] already exists", *OwnerId));
306
        return_ACPI_STATUS (AE_ALREADY_EXISTS);
307
    }
308
 
309
    /* Mutex for the global ID mask */
310
 
311
    Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES);
312
    if (ACPI_FAILURE (Status))
313
    {
314
        return_ACPI_STATUS (Status);
315
    }
316
 
317
    /*
318
     * Find a free owner ID, cycle through all possible IDs on repeated
319
     * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
320
     * to be scanned twice.
321
     */
322
    for (i = 0, j = AcpiGbl_LastOwnerIdIndex;
323
         i < (ACPI_NUM_OWNERID_MASKS + 1);
324
         i++, j++)
325
    {
326
        if (j >= ACPI_NUM_OWNERID_MASKS)
327
        {
328
            j = 0;  /* Wraparound to start of mask array */
329
        }
330
 
331
        for (k = AcpiGbl_NextOwnerIdOffset; k < 32; k++)
332
        {
333
            if (AcpiGbl_OwnerIdMask[j] == ACPI_UINT32_MAX)
334
            {
335
                /* There are no free IDs in this mask */
336
 
337
                break;
338
            }
339
 
340
            if (!(AcpiGbl_OwnerIdMask[j] & (1 << k)))
341
            {
342
                /*
343
                 * Found a free ID. The actual ID is the bit index plus one,
344
                 * making zero an invalid Owner ID. Save this as the last ID
345
                 * allocated and update the global ID mask.
346
                 */
347
                AcpiGbl_OwnerIdMask[j] |= (1 << k);
348
 
349
                AcpiGbl_LastOwnerIdIndex = (UINT8) j;
350
                AcpiGbl_NextOwnerIdOffset = (UINT8) (k + 1);
351
 
352
                /*
353
                 * Construct encoded ID from the index and bit position
354
                 *
355
                 * Note: Last [j].k (bit 255) is never used and is marked
356
                 * permanently allocated (prevents +1 overflow)
357
                 */
358
                *OwnerId = (ACPI_OWNER_ID) ((k + 1) + ACPI_MUL_32 (j));
359
 
360
                ACPI_DEBUG_PRINT ((ACPI_DB_VALUES,
361
                    "Allocated OwnerId: %2.2X\n", (unsigned int) *OwnerId));
362
                goto Exit;
363
            }
364
        }
365
 
366
        AcpiGbl_NextOwnerIdOffset = 0;
367
    }
368
 
369
    /*
370
     * All OwnerIds have been allocated. This typically should
371
     * not happen since the IDs are reused after deallocation. The IDs are
372
     * allocated upon table load (one per table) and method execution, and
373
     * they are released when a table is unloaded or a method completes
374
     * execution.
375
     *
376
     * If this error happens, there may be very deep nesting of invoked control
377
     * methods, or there may be a bug where the IDs are not released.
378
     */
379
    Status = AE_OWNER_ID_LIMIT;
380
    ACPI_ERROR ((AE_INFO,
381
        "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT"));
382
 
383
Exit:
384
    (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES);
385
    return_ACPI_STATUS (Status);
386
}
387
 
388
 
389
/*******************************************************************************
390
 *
391
 * FUNCTION:    AcpiUtReleaseOwnerId
392
 *
393
 * PARAMETERS:  OwnerIdPtr          - Pointer to a previously allocated OwnerID
394
 *
395
 * RETURN:      None. No error is returned because we are either exiting a
396
 *              control method or unloading a table. Either way, we would
397
 *              ignore any error anyway.
398
 *
399
 * DESCRIPTION: Release a table or method owner ID.  Valid IDs are 1 - 255
400
 *
401
 ******************************************************************************/
402
 
403
void
404
AcpiUtReleaseOwnerId (
405
    ACPI_OWNER_ID           *OwnerIdPtr)
406
{
407
    ACPI_OWNER_ID           OwnerId = *OwnerIdPtr;
408
    ACPI_STATUS             Status;
409
    UINT32                  Index;
410
    UINT32                  Bit;
411
 
412
 
413
    ACPI_FUNCTION_TRACE_U32 (UtReleaseOwnerId, OwnerId);
414
 
415
 
416
    /* Always clear the input OwnerId (zero is an invalid ID) */
417
 
418
    *OwnerIdPtr = 0;
419
 
420
    /* Zero is not a valid OwnerID */
421
 
422
    if (OwnerId == 0)
423
    {
424
        ACPI_ERROR ((AE_INFO, "Invalid OwnerId: 0x%2.2X", OwnerId));
425
        return_VOID;
426
    }
427
 
428
    /* Mutex for the global ID mask */
429
 
430
    Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES);
431
    if (ACPI_FAILURE (Status))
432
    {
433
        return_VOID;
434
    }
435
 
436
    /* Normalize the ID to zero */
437
 
438
    OwnerId--;
439
 
440
    /* Decode ID to index/offset pair */
441
 
442
    Index = ACPI_DIV_32 (OwnerId);
443
    Bit = 1 << ACPI_MOD_32 (OwnerId);
444
 
445
    /* Free the owner ID only if it is valid */
446
 
447
    if (AcpiGbl_OwnerIdMask[Index] & Bit)
448
    {
449
        AcpiGbl_OwnerIdMask[Index] ^= Bit;
450
    }
451
    else
452
    {
453
        ACPI_ERROR ((AE_INFO,
454
            "Release of non-allocated OwnerId: 0x%2.2X", OwnerId + 1));
455
    }
456
 
457
    (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES);
458
    return_VOID;
459
}
460
 
461
 
462
/*******************************************************************************
463
 *
464
 * FUNCTION:    AcpiUtStrupr (strupr)
465
 *
466
 * PARAMETERS:  SrcString       - The source string to convert
467
 *
468
 * RETURN:      None
469
 *
470
 * DESCRIPTION: Convert string to uppercase
471
 *
472
 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
473
 *
474
 ******************************************************************************/
475
 
476
void
477
AcpiUtStrupr (
478
    char                    *SrcString)
479
{
480
    char                    *String;
481
 
482
 
483
    ACPI_FUNCTION_ENTRY ();
484
 
485
 
486
    if (!SrcString)
487
    {
488
        return;
489
    }
490
 
491
    /* Walk entire string, uppercasing the letters */
492
 
493
    for (String = SrcString; *String; String++)
494
    {
495
        *String = (char) ACPI_TOUPPER (*String);
496
    }
497
 
498
    return;
499
}
500
 
501
 
2216 Serge 502
#ifdef ACPI_ASL_COMPILER
1498 serge 503
/*******************************************************************************
504
 *
2216 Serge 505
 * FUNCTION:    AcpiUtStrlwr (strlwr)
506
 *
507
 * PARAMETERS:  SrcString       - The source string to convert
508
 *
509
 * RETURN:      None
510
 *
511
 * DESCRIPTION: Convert string to lowercase
512
 *
513
 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
514
 *
515
 ******************************************************************************/
516
 
517
void
518
AcpiUtStrlwr (
519
    char                    *SrcString)
520
{
521
    char                    *String;
522
 
523
 
524
    ACPI_FUNCTION_ENTRY ();
525
 
526
 
527
    if (!SrcString)
528
    {
529
        return;
530
    }
531
 
532
    /* Walk entire string, lowercasing the letters */
533
 
534
    for (String = SrcString; *String; String++)
535
    {
536
        *String = (char) ACPI_TOLOWER (*String);
537
    }
538
 
539
    return;
540
}
541
#endif
542
 
543
 
544
/*******************************************************************************
545
 *
1498 serge 546
 * FUNCTION:    AcpiUtPrintString
547
 *
548
 * PARAMETERS:  String          - Null terminated ASCII string
549
 *              MaxLength       - Maximum output length
550
 *
551
 * RETURN:      None
552
 *
553
 * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
554
 *              sequences.
555
 *
556
 ******************************************************************************/
557
 
558
void
559
AcpiUtPrintString (
560
    char                    *String,
561
    UINT8                   MaxLength)
562
{
563
    UINT32                  i;
564
 
565
 
566
    if (!String)
567
    {
568
        AcpiOsPrintf ("<\"NULL STRING PTR\">");
569
        return;
570
    }
571
 
572
    AcpiOsPrintf ("\"");
573
    for (i = 0; String[i] && (i < MaxLength); i++)
574
    {
575
        /* Escape sequences */
576
 
577
        switch (String[i])
578
        {
579
        case 0x07:
580
            AcpiOsPrintf ("\\a");       /* BELL */
581
            break;
582
 
583
        case 0x08:
584
            AcpiOsPrintf ("\\b");       /* BACKSPACE */
585
            break;
586
 
587
        case 0x0C:
588
            AcpiOsPrintf ("\\f");       /* FORMFEED */
589
            break;
590
 
591
        case 0x0A:
592
            AcpiOsPrintf ("\\n");       /* LINEFEED */
593
            break;
594
 
595
        case 0x0D:
596
            AcpiOsPrintf ("\\r");       /* CARRIAGE RETURN*/
597
            break;
598
 
599
        case 0x09:
600
            AcpiOsPrintf ("\\t");       /* HORIZONTAL TAB */
601
            break;
602
 
603
        case 0x0B:
604
            AcpiOsPrintf ("\\v");       /* VERTICAL TAB */
605
            break;
606
 
607
        case '\'':                      /* Single Quote */
608
        case '\"':                      /* Double Quote */
609
        case '\\':                      /* Backslash */
610
            AcpiOsPrintf ("\\%c", (int) String[i]);
611
            break;
612
 
613
        default:
614
 
615
            /* Check for printable character or hex escape */
616
 
617
            if (ACPI_IS_PRINT (String[i]))
618
            {
619
                /* This is a normal character */
620
 
621
                AcpiOsPrintf ("%c", (int) String[i]);
622
            }
623
            else
624
            {
625
                /* All others will be Hex escapes */
626
 
627
                AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]);
628
            }
629
            break;
630
        }
631
    }
632
    AcpiOsPrintf ("\"");
633
 
634
    if (i == MaxLength && String[i])
635
    {
636
        AcpiOsPrintf ("...");
637
    }
638
}
639
 
640
 
641
/*******************************************************************************
642
 *
643
 * FUNCTION:    AcpiUtDwordByteSwap
644
 *
645
 * PARAMETERS:  Value           - Value to be converted
646
 *
647
 * RETURN:      UINT32 integer with bytes swapped
648
 *
649
 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
650
 *
651
 ******************************************************************************/
652
 
653
UINT32
654
AcpiUtDwordByteSwap (
655
    UINT32                  Value)
656
{
657
    union
658
    {
659
        UINT32              Value;
660
        UINT8               Bytes[4];
661
    } Out;
662
    union
663
    {
664
        UINT32              Value;
665
        UINT8               Bytes[4];
666
    } In;
667
 
668
 
669
    ACPI_FUNCTION_ENTRY ();
670
 
671
 
672
    In.Value = Value;
673
 
674
    Out.Bytes[0] = In.Bytes[3];
675
    Out.Bytes[1] = In.Bytes[2];
676
    Out.Bytes[2] = In.Bytes[1];
677
    Out.Bytes[3] = In.Bytes[0];
678
 
679
    return (Out.Value);
680
}
681
 
682
 
683
/*******************************************************************************
684
 *
685
 * FUNCTION:    AcpiUtSetIntegerWidth
686
 *
687
 * PARAMETERS:  Revision            From DSDT header
688
 *
689
 * RETURN:      None
690
 *
691
 * DESCRIPTION: Set the global integer bit width based upon the revision
692
 *              of the DSDT.  For Revision 1 and 0, Integers are 32 bits.
693
 *              For Revision 2 and above, Integers are 64 bits.  Yes, this
694
 *              makes a difference.
695
 *
696
 ******************************************************************************/
697
 
698
void
699
AcpiUtSetIntegerWidth (
700
    UINT8                   Revision)
701
{
702
 
703
    if (Revision < 2)
704
    {
705
        /* 32-bit case */
706
 
707
        AcpiGbl_IntegerBitWidth    = 32;
708
        AcpiGbl_IntegerNybbleWidth = 8;
709
        AcpiGbl_IntegerByteWidth   = 4;
710
    }
711
    else
712
    {
713
        /* 64-bit case (ACPI 2.0+) */
714
 
715
        AcpiGbl_IntegerBitWidth    = 64;
716
        AcpiGbl_IntegerNybbleWidth = 16;
717
        AcpiGbl_IntegerByteWidth   = 8;
718
    }
719
}
720
 
721
 
722
#ifdef ACPI_DEBUG_OUTPUT
723
/*******************************************************************************
724
 *
725
 * FUNCTION:    AcpiUtDisplayInitPathname
726
 *
727
 * PARAMETERS:  Type                - Object type of the node
728
 *              ObjHandle           - Handle whose pathname will be displayed
729
 *              Path                - Additional path string to be appended.
730
 *                                      (NULL if no extra path)
731
 *
732
 * RETURN:      ACPI_STATUS
733
 *
734
 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
735
 *
736
 ******************************************************************************/
737
 
738
void
739
AcpiUtDisplayInitPathname (
740
    UINT8                   Type,
741
    ACPI_NAMESPACE_NODE     *ObjHandle,
742
    char                    *Path)
743
{
744
    ACPI_STATUS             Status;
745
    ACPI_BUFFER             Buffer;
746
 
747
 
748
    ACPI_FUNCTION_ENTRY ();
749
 
750
 
751
    /* Only print the path if the appropriate debug level is enabled */
752
 
753
    if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES))
754
    {
755
        return;
756
    }
757
 
758
    /* Get the full pathname to the node */
759
 
760
    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
761
    Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
762
    if (ACPI_FAILURE (Status))
763
    {
764
        return;
765
    }
766
 
767
    /* Print what we're doing */
768
 
769
    switch (Type)
770
    {
771
    case ACPI_TYPE_METHOD:
772
        AcpiOsPrintf ("Executing    ");
773
        break;
774
 
775
    default:
776
        AcpiOsPrintf ("Initializing ");
777
        break;
778
    }
779
 
780
    /* Print the object type and pathname */
781
 
782
    AcpiOsPrintf ("%-12s  %s",
783
        AcpiUtGetTypeName (Type), (char *) Buffer.Pointer);
784
 
785
    /* Extra path is used to append names like _STA, _INI, etc. */
786
 
787
    if (Path)
788
    {
789
        AcpiOsPrintf (".%s", Path);
790
    }
791
    AcpiOsPrintf ("\n");
792
 
793
    ACPI_FREE (Buffer.Pointer);
794
}
795
#endif
796
 
797
 
798
/*******************************************************************************
799
 *
800
 * FUNCTION:    AcpiUtValidAcpiChar
801
 *
802
 * PARAMETERS:  Char            - The character to be examined
803
 *              Position        - Byte position (0-3)
804
 *
805
 * RETURN:      TRUE if the character is valid, FALSE otherwise
806
 *
807
 * DESCRIPTION: Check for a valid ACPI character. Must be one of:
808
 *              1) Upper case alpha
809
 *              2) numeric
810
 *              3) underscore
811
 *
812
 *              We allow a '!' as the last character because of the ASF! table
813
 *
814
 ******************************************************************************/
815
 
816
BOOLEAN
817
AcpiUtValidAcpiChar (
818
    char                    Character,
819
    UINT32                  Position)
820
{
821
 
822
    if (!((Character >= 'A' && Character <= 'Z') ||
823
          (Character >= '0' && Character <= '9') ||
824
          (Character == '_')))
825
    {
826
        /* Allow a '!' in the last position */
827
 
828
        if (Character == '!' && Position == 3)
829
        {
830
            return (TRUE);
831
        }
832
 
833
        return (FALSE);
834
    }
835
 
836
    return (TRUE);
837
}
838
 
839
 
840
/*******************************************************************************
841
 *
842
 * FUNCTION:    AcpiUtValidAcpiName
843
 *
844
 * PARAMETERS:  Name            - The name to be examined
845
 *
846
 * RETURN:      TRUE if the name is valid, FALSE otherwise
847
 *
848
 * DESCRIPTION: Check for a valid ACPI name.  Each character must be one of:
849
 *              1) Upper case alpha
850
 *              2) numeric
851
 *              3) underscore
852
 *
853
 ******************************************************************************/
854
 
855
BOOLEAN
856
AcpiUtValidAcpiName (
857
    UINT32                  Name)
858
{
859
    UINT32                  i;
860
 
861
 
862
    ACPI_FUNCTION_ENTRY ();
863
 
864
 
865
    for (i = 0; i < ACPI_NAME_SIZE; i++)
866
    {
867
        if (!AcpiUtValidAcpiChar ((ACPI_CAST_PTR (char, &Name))[i], i))
868
        {
869
            return (FALSE);
870
        }
871
    }
872
 
873
    return (TRUE);
874
}
875
 
876
 
877
/*******************************************************************************
878
 *
879
 * FUNCTION:    AcpiUtRepairName
880
 *
881
 * PARAMETERS:  Name            - The ACPI name to be repaired
882
 *
883
 * RETURN:      Repaired version of the name
884
 *
885
 * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
886
 *              return the new name. NOTE: the Name parameter must reside in
887
 *              read/write memory, cannot be a const.
888
 *
889
 * An ACPI Name must consist of valid ACPI characters. We will repair the name
890
 * if necessary because we don't want to abort because of this, but we want
891
 * all namespace names to be printable. A warning message is appropriate.
892
 *
893
 * This issue came up because there are in fact machines that exhibit
894
 * this problem, and we want to be able to enable ACPI support for them,
895
 * even though there are a few bad names.
896
 *
897
 ******************************************************************************/
898
 
899
void
900
AcpiUtRepairName (
901
    char                    *Name)
902
{
903
    UINT32                  i;
904
    BOOLEAN                 FoundBadChar = FALSE;
905
 
906
 
907
    ACPI_FUNCTION_NAME (UtRepairName);
908
 
909
 
910
    /* Check each character in the name */
911
 
912
    for (i = 0; i < ACPI_NAME_SIZE; i++)
913
    {
914
        if (AcpiUtValidAcpiChar (Name[i], i))
915
        {
916
            continue;
917
        }
918
 
919
        /*
920
         * Replace a bad character with something printable, yet technically
921
         * still invalid. This prevents any collisions with existing "good"
922
         * names in the namespace.
923
         */
924
        Name[i] = '*';
925
        FoundBadChar = TRUE;
926
    }
927
 
928
    if (FoundBadChar)
929
    {
930
        /* Report warning only if in strict mode or debug mode */
931
 
932
        if (!AcpiGbl_EnableInterpreterSlack)
933
        {
934
            ACPI_WARNING ((AE_INFO,
935
                "Found bad character(s) in name, repaired: [%4.4s]\n", Name));
936
        }
937
        else
938
        {
939
            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
940
                "Found bad character(s) in name, repaired: [%4.4s]\n", Name));
941
        }
942
    }
943
}
944
 
945
 
946
/*******************************************************************************
947
 *
948
 * FUNCTION:    AcpiUtStrtoul64
949
 *
950
 * PARAMETERS:  String          - Null terminated string
951
 *              Base            - Radix of the string: 16 or ACPI_ANY_BASE;
952
 *                                ACPI_ANY_BASE means 'in behalf of ToInteger'
953
 *              RetInteger      - Where the converted integer is returned
954
 *
955
 * RETURN:      Status and Converted value
956
 *
957
 * DESCRIPTION: Convert a string into an unsigned value. Performs either a
958
 *              32-bit or 64-bit conversion, depending on the current mode
959
 *              of the interpreter.
960
 *              NOTE: Does not support Octal strings, not needed.
961
 *
962
 ******************************************************************************/
963
 
964
ACPI_STATUS
965
AcpiUtStrtoul64 (
966
    char                    *String,
967
    UINT32                  Base,
968
    UINT64                  *RetInteger)
969
{
970
    UINT32                  ThisDigit = 0;
971
    UINT64                  ReturnValue = 0;
972
    UINT64                  Quotient;
973
    UINT64                  Dividend;
974
    UINT32                  ToIntegerOp = (Base == ACPI_ANY_BASE);
975
    UINT32                  Mode32 = (AcpiGbl_IntegerByteWidth == 4);
976
    UINT8                   ValidDigits = 0;
977
    UINT8                   SignOf0x = 0;
978
    UINT8                   Term = 0;
979
 
980
 
981
    ACPI_FUNCTION_TRACE_STR (UtStroul64, String);
982
 
983
 
984
    switch (Base)
985
    {
986
    case ACPI_ANY_BASE:
987
    case 16:
988
        break;
989
 
990
    default:
991
        /* Invalid Base */
992
        return_ACPI_STATUS (AE_BAD_PARAMETER);
993
    }
994
 
995
    if (!String)
996
    {
997
        goto ErrorExit;
998
    }
999
 
1000
    /* Skip over any white space in the buffer */
1001
 
1002
    while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t'))
1003
    {
1004
        String++;
1005
    }
1006
 
1007
    if (ToIntegerOp)
1008
    {
1009
        /*
1010
         * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
1011
         * We need to determine if it is decimal or hexadecimal.
1012
         */
1013
        if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x'))
1014
        {
1015
            SignOf0x = 1;
1016
            Base = 16;
1017
 
1018
            /* Skip over the leading '0x' */
1019
            String += 2;
1020
        }
1021
        else
1022
        {
1023
            Base = 10;
1024
        }
1025
    }
1026
 
1027
    /* Any string left? Check that '0x' is not followed by white space. */
1028
 
1029
    if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t')
1030
    {
1031
        if (ToIntegerOp)
1032
        {
1033
            goto ErrorExit;
1034
        }
1035
        else
1036
        {
1037
            goto AllDone;
1038
        }
1039
    }
1040
 
1041
    /*
1042
     * Perform a 32-bit or 64-bit conversion, depending upon the current
1043
     * execution mode of the interpreter
1044
     */
1045
    Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
1046
 
1047
    /* Main loop: convert the string to a 32- or 64-bit integer */
1048
 
1049
    while (*String)
1050
    {
1051
        if (ACPI_IS_DIGIT (*String))
1052
        {
1053
            /* Convert ASCII 0-9 to Decimal value */
1054
 
1055
            ThisDigit = ((UINT8) *String) - '0';
1056
        }
1057
        else if (Base == 10)
1058
        {
1059
            /* Digit is out of range; possible in ToInteger case only */
1060
 
1061
            Term = 1;
1062
        }
1063
        else
1064
        {
1065
            ThisDigit = (UINT8) ACPI_TOUPPER (*String);
1066
            if (ACPI_IS_XDIGIT ((char) ThisDigit))
1067
            {
1068
                /* Convert ASCII Hex char to value */
1069
 
1070
                ThisDigit = ThisDigit - 'A' + 10;
1071
            }
1072
            else
1073
            {
1074
                Term = 1;
1075
            }
1076
        }
1077
 
1078
        if (Term)
1079
        {
1080
            if (ToIntegerOp)
1081
            {
1082
                goto ErrorExit;
1083
            }
1084
            else
1085
            {
1086
                break;
1087
            }
1088
        }
1089
        else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
1090
        {
1091
            /* Skip zeros */
1092
            String++;
1093
            continue;
1094
        }
1095
 
1096
        ValidDigits++;
1097
 
1098
        if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32)))
1099
        {
1100
            /*
1101
             * This is ToInteger operation case.
1102
             * No any restrictions for string-to-integer conversion,
1103
             * see ACPI spec.
1104
             */
1105
            goto ErrorExit;
1106
        }
1107
 
1108
        /* Divide the digit into the correct position */
1109
 
1110
        (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit),
1111
                    Base, &Quotient, NULL);
1112
 
1113
        if (ReturnValue > Quotient)
1114
        {
1115
            if (ToIntegerOp)
1116
            {
1117
                goto ErrorExit;
1118
            }
1119
            else
1120
            {
1121
                break;
1122
            }
1123
        }
1124
 
1125
        ReturnValue *= Base;
1126
        ReturnValue += ThisDigit;
1127
        String++;
1128
    }
1129
 
1130
    /* All done, normal exit */
1131
 
1132
AllDone:
1133
 
1134
    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
1135
        ACPI_FORMAT_UINT64 (ReturnValue)));
1136
 
1137
    *RetInteger = ReturnValue;
1138
    return_ACPI_STATUS (AE_OK);
1139
 
1140
 
1141
ErrorExit:
1142
    /* Base was set/validated above */
1143
 
1144
    if (Base == 10)
1145
    {
1146
        return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
1147
    }
1148
    else
1149
    {
1150
        return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
1151
    }
1152
}
1153
 
1154
 
1155
/*******************************************************************************
1156
 *
1157
 * FUNCTION:    AcpiUtCreateUpdateStateAndPush
1158
 *
1159
 * PARAMETERS:  Object          - Object to be added to the new state
1160
 *              Action          - Increment/Decrement
1161
 *              StateList       - List the state will be added to
1162
 *
1163
 * RETURN:      Status
1164
 *
1165
 * DESCRIPTION: Create a new state and push it
1166
 *
1167
 ******************************************************************************/
1168
 
1169
ACPI_STATUS
1170
AcpiUtCreateUpdateStateAndPush (
1171
    ACPI_OPERAND_OBJECT     *Object,
1172
    UINT16                  Action,
1173
    ACPI_GENERIC_STATE      **StateList)
1174
{
1175
    ACPI_GENERIC_STATE       *State;
1176
 
1177
 
1178
    ACPI_FUNCTION_ENTRY ();
1179
 
1180
 
1181
    /* Ignore null objects; these are expected */
1182
 
1183
    if (!Object)
1184
    {
1185
        return (AE_OK);
1186
    }
1187
 
1188
    State = AcpiUtCreateUpdateState (Object, Action);
1189
    if (!State)
1190
    {
1191
        return (AE_NO_MEMORY);
1192
    }
1193
 
1194
    AcpiUtPushGenericState (StateList, State);
1195
    return (AE_OK);
1196
}
1197
 
1198
 
1199
/*******************************************************************************
1200
 *
1201
 * FUNCTION:    AcpiUtWalkPackageTree
1202
 *
1203
 * PARAMETERS:  SourceObject        - The package to walk
1204
 *              TargetObject        - Target object (if package is being copied)
1205
 *              WalkCallback        - Called once for each package element
1206
 *              Context             - Passed to the callback function
1207
 *
1208
 * RETURN:      Status
1209
 *
1210
 * DESCRIPTION: Walk through a package
1211
 *
1212
 ******************************************************************************/
1213
 
1214
ACPI_STATUS
1215
AcpiUtWalkPackageTree (
1216
    ACPI_OPERAND_OBJECT     *SourceObject,
1217
    void                    *TargetObject,
1218
    ACPI_PKG_CALLBACK       WalkCallback,
1219
    void                    *Context)
1220
{
1221
    ACPI_STATUS             Status = AE_OK;
1222
    ACPI_GENERIC_STATE      *StateList = NULL;
1223
    ACPI_GENERIC_STATE      *State;
1224
    UINT32                  ThisIndex;
1225
    ACPI_OPERAND_OBJECT     *ThisSourceObj;
1226
 
1227
 
1228
    ACPI_FUNCTION_TRACE (UtWalkPackageTree);
1229
 
1230
 
1231
    State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0);
1232
    if (!State)
1233
    {
1234
        return_ACPI_STATUS (AE_NO_MEMORY);
1235
    }
1236
 
1237
    while (State)
1238
    {
1239
        /* Get one element of the package */
1240
 
1241
        ThisIndex     = State->Pkg.Index;
1242
        ThisSourceObj = (ACPI_OPERAND_OBJECT *)
1243
                        State->Pkg.SourceObject->Package.Elements[ThisIndex];
1244
 
1245
        /*
1246
         * Check for:
1247
         * 1) An uninitialized package element.  It is completely
1248
         *    legal to declare a package and leave it uninitialized
1249
         * 2) Not an internal object - can be a namespace node instead
1250
         * 3) Any type other than a package.  Packages are handled in else
1251
         *    case below.
1252
         */
1253
        if ((!ThisSourceObj) ||
1254
            (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != ACPI_DESC_TYPE_OPERAND) ||
1255
            (ThisSourceObj->Common.Type != ACPI_TYPE_PACKAGE))
1256
        {
1257
            Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj,
1258
                                    State, Context);
1259
            if (ACPI_FAILURE (Status))
1260
            {
1261
                return_ACPI_STATUS (Status);
1262
            }
1263
 
1264
            State->Pkg.Index++;
1265
            while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count)
1266
            {
1267
                /*
1268
                 * We've handled all of the objects at this level,  This means
1269
                 * that we have just completed a package.  That package may
1270
                 * have contained one or more packages itself.
1271
                 *
1272
                 * Delete this state and pop the previous state (package).
1273
                 */
1274
                AcpiUtDeleteGenericState (State);
1275
                State = AcpiUtPopGenericState (&StateList);
1276
 
1277
                /* Finished when there are no more states */
1278
 
1279
                if (!State)
1280
                {
1281
                    /*
1282
                     * We have handled all of the objects in the top level
1283
                     * package just add the length of the package objects
1284
                     * and exit
1285
                     */
1286
                    return_ACPI_STATUS (AE_OK);
1287
                }
1288
 
1289
                /*
1290
                 * Go back up a level and move the index past the just
1291
                 * completed package object.
1292
                 */
1293
                State->Pkg.Index++;
1294
            }
1295
        }
1296
        else
1297
        {
1298
            /* This is a subobject of type package */
1299
 
1300
            Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj,
1301
                                        State, Context);
1302
            if (ACPI_FAILURE (Status))
1303
            {
1304
                return_ACPI_STATUS (Status);
1305
            }
1306
 
1307
            /*
1308
             * Push the current state and create a new one
1309
             * The callback above returned a new target package object.
1310
             */
1311
            AcpiUtPushGenericState (&StateList, State);
1312
            State = AcpiUtCreatePkgState (ThisSourceObj,
1313
                                            State->Pkg.ThisTargetObj, 0);
1314
            if (!State)
1315
            {
1316
                /* Free any stacked Update State objects */
1317
 
1318
                while (StateList)
1319
                {
1320
                    State = AcpiUtPopGenericState (&StateList);
1321
                    AcpiUtDeleteGenericState (State);
1322
                }
1323
                return_ACPI_STATUS (AE_NO_MEMORY);
1324
            }
1325
        }
1326
    }
1327
 
1328
    /* We should never get here */
1329
 
1330
    return_ACPI_STATUS (AE_AML_INTERNAL);
1331
}
1332