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: aslopcode - AML opcode generation
4
 *
5
 *****************************************************************************/
6
7
 
8
 *
9
 * 1. Copyright Notice
10
 *
11
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
2216 Serge 12
 * All rights reserved.
1498 serge 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
 
118
#include "aslcompiler.y.h"
119
#include "amlcode.h"
120
121
 
122
        ACPI_MODULE_NAME    ("aslopcodes")
123
124
 
125
 
126
127
 
128
OpcDoAccessAs (
129
    ACPI_PARSE_OBJECT       *Op);
130
131
 
132
OpcDoUnicode (
133
    ACPI_PARSE_OBJECT       *Op);
134
135
 
136
OpcDoEisaId (
137
    ACPI_PARSE_OBJECT       *Op);
138
139
 
140
OpcDoUuId (
141
    ACPI_PARSE_OBJECT       *Op);
142
143
 
144
 
145
 *
146
 * FUNCTION:    OpcAmlOpcodeUpdateWalk
147
 *
148
 * PARAMETERS:  ASL_WALK_CALLBACK
149
 *
150
 * RETURN:      Status
151
 *
152
 * DESCRIPTION: Opcode update walk, ascending callback
153
 *
154
 ******************************************************************************/
155
156
 
157
OpcAmlOpcodeUpdateWalk (
158
    ACPI_PARSE_OBJECT       *Op,
159
    UINT32                  Level,
160
    void                    *Context)
161
{
162
163
 
164
     * Handle the Package() case where the actual opcode cannot be determined
165
     * until the PackageLength operand has been folded and minimized.
166
     * (PackageOp versus VarPackageOp)
167
     *
168
     * This is (as of ACPI 3.0) the only case where the AML opcode can change
169
     * based upon the value of a parameter.
170
     *
171
     * The parser always inserts a VarPackage opcode, which can possibly be
172
     * optimized to a Package opcode.
173
     */
174
    if (Op->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)
175
    {
176
        OpnDoPackage (Op);
177
    }
178
179
 
180
}
181
182
 
183
 
184
 *
185
 * FUNCTION:    OpcAmlOpcodeWalk
186
 *
187
 * PARAMETERS:  ASL_WALK_CALLBACK
188
 *
189
 * RETURN:      Status
190
 *
191
 * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
192
 *              operands.
193
 *
194
 ******************************************************************************/
195
196
 
197
OpcAmlOpcodeWalk (
198
    ACPI_PARSE_OBJECT       *Op,
199
    UINT32                  Level,
200
    void                    *Context)
201
{
202
203
 
204
205
 
206
    OpnGenerateAmlOperands (Op);
207
    return (AE_OK);
208
}
209
210
 
211
 
212
 *
213
 * FUNCTION:    OpcGetIntegerWidth
214
 *
215
 * PARAMETERS:  Op          - DEFINITION BLOCK op
216
 *
217
 * RETURN:      none
218
 *
219
 * DESCRIPTION: Extract integer width from the table revision
220
 *
221
 ******************************************************************************/
222
223
 
224
OpcGetIntegerWidth (
225
    ACPI_PARSE_OBJECT       *Op)
226
{
227
    ACPI_PARSE_OBJECT       *Child;
228
229
 
230
 
231
    {
232
        return;
233
    }
234
235
 
236
    {
237
        AcpiUtSetIntegerWidth (Gbl_RevisionOverride);
238
    }
239
    else
240
    {
241
        Child = Op->Asl.Child;
242
        Child = Child->Asl.Next;
243
        Child = Child->Asl.Next;
244
245
 
246
247
 
248
    }
249
}
250
251
 
252
 
253
 *
254
 * FUNCTION:    OpcSetOptimalIntegerSize
255
 *
256
 * PARAMETERS:  Op        - A parse tree node
257
 *
258
 * RETURN:      Integer width, in bytes.  Also sets the node AML opcode to the
259
 *              optimal integer AML prefix opcode.
260
 *
261
 * DESCRIPTION: Determine the optimal AML encoding of an integer.  All leading
262
 *              zeros can be truncated to squeeze the integer into the
263
 *              minimal number of AML bytes.
264
 *
265
 ******************************************************************************/
266
267
 
268
OpcSetOptimalIntegerSize (
269
    ACPI_PARSE_OBJECT       *Op)
