checkdirs() was being passed the wrong mount point, resulting in a panic
[dragonfly.git] / sys / contrib / dev / acpica-unix-20050309 / compiler / aslcodegen.c
1
2 /******************************************************************************
3  *
4  * Module Name: aslcodegen - AML code generation
5  *              $Revision: 52 $
6  *
7  *****************************************************************************/
8
9 /******************************************************************************
10  *
11  * 1. Copyright Notice
12  *
13  * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
14  * All rights reserved.
15  *
16  * 2. License
17  *
18  * 2.1. This is your license from Intel Corp. under its intellectual property
19  * rights.  You may have additional license terms from the party that provided
20  * you this software, covering your right to use that party's intellectual
21  * property rights.
22  *
23  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24  * copy of the source code appearing in this file ("Covered Code") an
25  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26  * base code distributed originally by Intel ("Original Intel Code") to copy,
27  * make derivatives, distribute, use and display any portion of the Covered
28  * Code in any form, with the right to sublicense such rights; and
29  *
30  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31  * license (with the right to sublicense), under only those claims of Intel
32  * patents that are infringed by the Original Intel Code, to make, use, sell,
33  * offer to sell, and import the Covered Code and derivative works thereof
34  * solely to the minimum extent necessary to exercise the above copyright
35  * license, and in no event shall the patent license extend to any additions
36  * to or modifications of the Original Intel Code.  No other license or right
37  * is granted directly or by implication, estoppel or otherwise;
38  *
39  * The above copyright and patent license is granted only if the following
40  * conditions are met:
41  *
42  * 3. Conditions
43  *
44  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45  * Redistribution of source code of any substantial portion of the Covered
46  * Code or modification with rights to further distribute source must include
47  * the above Copyright Notice, the above License, this list of Conditions,
48  * and the following Disclaimer and Export Compliance provision.  In addition,
49  * Licensee must cause all Covered Code to which Licensee contributes to
50  * contain a file documenting the changes Licensee made to create that Covered
51  * Code and the date of any change.  Licensee must include in that file the
52  * documentation of any changes made by any predecessor Licensee.  Licensee
53  * must include a prominent statement that the modification is derived,
54  * directly or indirectly, from Original Intel Code.
55  *
56  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57  * Redistribution of source code of any substantial portion of the Covered
58  * Code or modification without rights to further distribute source must
59  * include the following Disclaimer and Export Compliance provision in the
60  * documentation and/or other materials provided with distribution.  In
61  * addition, Licensee may not authorize further sublicense of source of any
62  * portion of the Covered Code, and must include terms to the effect that the
63  * license from Licensee to its licensee is limited to the intellectual
64  * property embodied in the software Licensee provides to its licensee, and
65  * not to intellectual property embodied in modifications its licensee may
66  * make.
67  *
68  * 3.3. Redistribution of Executable. Redistribution in executable form of any
69  * substantial portion of the Covered Code or modification must reproduce the
70  * above Copyright Notice, and the following Disclaimer and Export Compliance
71  * provision in the documentation and/or other materials provided with the
72  * distribution.
73  *
74  * 3.4. Intel retains all right, title, and interest in and to the Original
75  * Intel Code.
76  *
77  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78  * Intel shall be used in advertising or otherwise to promote the sale, use or
79  * other dealings in products derived from or relating to the Covered Code
80  * without prior written authorization from Intel.
81  *
82  * 4. Disclaimer and Export Compliance
83  *
84  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90  * PARTICULAR PURPOSE.
91  *
92  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99  * LIMITED REMEDY.
100  *
101  * 4.3. Licensee shall not export, either directly or indirectly, any of this
102  * software or system incorporating such software without first obtaining any
103  * required license or other approval from the U. S. Department of Commerce or
104  * any other agency or department of the United States Government.  In the
105  * event Licensee exports any such software from the United States or
106  * re-exports any such software from a foreign destination, Licensee shall
107  * ensure that the distribution and export/re-export of the software is in
108  * compliance with all laws, regulations, orders, or other restrictions of the
109  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110  * any of its subsidiaries will export/re-export any technical data, process,
111  * software, or service, directly or indirectly, to any country for which the
112  * United States government or any agency thereof requires an export license,
113  * other governmental approval, or letter of assurance, without first obtaining
114  * such license, approval or letter.
115  *
116  *****************************************************************************/
117
118
119 #include "aslcompiler.h"
120 #include "aslcompiler.y.h"
121 #include "amlcode.h"
122
123 #define _COMPONENT          ACPI_COMPILER
124         ACPI_MODULE_NAME    ("aslcodegen")
125
126
127 /*******************************************************************************
128  *
129  * FUNCTION:    CgGenerateAmlOutput
130  *
131  * PARAMETERS:  None.
132  *
133  * RETURN:      None
134  *
135  * DESCRIPTION: Generate AML code.  Currently generates the listing file
136  *              simultaneously.
137  *
138  ******************************************************************************/
139
140 void
141 CgGenerateAmlOutput (void)
142 {
143
144     DbgPrint (ASL_DEBUG_OUTPUT, "\nWriting AML\n\n");
145
146     /* Generate the AML output file */
147
148     FlSeekFile (ASL_FILE_SOURCE_OUTPUT, 0);
149     Gbl_SourceLine = 0;
150     Gbl_NextError = Gbl_ErrorLog;
151
152     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, CgAmlWriteWalk, NULL, NULL);
153     CgCloseTable ();
154 }
155
156
157 /*******************************************************************************
158  *
159  * FUNCTION:    CgAmlWriteWalk
160  *
161  * PARAMETERS:  ASL_WALK_CALLBACK
162  *
163  * RETURN:      Status
164  *
165  * DESCRIPTION: Parse tree walk to generate the AML code.
166  *
167  ******************************************************************************/
168
169 ACPI_STATUS
170 CgAmlWriteWalk (
171     ACPI_PARSE_OBJECT       *Op,
172     UINT32                  Level,
173     void                    *Context)
174 {
175
176     /*
177      * Debug output
178      */
179     DbgPrint (ASL_TREE_OUTPUT,
180         "%5.5d [%2d]", Op->Asl.LogicalLineNumber, Level);
181     UtPrintFormattedName (Op->Asl.ParseOpcode, Level);
182
183     if (Op->Asl.ParseOpcode == PARSEOP_NAMESEG    ||
184         Op->Asl.ParseOpcode == PARSEOP_NAMESTRING ||
185         Op->Asl.ParseOpcode == PARSEOP_METHODCALL)
186     {
187         DbgPrint (ASL_TREE_OUTPUT,
188             "%10.32s      ", Op->Asl.ExternalName);
189     }
190     else
191     {
192         DbgPrint (ASL_TREE_OUTPUT, "                ");
193     }
194
195     DbgPrint (ASL_TREE_OUTPUT,
196         "Val-%08X POp-%04X AOp-%04X OpLen-%01X PByts-%01X Len-%04X SubLen-%04X PSubLen-%04X Op-%08X Chld-%08X Paren-%08X Flags-%04X AcTyp-%08X C-%2d L-%d\n",
197                 (UINT32) Op->Asl.Value.Integer,
198                 Op->Asl.ParseOpcode,
199                 Op->Asl.AmlOpcode,
200                 Op->Asl.AmlOpcodeLength,
201                 Op->Asl.AmlPkgLenBytes,
202                 Op->Asl.AmlLength,
203                 Op->Asl.AmlSubtreeLength,
204                 Op->Asl.Parent ? Op->Asl.Parent->Asl.AmlSubtreeLength : 0,
205                 Op,
206                 Op->Asl.Child,
207                 Op->Asl.Parent,
208                 Op->Asl.CompileFlags,
209                 Op->Asl.AcpiBtype,
210                 Op->Asl.Column,
211                 Op->Asl.LineNumber);
212
213     /*
214      * Generate the AML for this node
215      */
216     CgWriteNode (Op);
217     return (AE_OK);
218 }
219
220
221 /*******************************************************************************
222  *
223  * FUNCTION:    CgLocalWriteAmlData
224  *
225  * PARAMETERS:  Buffer          - Buffer to write
226  *              Length          - Size of data in buffer
227  *
228  * RETURN:      None
229  *
230  * DESCRIPTION: Write a buffer of AML data to the AML output file.
231  *
232  ******************************************************************************/
233
234 void
235 CgLocalWriteAmlData (
236     ACPI_PARSE_OBJECT       *Op,
237     void                    *Buffer,
238     UINT32                  Length)
239 {
240
241
242     /* Write the raw data to the AML file */
243
244     FlWriteFile (ASL_FILE_AML_OUTPUT, Buffer, Length);
245
246     /* Update the final AML length for this node (used for listings) */
247
248     if (Op)
249     {
250         Op->Asl.FinalAmlLength += Length;
251     }
252 }
253
254
255 /*******************************************************************************
256  *
257  * FUNCTION:    CgWriteAmlOpcode
258  *
259  * PARAMETERS:  Op            - Parse node with an AML opcode
260  *
261  * RETURN:      None.
262  *
263  * DESCRIPTION: Write the AML opcode corresponding to a parse node.
264  *
265  ******************************************************************************/
266
267 void
268 CgWriteAmlOpcode (
269     ACPI_PARSE_OBJECT           *Op)
270 {
271     union {
272         UINT16                      Opcode;
273         UINT8                       OpcodeBytes[2];
274     } Aml;
275     union {
276         UINT32                      Len;
277         UINT8                       LenBytes[4];
278     } PkgLen;
279
280     UINT8                       PkgLenFirstByte;
281     UINT32                      i;
282
283
284     /* We expect some DEFAULT_ARGs, just ignore them */
285
286     if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
287     {
288         return;
289     }
290
291     switch (Op->Asl.AmlOpcode)
292     {
293     case AML_UNASSIGNED_OPCODE:
294
295         /* These opcodes should not get here */
296
297         printf ("Found a node with an unassigned AML opcode\n");
298         fprintf (stderr, "Found a node with an unassigned AML opcode\n");
299         return;
300
301     case AML_INT_RESERVEDFIELD_OP:
302
303         /* Special opcodes for within a field definition */
304
305         Aml.Opcode = 0x00;
306         break;
307
308     case AML_INT_ACCESSFIELD_OP:
309
310         Aml.Opcode = 0x01;
311         break;
312
313     default:
314         Aml.Opcode = Op->Asl.AmlOpcode;
315         break;
316     }
317
318
319     switch (Aml.Opcode)
320     {
321     case AML_PACKAGE_LENGTH:
322
323         /* Value is the length to be encoded (Used in field definitions) */
324
325         PkgLen.Len = (UINT32) Op->Asl.Value.Integer;
326         break;
327
328     default:
329
330         /* Check for two-byte opcode */
331
332         if (Aml.Opcode > 0x00FF)
333         {
334             /* Write the high byte first */
335
336             CgLocalWriteAmlData (Op, &Aml.OpcodeBytes[1], 1);
337         }
338
339         CgLocalWriteAmlData (Op, &Aml.OpcodeBytes[0], 1);
340
341         /* Subtreelength doesn't include length of package length bytes */
342
343         PkgLen.Len = Op->Asl.AmlSubtreeLength + Op->Asl.AmlPkgLenBytes;
344         break;
345     }
346
347     /* Does this opcode have an associated "PackageLength" field? */
348
349     if (Op->Asl.CompileFlags & NODE_AML_PACKAGE)
350     {
351         if (Op->Asl.AmlPkgLenBytes == 1)
352         {
353             /* Simplest case -- no bytes to follow, just write the count */
354
355             CgLocalWriteAmlData (Op, &PkgLen.LenBytes[0], 1);
356         }
357         else
358         {
359             /*
360              * Encode the "bytes to follow" in the first byte, top two bits.
361              * The low-order nybble of the length is in the bottom 4 bits
362              */
363             PkgLenFirstByte = (UINT8) (((UINT32) (Op->Asl.AmlPkgLenBytes - 1) << 6) |
364                                         (PkgLen.LenBytes[0] & 0x0F));
365
366             CgLocalWriteAmlData (Op, &PkgLenFirstByte, 1);
367
368             /* Shift the length over by the 4 bits we just stuffed in the first byte */
369
370             PkgLen.Len >>= 4;
371
372             /* Now we can write the remaining bytes - either 1, 2, or 3 bytes */
373
374             for (i = 0; i < (UINT32) (Op->Asl.AmlPkgLenBytes - 1); i++)
375             {
376                 CgLocalWriteAmlData (Op, &PkgLen.LenBytes[i], 1);
377             }
378         }
379     }
380
381     switch (Aml.Opcode)
382     {
383     case AML_BYTE_OP:
384
385         CgLocalWriteAmlData (Op, (UINT8 *) &Op->Asl.Value.Integer, 1);
386         break;
387
388     case AML_WORD_OP:
389
390         CgLocalWriteAmlData (Op, (UINT16 *) &Op->Asl.Value.Integer, 2);
391        break;
392
393     case AML_DWORD_OP:
394
395         CgLocalWriteAmlData (Op, (UINT32 *) &Op->Asl.Value.Integer, 4);
396         break;
397
398     case AML_QWORD_OP:
399
400         CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, 8);
401         break;
402
403     case AML_STRING_OP:
404
405         CgLocalWriteAmlData (Op, Op->Asl.Value.String, Op->Asl.AmlLength);
406         break;
407
408     default:
409         /* All data opcodes must appear above */
410         break;
411     }
412 }
413
414
415 /*******************************************************************************
416  *
417  * FUNCTION:    CgWriteTableHeader
418  *
419  * PARAMETERS:  Op        - The DEFINITIONBLOCK node
420  *
421  * RETURN:      None.
422  *
423  * DESCRIPTION: Write a table header corresponding to the DEFINITIONBLOCK
424  *
425  ******************************************************************************/
426
427 void
428 CgWriteTableHeader (
429     ACPI_PARSE_OBJECT           *Op)
430 {
431     ACPI_PARSE_OBJECT           *Child;
432
433
434     /* AML filename */
435
436     Child = Op->Asl.Child;
437
438     /* Signature */
439
440     Child = Child->Asl.Next;
441     strncpy (TableHeader.Signature, Child->Asl.Value.String, 4);
442
443     /* Revision */
444
445     Child = Child->Asl.Next;
446     TableHeader.Revision = (UINT8) Child->Asl.Value.Integer;
447
448     /* Command-line Revision override */
449
450     if (Gbl_RevisionOverride)
451     {
452         TableHeader.Revision = Gbl_RevisionOverride;
453     }
454
455     /* OEMID */
456
457     Child = Child->Asl.Next;
458     strncpy (TableHeader.OemId, Child->Asl.Value.String, 6);
459
460     /* OEM TableID */
461
462     Child = Child->Asl.Next;
463     strncpy (TableHeader.OemTableId, Child->Asl.Value.String, 8);
464
465     /* OEM Revision */
466
467     Child = Child->Asl.Next;
468     TableHeader.OemRevision = (UINT32) Child->Asl.Value.Integer;
469
470     /* Compiler ID */
471
472     strncpy (TableHeader.AslCompilerId, CompilerCreatorId, 4);
473
474     /* Compiler version */
475
476     TableHeader.AslCompilerRevision = CompilerCreatorRevision;
477
478     /* Table length.  Checksum zero for now, will rewrite later */
479
480     TableHeader.Length   = Gbl_TableLength;
481     TableHeader.Checksum = 0;
482
483     CgLocalWriteAmlData (Op, &TableHeader, sizeof (ACPI_TABLE_HEADER));
484 }
485
486
487 /*******************************************************************************
488  *
489  * FUNCTION:    CgCloseTable
490  *
491  * PARAMETERS:  None.
492  *
493  * RETURN:      None.
494  *
495  * DESCRIPTION: Complete the ACPI table by calculating the checksum and
496  *              re-writing the header.
497  *
498  ******************************************************************************/
499
500 void
501 CgCloseTable (void)
502 {
503     signed char         Sum;
504     UINT8               FileByte;
505
506
507     FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
508     Sum = 0;
509
510     /* Calculate the checksum over the entire file */
511
512     while (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte, 1) == AE_OK)
513     {
514         Sum = (signed char) (Sum + FileByte);
515     }
516
517     /* Re-write the table header with the checksum */
518
519     TableHeader.Checksum = (UINT8) (0 - Sum);
520
521     FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
522     CgLocalWriteAmlData (NULL, &TableHeader, sizeof (ACPI_TABLE_HEADER));
523 }
524
525
526 /*******************************************************************************
527  *
528  * FUNCTION:    CgWriteNode
529  *
530  * PARAMETERS:  Op            - Parse node to write.
531  *
532  * RETURN:      None.
533  *
534  * DESCRIPTION: Write the AML that corresponds to a parse node.
535  *
536  ******************************************************************************/
537
538 void
539 CgWriteNode (
540     ACPI_PARSE_OBJECT       *Op)
541 {
542     ASL_RESOURCE_NODE       *Rnode;
543
544
545     Op->Asl.FinalAmlLength = 0;
546
547     /* Always check for DEFAULT_ARG and other "Noop" nodes */
548     /* TBD: this may not be the best place for this check */
549
550     if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)  ||
551         (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)     ||
552         (Op->Asl.ParseOpcode == PARSEOP_INCLUDE)      ||
553         (Op->Asl.ParseOpcode == PARSEOP_INCLUDE_END))
554     {
555         return;
556     }
557
558     switch (Op->Asl.AmlOpcode)
559     {
560     case AML_RAW_DATA_BYTE:
561     case AML_RAW_DATA_WORD:
562     case AML_RAW_DATA_DWORD:
563     case AML_RAW_DATA_QWORD:
564
565         CgLocalWriteAmlData (Op, &Op->Asl.Value.Integer, Op->Asl.AmlLength);
566         return;
567
568
569     case AML_RAW_DATA_BUFFER:
570
571         CgLocalWriteAmlData (Op, Op->Asl.Value.Buffer, Op->Asl.AmlLength);
572         return;
573
574
575     case AML_RAW_DATA_CHAIN:
576
577         Rnode = ACPI_CAST_PTR (ASL_RESOURCE_NODE, Op->Asl.Value.Buffer);
578         while (Rnode)
579         {
580             CgLocalWriteAmlData (Op, Rnode->Buffer, Rnode->BufferLength);
581             Rnode = Rnode->Next;
582         }
583         return;
584
585     default:
586         /* Internal data opcodes must all appear above */
587         break;
588     }
589
590     switch (Op->Asl.ParseOpcode)
591     {
592     case PARSEOP_DEFAULT_ARG:
593
594         break;
595
596     case PARSEOP_DEFINITIONBLOCK:
597
598         CgWriteTableHeader (Op);
599         break;
600
601     case PARSEOP_NAMESEG:
602     case PARSEOP_NAMESTRING:
603     case PARSEOP_METHODCALL:
604
605         CgLocalWriteAmlData (Op, Op->Asl.Value.String, Op->Asl.AmlLength);
606         break;
607
608     default:
609
610         CgWriteAmlOpcode (Op);
611         break;
612     }
613 }
614
615