Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/acpica/compiler/aslopcodes.c
48371 views
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 - 2025, Intel Corp.
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
* Alternatively, you may choose to be licensed under the terms of the
117
* following license:
118
*
119
* Redistribution and use in source and binary forms, with or without
120
* modification, are permitted provided that the following conditions
121
* are met:
122
* 1. Redistributions of source code must retain the above copyright
123
* notice, this list of conditions, and the following disclaimer,
124
* without modification.
125
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
126
* substantially similar to the "NO WARRANTY" disclaimer below
127
* ("Disclaimer") and any redistribution must be conditioned upon
128
* including a substantially similar Disclaimer requirement for further
129
* binary redistribution.
130
* 3. Neither the names of the above-listed copyright holders nor the names
131
* of any contributors may be used to endorse or promote products derived
132
* from this software without specific prior written permission.
133
*
134
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145
*
146
* Alternatively, you may choose to be licensed under the terms of the
147
* GNU General Public License ("GPL") version 2 as published by the Free
148
* Software Foundation.
149
*
150
*****************************************************************************/
151
152
#include <contrib/dev/acpica/compiler/aslcompiler.h>
153
#include "aslcompiler.y.h"
154
#include <contrib/dev/acpica/include/amlcode.h>
155
156
#define _COMPONENT ACPI_COMPILER
157
ACPI_MODULE_NAME ("aslopcodes")
158
159
160
/* Local prototypes */
161
162
static void
163
OpcDoAccessAs (
164
ACPI_PARSE_OBJECT *Op);
165
166
static void
167
OpcDoConnection (
168
ACPI_PARSE_OBJECT *Op);
169
170
static void
171
OpcDoUnicode (
172
ACPI_PARSE_OBJECT *Op);
173
174
static void
175
OpcDoEisaId (
176
ACPI_PARSE_OBJECT *Op);
177
178
static void
179
OpcDoUuId (
180
ACPI_PARSE_OBJECT *Op);
181
182
183
/*******************************************************************************
184
*
185
* FUNCTION: OpcAmlOpcodeUpdateWalk
186
*
187
* PARAMETERS: ASL_WALK_CALLBACK
188
*
189
* RETURN: Status
190
*
191
* DESCRIPTION: Opcode update walk, ascending callback
192
*
193
******************************************************************************/
194
195
ACPI_STATUS
196
OpcAmlOpcodeUpdateWalk (
197
ACPI_PARSE_OBJECT *Op,
198
UINT32 Level,
199
void *Context)
200
{
201
202
/*
203
* Handle the Package() case where the actual opcode cannot be determined
204
* until the PackageLength operand has been folded and minimized.
205
* (PackageOp versus VarPackageOp)
206
*
207
* This is (as of ACPI 3.0) the only case where the AML opcode can change
208
* based upon the value of a parameter.
209
*
210
* The parser always inserts a VarPackage opcode, which can possibly be
211
* optimized to a Package opcode.
212
*/
213
if (Op->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)
214
{
215
OpnDoPackage (Op);
216
}
217
218
return (AE_OK);
219
}
220
221
222
/*******************************************************************************
223
*
224
* FUNCTION: OpcAmlOpcodeWalk
225
*
226
* PARAMETERS: ASL_WALK_CALLBACK
227
*
228
* RETURN: Status
229
*
230
* DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
231
* operands.
232
*
233
******************************************************************************/
234
235
ACPI_STATUS
236
OpcAmlOpcodeWalk (
237
ACPI_PARSE_OBJECT *Op,
238
UINT32 Level,
239
void *Context)
240
{
241
242
AslGbl_TotalParseNodes++;
243
244
OpcGenerateAmlOpcode (Op);
245
OpnGenerateAmlOperands (Op);
246
return (AE_OK);
247
}
248
249
250
/*******************************************************************************
251
*
252
* FUNCTION: OpcGetIntegerWidth
253
*
254
* PARAMETERS: Op - DEFINITION BLOCK op
255
*
256
* RETURN: none
257
*
258
* DESCRIPTION: Extract integer width from the table revision
259
*
260
******************************************************************************/
261
262
void
263
OpcGetIntegerWidth (
264
ACPI_PARSE_OBJECT *Op)
265
{
266
ACPI_PARSE_OBJECT *Child;
267
268
269
if (!Op)
270
{
271
return;
272
}
273
274
if (AslGbl_RevisionOverride)
275
{
276
AcpiUtSetIntegerWidth (AslGbl_RevisionOverride);
277
}
278
else
279
{
280
Child = Op->Asl.Child;
281
Child = Child->Asl.Next;
282
Child = Child->Asl.Next;
283
284
/* Use the revision to set the integer width */
285
286
AcpiUtSetIntegerWidth ((UINT8) Child->Asl.Value.Integer);
287
}
288
}
289
290
291
/*******************************************************************************
292
*
293
* FUNCTION: OpcSetOptimalIntegerSize
294
*
295
* PARAMETERS: Op - A parse tree node
296
*
297
* RETURN: Integer width, in bytes. Also sets the node AML opcode to the
298
* optimal integer AML prefix opcode.
299
*
300
* DESCRIPTION: Determine the optimal AML encoding of an integer. All leading
301
* zeros can be truncated to squeeze the integer into the
302
* minimal number of AML bytes.
303
*
304
******************************************************************************/
305
306
UINT32
307
OpcSetOptimalIntegerSize (
308
ACPI_PARSE_OBJECT *Op)
309
{
310
311
#if 0
312
/*
313
* TBD: - we don't want to optimize integers in the block header, but the
314
* code below does not work correctly.
315
*/
316
if (Op->Asl.Parent &&
317
Op->Asl.Parent->Asl.Parent &&
318
(Op->Asl.Parent->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK))
319
{
320
return (0);
321
}
322
#endif
323
324
/*
325
* Check for the special AML integers first - Zero, One, Ones.
326
* These are single-byte opcodes that are the smallest possible
327
* representation of an integer.
328
*
329
* This optimization is optional.
330
*/
331
if (AslGbl_IntegerOptimizationFlag)
332
{
333
switch (Op->Asl.Value.Integer)
334
{
335
case 0:
336
337
Op->Asl.AmlOpcode = AML_ZERO_OP;
338
AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
339
Op, "Zero");
340
return (1);
341
342
case 1:
343
344
Op->Asl.AmlOpcode = AML_ONE_OP;
345
AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
346
Op, "One");
347
return (1);
348
349
case ACPI_UINT32_MAX:
350
351
/* Check for table integer width (32 or 64) */
352
353
if (AcpiGbl_IntegerByteWidth == 4)
354
{
355
Op->Asl.AmlOpcode = AML_ONES_OP;
356
AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
357
Op, "Ones");
358
return (1);
359
}
360
break;
361
362
case ACPI_UINT64_MAX:
363
364
/* Check for table integer width (32 or 64) */
365
366
if (AcpiGbl_IntegerByteWidth == 8)
367
{
368
Op->Asl.AmlOpcode = AML_ONES_OP;
369
AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
370
Op, "Ones");
371
return (1);
372
}
373
break;
374
375
default:
376
377
break;
378
}
379
}
380
381
/* Find the best fit using the various AML integer prefixes */
382
383
if (Op->Asl.Value.Integer <= ACPI_UINT8_MAX)
384
{
385
Op->Asl.AmlOpcode = AML_BYTE_OP;
386
return (1);
387
}
388
389
if (Op->Asl.Value.Integer <= ACPI_UINT16_MAX)
390
{
391
Op->Asl.AmlOpcode = AML_WORD_OP;
392
return (2);
393
}
394
395
if (Op->Asl.Value.Integer <= ACPI_UINT32_MAX)
396
{
397
Op->Asl.AmlOpcode = AML_DWORD_OP;
398
return (4);
399
}
400
else /* 64-bit integer */
401
{
402
if (AcpiGbl_IntegerByteWidth == 4)
403
{
404
AslError (ASL_WARNING, ASL_MSG_INTEGER_LENGTH,
405
Op, NULL);
406
407
if (!AslGbl_IgnoreErrors)
408
{
409
/* Truncate the integer to 32-bit */
410
411
Op->Asl.Value.Integer &= ACPI_UINT32_MAX;
412
413
/* Now set the optimal integer size */
414
415
return (OpcSetOptimalIntegerSize (Op));
416
}
417
}
418
419
Op->Asl.AmlOpcode = AML_QWORD_OP;
420
return (8);
421
}
422
}
423
424
425
/*******************************************************************************
426
*
427
* FUNCTION: OpcDoAccessAs
428
*
429
* PARAMETERS: Op - Parse node
430
*
431
* RETURN: None
432
*
433
* DESCRIPTION: Implement the ACCESS_AS ASL keyword.
434
*
435
******************************************************************************/
436
437
static void
438
OpcDoAccessAs (
439
ACPI_PARSE_OBJECT *Op)
440
{
441
ACPI_PARSE_OBJECT *TypeOp;
442
ACPI_PARSE_OBJECT *AttribOp;
443
ACPI_PARSE_OBJECT *LengthOp;
444
UINT8 Attribute;
445
446
447
Op->Asl.AmlOpcodeLength = 1;
448
TypeOp = Op->Asl.Child;
449
450
/* First child is the access type */
451
452
TypeOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
453
TypeOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
454
455
/* Second child is the optional access attribute */
456
457
AttribOp = TypeOp->Asl.Next;
458
if (AttribOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
459
{
460
AttribOp->Asl.Value.Integer = 0;
461
}
462
463
AttribOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
464
AttribOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
465
466
/* Only a few AccessAttributes support AccessLength */
467
468
Attribute = (UINT8) AttribOp->Asl.Value.Integer;
469
if ((Attribute != AML_FIELD_ATTRIB_BYTES) &&
470
(Attribute != AML_FIELD_ATTRIB_RAW_BYTES) &&
471
(Attribute != AML_FIELD_ATTRIB_RAW_PROCESS_BYTES))
472
{
473
return;
474
}
475
476
Op->Asl.AmlOpcode = AML_FIELD_EXT_ACCESS_OP;
477
478
/*
479
* Child of Attributes is the AccessLength (required for Multibyte,
480
* RawBytes, RawProcess.)
481
*/
482
LengthOp = AttribOp->Asl.Child;
483
if (!LengthOp)
484
{
485
return;
486
}
487
488
/* TBD: probably can remove */
489
490
if (LengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
491
{
492
LengthOp->Asl.Value.Integer = 16;
493
}
494
495
LengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
496
LengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
497
}
498
499
500
/*******************************************************************************
501
*
502
* FUNCTION: OpcDoConnection
503
*
504
* PARAMETERS: Op - Parse node
505
*
506
* RETURN: None
507
*
508
* DESCRIPTION: Implement the Connection ASL keyword.
509
*
510
******************************************************************************/
511
512
static void
513
OpcDoConnection (
514
ACPI_PARSE_OBJECT *Op)
515
{
516
ASL_RESOURCE_NODE *Rnode;
517
ACPI_PARSE_OBJECT *BufferOp;
518
ACPI_PARSE_OBJECT *BufferLengthOp;
519
ACPI_PARSE_OBJECT *BufferDataOp;
520
ASL_RESOURCE_INFO Info;
521
UINT8 State;
522
523
524
Op->Asl.AmlOpcodeLength = 1;
525
526
if (Op->Asl.Child->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)
527
{
528
return;
529
}
530
531
BufferOp = Op->Asl.Child;
532
BufferLengthOp = BufferOp->Asl.Child;
533
BufferDataOp = BufferLengthOp->Asl.Next;
534
535
Info.DescriptorTypeOp = BufferDataOp->Asl.Next;
536
Info.CurrentByteOffset = 0;
537
State = ACPI_RSTATE_NORMAL;
538
Rnode = RsDoOneResourceDescriptor (&Info, &State);
539
if (!Rnode)
540
{
541
return; /* error */
542
}
543
544
/*
545
* Transform the nodes into the following
546
*
547
* Op -> AML_BUFFER_OP
548
* First Child -> BufferLength
549
* Second Child -> Descriptor Buffer (raw byte data)
550
*/
551
BufferOp->Asl.ParseOpcode = PARSEOP_BUFFER;
552
BufferOp->Asl.AmlOpcode = AML_BUFFER_OP;
553
BufferOp->Asl.CompileFlags = OP_AML_PACKAGE | OP_IS_RESOURCE_DESC;
554
UtSetParseOpName (BufferOp);
555
556
BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
557
BufferLengthOp->Asl.Value.Integer = Rnode->BufferLength;
558
(void) OpcSetOptimalIntegerSize (BufferLengthOp);
559
UtSetParseOpName (BufferLengthOp);
560
561
BufferDataOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
562
BufferDataOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN;
563
BufferDataOp->Asl.AmlOpcodeLength = 0;
564
BufferDataOp->Asl.AmlLength = Rnode->BufferLength;
565
BufferDataOp->Asl.Value.Buffer = (UINT8 *) Rnode;
566
UtSetParseOpName (BufferDataOp);
567
}
568
569
570
/*******************************************************************************
571
*
572
* FUNCTION: OpcDoUnicode
573
*
574
* PARAMETERS: Op - Parse node
575
*
576
* RETURN: None
577
*
578
* DESCRIPTION: Implement the UNICODE ASL "macro". Convert the input string
579
* to a unicode buffer. There is no Unicode AML opcode.
580
*
581
* Note: The Unicode string is 16 bits per character, no leading signature,
582
* with a 16-bit terminating NULL.
583
*
584
******************************************************************************/
585
586
static void
587
OpcDoUnicode (
588
ACPI_PARSE_OBJECT *Op)
589
{
590
ACPI_PARSE_OBJECT *InitializerOp;
591
UINT32 Length;
592
UINT32 Count;
593
UINT32 i;
594
UINT8 *AsciiString;
595
UINT16 *UnicodeString;
596
ACPI_PARSE_OBJECT *BufferLengthOp;
597
598
599
/* Change op into a buffer object */
600
601
Op->Asl.CompileFlags &= ~OP_COMPILE_TIME_CONST;
602
Op->Asl.ParseOpcode = PARSEOP_BUFFER;
603
UtSetParseOpName (Op);
604
605
/* Buffer Length is first, followed by the string */
606
607
BufferLengthOp = Op->Asl.Child;
608
InitializerOp = BufferLengthOp->Asl.Next;
609
610
AsciiString = (UINT8 *) InitializerOp->Asl.Value.String;
611
612
/* Create a new buffer for the Unicode string */
613
614
Count = strlen (InitializerOp->Asl.Value.String) + 1;
615
Length = Count * sizeof (UINT16);
616
UnicodeString = UtLocalCalloc (Length);
617
618
/* Convert to Unicode string (including null terminator) */
619
620
for (i = 0; i < Count; i++)
621
{
622
UnicodeString[i] = (UINT16) AsciiString[i];
623
}
624
625
/*
626
* Just set the buffer size node to be the buffer length, regardless
627
* of whether it was previously an integer or a default_arg placeholder
628
*/
629
BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
630
BufferLengthOp->Asl.AmlOpcode = AML_DWORD_OP;
631
BufferLengthOp->Asl.Value.Integer = Length;
632
UtSetParseOpName (BufferLengthOp);
633
634
(void) OpcSetOptimalIntegerSize (BufferLengthOp);
635
636
/* The Unicode string is a raw data buffer */
637
638
InitializerOp->Asl.Value.Buffer = (UINT8 *) UnicodeString;
639
InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
640
InitializerOp->Asl.AmlLength = Length;
641
InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
642
InitializerOp->Asl.Child = NULL;
643
UtSetParseOpName (InitializerOp);
644
}
645
646
647
/*******************************************************************************
648
*
649
* FUNCTION: OpcDoEisaId
650
*
651
* PARAMETERS: Op - Parse node
652
*
653
* RETURN: None
654
*
655
* DESCRIPTION: Convert a string EISA ID to numeric representation. See the
656
* Pnp BIOS Specification for details. Here is an excerpt:
657
*
658
* A seven character ASCII representation of the product
659
* identifier compressed into a 32-bit identifier. The seven
660
* character ID consists of a three character manufacturer code,
661
* a three character hexadecimal product identifier, and a one
662
* character hexadecimal revision number. The manufacturer code
663
* is a 3 uppercase character code that is compressed into 3 5-bit
664
* values as follows:
665
* 1) Find hex ASCII value for each letter
666
* 2) Subtract 40h from each ASCII value
667
* 3) Retain 5 least significant bits for each letter by
668
* discarding upper 3 bits because they are always 0.
669
* 4) Compressed code = concatenate 0 and the 3 5-bit values
670
*
671
* The format of the compressed product identifier is as follows:
672
* Byte 0: Bit 7 - Reserved (0)
673
* Bits 6-2: - 1st character of compressed mfg code
674
* Bits 1-0 - Upper 2 bits of 2nd character of mfg code
675
* Byte 1: Bits 7-5 - Lower 3 bits of 2nd character of mfg code
676
* Bits 4-0 - 3rd character of mfg code
677
* Byte 2: Bits 7-4 - 1st hex digit of product number
678
* Bits 3-0 - 2nd hex digit of product number
679
* Byte 3: Bits 7-4 - 3rd hex digit of product number
680
* Bits 3-0 - Hex digit of the revision number
681
*
682
******************************************************************************/
683
684
static void
685
OpcDoEisaId (
686
ACPI_PARSE_OBJECT *Op)
687
{
688
UINT32 EisaId = 0;
689
UINT32 BigEndianId;
690
char *InString;
691
ACPI_STATUS Status = AE_OK;
692
UINT32 i;
693
694
695
InString = (char *) Op->Asl.Value.String;
696
697
/*
698
* The EISAID string must be exactly 7 characters and of the form
699
* "UUUXXXX" -- 3 uppercase letters and 4 hex digits (e.g., "PNP0001")
700
*/
701
if (strlen (InString) != 7)
702
{
703
Status = AE_BAD_PARAMETER;
704
}
705
else
706
{
707
/* Check all 7 characters for correct format */
708
709
for (i = 0; i < 7; i++)
710
{
711
/* First 3 characters must be uppercase letters */
712
713
if (i < 3)
714
{
715
if (!isupper ((int) InString[i]))
716
{
717
Status = AE_BAD_PARAMETER;
718
}
719
}
720
721
/* Last 4 characters must be hex digits */
722
723
else if (!isxdigit ((int) InString[i]))
724
{
725
Status = AE_BAD_PARAMETER;
726
}
727
}
728
}
729
730
if (ACPI_FAILURE (Status))
731
{
732
AslError (ASL_ERROR, ASL_MSG_INVALID_EISAID, Op, Op->Asl.Value.String);
733
}
734
else
735
{
736
/* Create ID big-endian first (bits are contiguous) */
737
738
BigEndianId =
739
(UINT32) ((UINT8) (InString[0] - 0x40)) << 26 |
740
(UINT32) ((UINT8) (InString[1] - 0x40)) << 21 |
741
(UINT32) ((UINT8) (InString[2] - 0x40)) << 16 |
742
743
(AcpiUtAsciiCharToHex (InString[3])) << 12 |
744
(AcpiUtAsciiCharToHex (InString[4])) << 8 |
745
(AcpiUtAsciiCharToHex (InString[5])) << 4 |
746
AcpiUtAsciiCharToHex (InString[6]);
747
748
/* Swap to little-endian to get final ID (see function header) */
749
750
EisaId = AcpiUtDwordByteSwap (BigEndianId);
751
}
752
753
/*
754
* Morph the Op into an integer, regardless of whether there
755
* was an error in the EISAID string
756
*/
757
Op->Asl.Value.Integer = EisaId;
758
759
Op->Asl.CompileFlags &= ~OP_COMPILE_TIME_CONST;
760
Op->Asl.ParseOpcode = PARSEOP_INTEGER;
761
(void) OpcSetOptimalIntegerSize (Op);
762
763
/* Op is now an integer */
764
765
UtSetParseOpName (Op);
766
}
767
768
769
/*******************************************************************************
770
*
771
* FUNCTION: OpcDoUuId
772
*
773
* PARAMETERS: Op - Parse node
774
*
775
* RETURN: None
776
*
777
* DESCRIPTION: Convert UUID string to 16-byte buffer
778
*
779
******************************************************************************/
780
781
static void
782
OpcDoUuId (
783
ACPI_PARSE_OBJECT *Op)
784
{
785
char *InString;
786
UINT8 *Buffer;
787
ACPI_STATUS Status = AE_OK;
788
ACPI_PARSE_OBJECT *NewOp;
789
790
791
InString = ACPI_CAST_PTR (char, Op->Asl.Value.String);
792
Buffer = UtLocalCalloc (16);
793
794
Status = AuValidateUuid (InString);
795
if (ACPI_FAILURE (Status))
796
{
797
AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String);
798
}
799
else
800
{
801
/* Convert UUID string to a buffer, check for a known UUID */
802
803
AcpiUtConvertStringToUuid (InString, Buffer);
804
if (!AcpiAhMatchUuid (Buffer))
805
{
806
AslError (ASL_REMARK, ASL_MSG_UUID_NOT_FOUND, Op, NULL);
807
}
808
}
809
810
/* Change Op to a Buffer */
811
812
Op->Asl.ParseOpcode = PARSEOP_BUFFER;
813
Op->Common.AmlOpcode = AML_BUFFER_OP;
814
815
/* Disable further optimization */
816
817
Op->Asl.CompileFlags &= ~OP_COMPILE_TIME_CONST;
818
UtSetParseOpName (Op);
819
820
/* Child node is the buffer length */
821
822
NewOp = TrAllocateOp (PARSEOP_INTEGER);
823
824
NewOp->Asl.AmlOpcode = AML_BYTE_OP;
825
NewOp->Asl.Value.Integer = 16;
826
NewOp->Asl.Parent = Op;
827
828
Op->Asl.Child = NewOp;
829
Op = NewOp;
830
831
/* Peer to the child is the raw buffer data */
832
833
NewOp = TrAllocateOp (PARSEOP_RAW_DATA);
834
NewOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
835
NewOp->Asl.AmlLength = 16;
836
NewOp->Asl.Value.String = ACPI_CAST_PTR (char, Buffer);
837
NewOp->Asl.Parent = Op->Asl.Parent;
838
839
Op->Asl.Next = NewOp;
840
}
841
842
843
/*******************************************************************************
844
*
845
* FUNCTION: OpcGenerateAmlOpcode
846
*
847
* PARAMETERS: Op - Parse node
848
*
849
* RETURN: None
850
*
851
* DESCRIPTION: Generate the AML opcode associated with the node and its
852
* parse (lex/flex) keyword opcode. Essentially implements
853
* a mapping between the parse opcodes and the actual AML opcodes.
854
*
855
******************************************************************************/
856
857
void
858
OpcGenerateAmlOpcode (
859
ACPI_PARSE_OBJECT *Op)
860
{
861
UINT16 Index;
862
863
864
Index = (UINT16) (Op->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
865
866
Op->Asl.AmlOpcode = AslKeywordMapping[Index].AmlOpcode;
867
Op->Asl.AcpiBtype = AslKeywordMapping[Index].AcpiBtype;
868
Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags;
869
870
if (!Op->Asl.Value.Integer)
871
{
872
Op->Asl.Value.Integer = AslKeywordMapping[Index].Value;
873
}
874
875
/* Special handling for some opcodes */
876
877
switch (Op->Asl.ParseOpcode)
878
{
879
case PARSEOP_INTEGER:
880
/*
881
* Set the opcode based on the size of the integer
882
*/
883
(void) OpcSetOptimalIntegerSize (Op);
884
break;
885
886
case PARSEOP_OFFSET:
887
888
Op->Asl.AmlOpcodeLength = 1;
889
break;
890
891
case PARSEOP_ACCESSAS:
892
893
OpcDoAccessAs (Op);
894
break;
895
896
case PARSEOP_CONNECTION:
897
898
OpcDoConnection (Op);
899
break;
900
901
case PARSEOP_EISAID:
902
903
OpcDoEisaId (Op);
904
break;
905
906
case PARSEOP_PRINTF:
907
908
OpcDoPrintf (Op);
909
break;
910
911
case PARSEOP_FPRINTF:
912
913
OpcDoFprintf (Op);
914
break;
915
916
case PARSEOP_TOPLD:
917
918
OpcDoPld (Op);
919
break;
920
921
case PARSEOP_TOUUID:
922
923
OpcDoUuId (Op);
924
break;
925
926
case PARSEOP_UNICODE:
927
928
OpcDoUnicode (Op);
929
break;
930
931
case PARSEOP_INCLUDE:
932
933
AslGbl_HasIncludeFiles = TRUE;
934
break;
935
936
case PARSEOP_TIMER:
937
938
if (AcpiGbl_IntegerBitWidth == 32)
939
{
940
AslError (ASL_REMARK, ASL_MSG_TRUNCATION, Op, NULL);
941
}
942
break;
943
944
default:
945
946
/* Nothing to do for other opcodes */
947
948
break;
949
}
950
951
return;
952
}
953
954