270
{
271
272
 
273
    /*
274
     * TBD: - we don't want to optimize integers in the block header, but the
275
     * code below does not work correctly.
276
     */
277
    if (Op->Asl.Parent &&
278
        Op->Asl.Parent->Asl.Parent &&
279
       (Op->Asl.Parent->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEFINITIONBLOCK))
280
    {
281
        return 0;
282
    }
283
#endif
284
285
 
286
     * Check for the special AML integers first - Zero, One, Ones.
287
     * These are single-byte opcodes that are the smallest possible
288
     * representation of an integer.
289
     *
290
     * This optimization is optional.
291
     */
292
    if (Gbl_IntegerOptimizationFlag)
293
    {
294
        switch (Op->Asl.Value.Integer)
295
        {
296
        case 0:
297
298
 
299
            AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
300
                Op, "Zero");
301
            return 1;
302
303
 
304
305
 
306
            AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
307
                Op, "One");
308
            return 1;
309
310
 
311
312
 
313
314
 
315
            {
316
                Op->Asl.AmlOpcode = AML_ONES_OP;
317
                AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
318
                    Op, "Ones");
319
                return 1;
320
            }
321
            break;
322
323
 
324
325
 
326
327
 
328
            {
329
                Op->Asl.AmlOpcode = AML_ONES_OP;
330
                AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
331
                    Op, "Ones");
332
                return 1;
333
            }
334
            break;
335
336
 
337
            break;
338
        }
339
    }
340
341
 
342
343
 
344
    {
345
        Op->Asl.AmlOpcode = AML_BYTE_OP;
346
        return 1;
347
    }
348
    if (Op->Asl.Value.Integer <= ACPI_UINT16_MAX)
349
    {
350
        Op->Asl.AmlOpcode = AML_WORD_OP;
351
        return 2;
352
    }
353
    if (Op->Asl.Value.Integer <= ACPI_UINT32_MAX)
354
    {
355
        Op->Asl.AmlOpcode = AML_DWORD_OP;
356
        return 4;
357
    }
358
    else
359
    {
360
        if (AcpiGbl_IntegerByteWidth == 4)
361
        {
362
            AslError (ASL_WARNING, ASL_MSG_INTEGER_LENGTH,
363
                Op, NULL);
364
365
 
366
            {
367
                /* Truncate the integer to 32-bit */
368
                Op->Asl.AmlOpcode = AML_DWORD_OP;
369
                return 4;
370
            }
371
        }
372
373
 
374
        return 8;
375
    }
376
}
377
378
 
379
 
380
 *
381
 * FUNCTION:    OpcDoAccessAs
382
 *
383
 * PARAMETERS:  Op        - Parse node
384
 *
385
 * RETURN:      None
386
 *
387
 * DESCRIPTION: Implement the ACCESS_AS ASL keyword.
388
 *
389
 ******************************************************************************/
390
391
 
392
OpcDoAccessAs (
393
    ACPI_PARSE_OBJECT       *Op)
394
{
395
    ACPI_PARSE_OBJECT       *Next;
396
397
 
398
 
399
    Next = Op->Asl.Child;
400
401
 
402
403
 
404
    Next->Asl.ParseOpcode = PARSEOP_RAW_DATA;
405
406
 
407
408
 
409
    if (Next->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
410
    {
411
        Next->Asl.Value.Integer = 0;
412
    }
413
    Next->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
414
    Next->Asl.ParseOpcode = PARSEOP_RAW_DATA;
415
}
416
417
 
418
 
419
 *
420
 * FUNCTION:    OpcDoUnicode
421
 *
422
 * PARAMETERS:  Op        - Parse node
423
 *
424
 * RETURN:      None
425
 *
426
 * DESCRIPTION: Implement the UNICODE ASL "macro".  Convert the input string
427
 *              to a unicode buffer.  There is no Unicode AML opcode.
428
 *
429
 * Note:  The Unicode string is 16 bits per character, no leading signature,
430
 *        with a 16-bit terminating NULL.
431
 *
432
 ******************************************************************************/
433
434
 
435
OpcDoUnicode (
436
    ACPI_PARSE_OBJECT       *Op)
437
{
438
    ACPI_PARSE_OBJECT       *InitializerOp;
439
    UINT32                  Length;
440
    UINT32                  Count;
441
    UINT32                  i;
442
    UINT8                   *AsciiString;
443
    UINT16                  *UnicodeString;
444
    ACPI_PARSE_OBJECT       *BufferLengthOp;
445
446
 
447
 
448
449
 
450
    Op->Asl.ParseOpcode = PARSEOP_BUFFER;
451
    UtSetParseOpName (Op);
452
453
 
454
455
 
456
    InitializerOp = BufferLengthOp->Asl.Next;
457
458
 
459
460
 
461
462
 
463
    Length = Count * sizeof (UINT16);
464
    UnicodeString = UtLocalCalloc (Length);
465
466
 
467
468
 
469
    {
470
        UnicodeString[i] = (UINT16) AsciiString[i];
471
    }
472
473
 
474
     * Just set the buffer size node to be the buffer length, regardless
475
     * of whether it was previously an integer or a default_arg placeholder
476
     */
477
    BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
478
    BufferLengthOp->Asl.AmlOpcode     = AML_DWORD_OP;
479
    BufferLengthOp->Asl.Value.Integer = Length;
480
    UtSetParseOpName (BufferLengthOp);
481
482
 
483
484
 
485
486
 
487
    InitializerOp->Asl.AmlOpcode      = AML_RAW_DATA_BUFFER;
488
    InitializerOp->Asl.AmlLength      = Length;
489
    InitializerOp->Asl.ParseOpcode    = PARSEOP_RAW_DATA;
490
    InitializerOp->Asl.Child          = NULL;
491
    UtSetParseOpName (InitializerOp);
492
}
493
494
 
495
 
496
 *
497
 * FUNCTION:    OpcDoEisaId
498
 *
499
 * PARAMETERS:  Op        - Parse node
500
 *
501
 * RETURN:      None
502
 *
503
 * DESCRIPTION: Convert a string EISA ID to numeric representation.  See the
504
 *              Pnp BIOS Specification for details.  Here is an excerpt:
505
 *
506
 *              A seven character ASCII representation of the product
507
 *              identifier compressed into a 32-bit identifier.  The seven
508
 *              character ID consists of a three character manufacturer code,
509
 *              a three character hexadecimal product identifier, and a one
510
 *              character hexadecimal revision number.  The manufacturer code
511
 *              is a 3 uppercase character code that is compressed into 3 5-bit
512
 *              values as follows:
513
 *                  1) Find hex ASCII value for each letter
514
 *                  2) Subtract 40h from each ASCII value
515
 *                  3) Retain 5 least signficant bits for each letter by
516
 *                     discarding upper 3 bits because they are always 0.
517
 *                  4) Compressed code = concatenate 0 and the 3 5-bit values
518
 *
519
 *              The format of the compressed product identifier is as follows:
520
 *              Byte 0: Bit 7       - Reserved (0)
521
 *                      Bits 6-2:   - 1st character of compressed mfg code
522
 *                      Bits 1-0    - Upper 2 bits of 2nd character of mfg code
523
 *              Byte 1: Bits 7-5    - Lower 3 bits of 2nd character of mfg code
524
 *                      Bits 4-0    - 3rd character of mfg code
525
 *              Byte 2: Bits 7-4    - 1st hex digit of product number
526
 *                      Bits 3-0    - 2nd hex digit of product number
527
 *              Byte 3: Bits 7-4    - 3st hex digit of product number
528
 *                      Bits 3-0    - Hex digit of the revision number
529
 *
530
 ******************************************************************************/
531
532
 
533
OpcDoEisaId (
534
    ACPI_PARSE_OBJECT       *Op)
535
{
536
    UINT32                  EisaId = 0;
537
    UINT32                  BigEndianId;
538
    char                    *InString;
539
    ACPI_STATUS             Status = AE_OK;
540
    UINT32                  i;
541
542
 
543
 
544
545
 
546
     * The EISAID string must be exactly 7 characters and of the form
547
     * "UUUXXXX" -- 3 uppercase letters and 4 hex digits (e.g., "PNP0001")
548
     */
549
    if (ACPI_STRLEN (InString) != 7)
550
    {
551
        Status = AE_BAD_PARAMETER;
552
    }
553
    else
554
    {
555
        /* Check all 7 characters for correct format */
556
557
 
558
        {
559
            /* First 3 characters must be uppercase letters */
560
561
 
562
            {
563
                if (!isupper ((int) InString[i]))
564
                {
565
                    Status = AE_BAD_PARAMETER;
566
                }
567
            }
568
569
 
570
571
 
572
            {
573
                Status = AE_BAD_PARAMETER;
574
            }
575
        }
576
    }
577
578
 
579
    {
580
        AslError (ASL_ERROR, ASL_MSG_INVALID_EISAID, Op, Op->Asl.Value.String);
581
    }
582
    else
583
    {
584
        /* Create ID big-endian first (bits are contiguous) */
585
586
 
587
            (UINT32) ((UINT8) (InString[0] - 0x40)) << 26 |
2216 Serge 588
            (UINT32) ((UINT8) (InString[1] - 0x40)) << 21 |
589
            (UINT32) ((UINT8) (InString[2] - 0x40)) << 16 |
590
1498 serge 591
 
592
            (UtHexCharToValue (InString[4])) << 8  |
593
            (UtHexCharToValue (InString[5])) << 4  |
594
             UtHexCharToValue (InString[6]);
595
596
 
597
598
 
599
    }
600
601
 
602
     * Morph the Op into an integer, regardless of whether there
603
     * was an error in the EISAID string
604
     */
605
    Op->Asl.Value.Integer = EisaId;
606
607
 
608
    Op->Asl.ParseOpcode = PARSEOP_INTEGER;
609
    (void) OpcSetOptimalIntegerSize (Op);
610
611
 
612
613
 
614
}
615
616
 
617
 
618
 *
619
 * FUNCTION:    OpcDoUiId
620
 *
621
 * PARAMETERS:  Op        - Parse node
622
 *
623
 * RETURN:      None
624
 *
625
 * DESCRIPTION: Convert UUID string to 16-byte buffer
626
 *
627
 ******************************************************************************/
628
629
 
630
OpcDoUuId (
631
    ACPI_PARSE_OBJECT       *Op)
632
{
633
    char                    *InString;
634
    char                    *Buffer;
635
    ACPI_STATUS             Status = AE_OK;
636
    ACPI_PARSE_OBJECT       *NewOp;
637
638
 
639
 
640
    Buffer = UtLocalCalloc (16);
641
642
 
2216 Serge 643
    if (ACPI_FAILURE (Status))
1498 serge 644
    {
645
        AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String);
646
    }
647
    else
2216 Serge 648
    {
1498 serge 649
        (void) AuConvertStringToUuid (InString, Buffer);
2216 Serge 650
    }
1498 serge 651
652
 
653
654
 
655
    Op->Common.AmlOpcode = AML_BUFFER_OP;
656
657
 
658
659
 
660
    UtSetParseOpName (Op);
661
662
 
663
664
 
665
666
 
667
    NewOp->Asl.Value.Integer = 16;
668
    NewOp->Asl.Parent        = Op;
669
670
 
671
    Op = NewOp;
672
673
 
674
675
 
676
    NewOp->Asl.AmlOpcode     = AML_RAW_DATA_BUFFER;
677
    NewOp->Asl.AmlLength     = 16;
678
    NewOp->Asl.Value.String  = (char *) Buffer;
679
    NewOp->Asl.Parent        = Op->Asl.Parent;
680
681
 
682
}
683
684
 
685
 
686
 *
687
 * FUNCTION:    OpcGenerateAmlOpcode
688
 *
689
 * PARAMETERS:  Op        - Parse node
690
 *
691
 * RETURN:      None
692
 *
693
 * DESCRIPTION: Generate the AML opcode associated with the node and its
694
 *              parse (lex/flex) keyword opcode.  Essentially implements
695
 *              a mapping between the parse opcodes and the actual AML opcodes.
696
 *
697
 ******************************************************************************/
698
699
 
700
OpcGenerateAmlOpcode (
701
    ACPI_PARSE_OBJECT       *Op)
702
{
703
704
 
705
706
 
707
 
708
709
 
710
    Op->Asl.AcpiBtype     = AslKeywordMapping[Index].AcpiBtype;
711
    Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags;
712
713
 
714
    {
715
        Op->Asl.Value.Integer = AslKeywordMapping[Index].Value;
716
    }
717
718
 
719
720
 
721
    {
722
    case PARSEOP_INTEGER:
723
        /*
724
         * Set the opcode based on the size of the integer
725
         */
726
        (void) OpcSetOptimalIntegerSize (Op);
727
        break;
728
729
 
730
731
 
732
        break;
733
734
 
735
736
 
737
        break;
738
739
 
740
741
 
742
        break;
743
744
 
745
746
 
747
        break;
748
749
 
750
751
 
752
        break;
753
754
 
755
756
 
757
        Gbl_HasIncludeFiles = TRUE;
758
        break;
759
760
 
761
762
 
763
        Op->Asl.Child->Asl.Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
764
        break;
765
766
 
767
        /* Nothing to do for other opcodes */
768
        break;
769
    }
770
771
 
772
}
773