]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/contrib/dev/acpica/common/dmrestag.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / contrib / dev / acpica / common / dmrestag.c
1 /******************************************************************************
2  *
3  * Module Name: dmrestag - Add tags to resource descriptors (Application-level)
4  *
5  *****************************************************************************/
6
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2010, 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
117 #include <contrib/dev/acpica/include/acpi.h>
118 #include <contrib/dev/acpica/include/accommon.h>
119 #include <contrib/dev/acpica/include/acparser.h>
120 #include <contrib/dev/acpica/include/acdisasm.h>
121 #include <contrib/dev/acpica/include/acnamesp.h>
122 #include <contrib/dev/acpica/include/amlcode.h>
123
124 /* This module used for application-level code only */
125
126 #define _COMPONENT          ACPI_CA_DISASSEMBLER
127         ACPI_MODULE_NAME    ("dmrestag")
128
129 /* Local prototypes */
130
131 static void
132 AcpiDmUpdateResourceName (
133     ACPI_NAMESPACE_NODE     *ResourceNode);
134
135 static char *
136 AcpiDmSearchTagList (
137     UINT32                  BitIndex,
138     ACPI_RESOURCE_TAG       *TagList);
139
140 static char *
141 AcpiDmGetResourceTag (
142     UINT32                  BitIndex,
143     AML_RESOURCE            *Resource,
144     UINT8                   ResourceIndex);
145
146 static char *
147 AcpiGetTagPathname (
148     ACPI_NAMESPACE_NODE     *BufferNode,
149     ACPI_NAMESPACE_NODE     *ResourceNode,
150     UINT32                  BitIndex);
151
152 static ACPI_NAMESPACE_NODE *
153 AcpiDmGetResourceNode (
154     ACPI_NAMESPACE_NODE     *BufferNode,
155     UINT32                  BitIndex);
156
157 static ACPI_STATUS
158 AcpiDmAddResourceToNamespace (
159     UINT8                   *Aml,
160     UINT32                  Length,
161     UINT32                  Offset,
162     UINT8                   ResourceIndex,
163     void                    *Context);
164
165 static void
166 AcpiDmAddResourcesToNamespace (
167     ACPI_NAMESPACE_NODE     *BufferNode,
168     ACPI_PARSE_OBJECT       *Op);
169
170
171 /******************************************************************************
172  *
173  * Resource Tag tables
174  *
175  * These are the predefined tags that refer to elements of a resource
176  * descriptor. Each name and offset is defined in the ACPI specification.
177  *
178  * Each table entry contains the bit offset of the field and the associated
179  * name.
180  *
181  ******************************************************************************/
182
183 static ACPI_RESOURCE_TAG        AcpiDmIrqTags[] =
184 {
185     {( 1 * 8),      ACPI_RESTAG_INTERRUPT},
186     {( 3 * 8) + 0,  ACPI_RESTAG_INTERRUPTTYPE},
187     {( 3 * 8) + 3,  ACPI_RESTAG_INTERRUPTLEVEL},
188     {( 3 * 8) + 4,  ACPI_RESTAG_INTERRUPTSHARE},
189     {0,             NULL}
190 };
191
192 static ACPI_RESOURCE_TAG        AcpiDmDmaTags[] =
193 {
194     {( 1 * 8),      ACPI_RESTAG_DMA},
195     {( 2 * 8) + 0,  ACPI_RESTAG_XFERTYPE},
196     {( 2 * 8) + 2,  ACPI_RESTAG_BUSMASTER},
197     {( 2 * 8) + 5,  ACPI_RESTAG_DMATYPE},
198     {0,             NULL}
199 };
200
201 static ACPI_RESOURCE_TAG        AcpiDmIoTags[] =
202 {
203     {( 1 * 8) + 0,  ACPI_RESTAG_DECODE},
204     {( 2 * 8),      ACPI_RESTAG_MINADDR},
205     {( 4 * 8),      ACPI_RESTAG_MAXADDR},
206     {( 6 * 8),      ACPI_RESTAG_ALIGNMENT},
207     {( 7 * 8),      ACPI_RESTAG_LENGTH},
208     {0,             NULL}
209 };
210
211 static ACPI_RESOURCE_TAG        AcpiDmFixedIoTags[] =
212 {
213     {( 1 * 8),      ACPI_RESTAG_BASEADDRESS},
214     {( 3 * 8),      ACPI_RESTAG_LENGTH},
215     {0,             NULL}
216 };
217
218 static ACPI_RESOURCE_TAG        AcpiDmMemory24Tags[] =
219 {
220     {( 3 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
221     {( 4 * 8),      ACPI_RESTAG_MINADDR},
222     {( 6 * 8),      ACPI_RESTAG_MAXADDR},
223     {( 8 * 8),      ACPI_RESTAG_ALIGNMENT},
224     {(10 * 8),      ACPI_RESTAG_LENGTH},
225     {0,             NULL}
226 };
227
228 static ACPI_RESOURCE_TAG        AcpiDmRegisterTags[] =
229 {
230     {( 3 * 8),      ACPI_RESTAG_ADDRESSSPACE},
231     {( 4 * 8),      ACPI_RESTAG_REGISTERBITWIDTH},
232     {( 5 * 8),      ACPI_RESTAG_REGISTERBITOFFSET},
233     {( 6 * 8),      ACPI_RESTAG_ACCESSSIZE},
234     {( 7 * 8),      ACPI_RESTAG_ADDRESS},
235     {0,             NULL}
236 };
237
238 static ACPI_RESOURCE_TAG        AcpiDmMemory32Tags[] =
239 {
240     {( 3 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
241     {( 4 * 8),      ACPI_RESTAG_MINADDR},
242     {( 8 * 8),      ACPI_RESTAG_MAXADDR},
243     {(12 * 8),      ACPI_RESTAG_ALIGNMENT},
244     {(16 * 8),      ACPI_RESTAG_LENGTH},
245     {0,             NULL}
246 };
247
248 static ACPI_RESOURCE_TAG        AcpiDmFixedMemory32Tags[] =
249 {
250     {( 3 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
251     {( 4 * 8),      ACPI_RESTAG_BASEADDRESS},
252     {( 8 * 8),      ACPI_RESTAG_LENGTH},
253     {0,             NULL}
254 };
255
256 static ACPI_RESOURCE_TAG        AcpiDmInterruptTags[] =
257 {
258     {( 3 * 8) + 1,  ACPI_RESTAG_INTERRUPTTYPE},
259     {( 3 * 8) + 2,  ACPI_RESTAG_INTERRUPTLEVEL},
260     {( 3 * 8) + 3,  ACPI_RESTAG_INTERRUPTSHARE},
261     {( 5 * 8),      ACPI_RESTAG_INTERRUPT},
262     {0,             NULL}
263 };
264
265 static ACPI_RESOURCE_TAG        AcpiDmAddress16Tags[] =
266 {
267     {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
268     {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
269     {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
270     {( 6 * 8),      ACPI_RESTAG_GRANULARITY},
271     {( 8 * 8),      ACPI_RESTAG_MINADDR},
272     {(10 * 8),      ACPI_RESTAG_MAXADDR},
273     {(12 * 8),      ACPI_RESTAG_TRANSLATION},
274     {(14 * 8),      ACPI_RESTAG_LENGTH},
275     {0,             NULL}
276 };
277
278 static ACPI_RESOURCE_TAG        AcpiDmAddress32Tags[] =
279 {
280     {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
281     {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
282     {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
283     {( 6 * 8),      ACPI_RESTAG_GRANULARITY},
284     {(10 * 8),      ACPI_RESTAG_MINADDR},
285     {(14 * 8),      ACPI_RESTAG_MAXADDR},
286     {(18 * 8),      ACPI_RESTAG_TRANSLATION},
287     {(22 * 8),      ACPI_RESTAG_LENGTH},
288     {0,             NULL}
289 };
290
291 static ACPI_RESOURCE_TAG        AcpiDmAddress64Tags[] =
292 {
293     {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
294     {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
295     {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
296     {( 6 * 8),      ACPI_RESTAG_GRANULARITY},
297     {(14 * 8),      ACPI_RESTAG_MINADDR},
298     {(22 * 8),      ACPI_RESTAG_MAXADDR},
299     {(30 * 8),      ACPI_RESTAG_TRANSLATION},
300     {(38 * 8),      ACPI_RESTAG_LENGTH},
301     {0,             NULL}
302 };
303
304 static ACPI_RESOURCE_TAG        AcpiDmExtendedAddressTags[] =
305 {
306     {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
307     {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
308     {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
309     {( 8 * 8),      ACPI_RESTAG_GRANULARITY},
310     {(16 * 8),      ACPI_RESTAG_MINADDR},
311     {(24 * 8),      ACPI_RESTAG_MAXADDR},
312     {(32 * 8),      ACPI_RESTAG_TRANSLATION},
313     {(40 * 8),      ACPI_RESTAG_LENGTH},
314     {(48 * 8),      ACPI_RESTAG_TYPESPECIFICATTRIBUTES},
315     {0,             NULL}
316 };
317
318 /* Special-case tables for the type-specific flags */
319
320 static ACPI_RESOURCE_TAG        AcpiDmMemoryFlagTags[] =
321 {
322     {( 5 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
323     {( 5 * 8) + 1,  ACPI_RESTAG_MEMTYPE},
324     {( 5 * 8) + 3,  ACPI_RESTAG_MEMATTRIBUTES},
325     {( 5 * 8) + 5,  ACPI_RESTAG_TYPE},
326     {0,             NULL}
327 };
328
329 static ACPI_RESOURCE_TAG        AcpiDmIoFlagTags[] =
330 {
331     {( 5 * 8) + 0,  ACPI_RESTAG_RANGETYPE},
332     {( 5 * 8) + 4,  ACPI_RESTAG_TYPE},
333     {( 5 * 8) + 5,  ACPI_RESTAG_TRANSTYPE},
334     {0,             NULL}
335 };
336
337
338 /* Dispatch table used to obtain the correct tag table for a descriptor */
339
340 static ACPI_RESOURCE_TAG        *AcpiGbl_ResourceTags [] =
341 {
342     /* Small descriptors */
343
344     NULL,                           /* 0x00, Reserved */
345     NULL,                           /* 0x01, Reserved */
346     NULL,                           /* 0x02, Reserved */
347     NULL,                           /* 0x03, Reserved */
348     AcpiDmIrqTags,                  /* 0x04, ACPI_RESOURCE_NAME_IRQ_FORMAT */
349     AcpiDmDmaTags,                  /* 0x05, ACPI_RESOURCE_NAME_DMA_FORMAT */
350     NULL,                           /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */
351     NULL,                           /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */
352     AcpiDmIoTags,                   /* 0x08, ACPI_RESOURCE_NAME_IO_PORT */
353     AcpiDmFixedIoTags,              /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO_PORT */
354     NULL,                           /* 0x0A, Reserved */
355     NULL,                           /* 0x0B, Reserved */
356     NULL,                           /* 0x0C, Reserved */
357     NULL,                           /* 0x0D, Reserved */
358     NULL,                           /* 0x0E, ACPI_RESOURCE_NAME_SMALL_VENDOR */
359     NULL,                           /* 0x0F, ACPI_RESOURCE_NAME_END_TAG (not used) */
360
361     /* Large descriptors */
362
363     NULL,                           /* 0x00, Reserved */
364     AcpiDmMemory24Tags,             /* 0x01, ACPI_RESOURCE_NAME_MEMORY_24 */
365     AcpiDmRegisterTags,             /* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */
366     NULL,                           /* 0x03, Reserved */
367     NULL,                           /* 0x04, ACPI_RESOURCE_NAME_LARGE_VENDOR */
368     AcpiDmMemory32Tags,             /* 0x05, ACPI_RESOURCE_NAME_MEMORY_32 */
369     AcpiDmFixedMemory32Tags,        /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY_32 */
370     AcpiDmAddress32Tags,            /* 0x07, ACPI_RESOURCE_NAME_DWORD_ADDRESS_SPACE */
371     AcpiDmAddress16Tags,            /* 0x08, ACPI_RESOURCE_NAME_WORD_ADDRESS_SPACE */
372     AcpiDmInterruptTags,            /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_XRUPT */
373     AcpiDmAddress64Tags,            /* 0x0A, ACPI_RESOURCE_NAME_QWORD_ADDRESS_SPACE */
374     AcpiDmExtendedAddressTags       /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS_SPACE */
375 };
376
377
378 /*
379  * Globals used to generate unique resource descriptor names. We use names that
380  * start with underscore and a prefix letter that is not used by other ACPI
381  * reserved names. To this, we append hex 0x00 through 0xFF. These 5 prefixes
382  * allow for 5*256 = 1280 unique names, probably sufficient for any single ASL
383  * file. If this becomes too small, we can use alpha+numerals for a total
384  * of 5*36*36 = 6480.
385  */
386 #define ACPI_NUM_RES_PREFIX     5
387
388 static UINT32                   AcpiGbl_NextResourceId = 0;
389 static UINT8                    AcpiGbl_NextPrefix = 0;
390 static char                     AcpiGbl_Prefix[ACPI_NUM_RES_PREFIX] =
391                                     {'Y','Z','J','K','X'};
392
393
394 /*******************************************************************************
395  *
396  * FUNCTION:    AcpiDmCheckResourceReference
397  *
398  * PARAMETERS:  Op                  - Parse Op for the AML opcode
399  *              WalkState           - Current walk state (with valid scope)
400  *
401  * RETURN:      None
402  *
403  * DESCRIPTION: Convert a reference to a resource descriptor to a symbolic
404  *              reference if possible
405  *
406  * NOTE:        Bit index is used to transparently handle both resource bit
407  *              fields and byte fields.
408  *
409  ******************************************************************************/
410
411 void
412 AcpiDmCheckResourceReference (
413     ACPI_PARSE_OBJECT       *Op,
414     ACPI_WALK_STATE         *WalkState)
415 {
416     ACPI_STATUS             Status;
417     ACPI_PARSE_OBJECT       *BufferNameOp;
418     ACPI_PARSE_OBJECT       *IndexOp;
419     ACPI_NAMESPACE_NODE     *BufferNode;
420     ACPI_NAMESPACE_NODE     *ResourceNode;
421     const ACPI_OPCODE_INFO  *OpInfo;
422     char                    *Pathname;
423     UINT32                  BitIndex;
424
425
426     /* We are only interested in the CreateXxxxField opcodes */
427
428     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
429     if (OpInfo->Type != AML_TYPE_CREATE_FIELD)
430     {
431         return;
432     }
433
434     /* Get the buffer term operand */
435
436     BufferNameOp = AcpiPsGetDepthNext (NULL, Op);
437
438     /* Must be a named buffer, not an arg or local or method call */
439
440     if (BufferNameOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)
441     {
442         return;
443     }
444
445     /* Get the Index term, must be an integer constant to convert */
446
447     IndexOp = BufferNameOp->Common.Next;
448     OpInfo = AcpiPsGetOpcodeInfo (IndexOp->Common.AmlOpcode);
449     if (OpInfo->ObjectType != ACPI_TYPE_INTEGER)
450     {
451         return;
452     }
453
454     /* Get the bit offset of the descriptor within the buffer */
455
456     if ((Op->Common.AmlOpcode == AML_CREATE_BIT_FIELD_OP) ||
457         (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP))
458     {
459         /* Index operand is a bit offset */
460
461         BitIndex = (UINT32) IndexOp->Common.Value.Integer;
462     }
463     else
464     {
465         /* Index operand is a byte offset, convert to bits */
466
467         BitIndex = (UINT32) ACPI_MUL_8 (IndexOp->Common.Value.Integer);
468     }
469
470     /* Lookup the buffer in the namespace */
471
472     Status = AcpiNsLookup (WalkState->ScopeInfo,
473                 BufferNameOp->Common.Value.String, ACPI_TYPE_BUFFER,
474                 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState,
475                 &BufferNode);
476     if (ACPI_FAILURE (Status))
477     {
478         return;
479     }
480
481     /* Validate object type, we must have a buffer */
482
483     if (BufferNode->Type != ACPI_TYPE_BUFFER)
484     {
485         return;
486     }
487
488     /* Find the resource descriptor node corresponding to the index */
489
490     ResourceNode = AcpiDmGetResourceNode (BufferNode, BitIndex);
491     if (!ResourceNode)
492     {
493         return;
494     }
495
496     /* Translate the Index to a resource tag pathname */
497
498     Pathname = AcpiGetTagPathname (BufferNode, ResourceNode, BitIndex);
499     if (Pathname)
500     {
501         /* Complete the conversion of the Index to a symbol */
502
503         IndexOp->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
504         IndexOp->Common.Value.String = Pathname;
505     }
506 }
507
508
509 /*******************************************************************************
510  *
511  * FUNCTION:    AcpiDmGetResourceNode
512  *
513  * PARAMETERS:  BufferNode          - Node for the parent buffer
514  *              BitIndex            - Index into the resource descriptor
515  *
516  * RETURN:      Namespace node for the resource descriptor. NULL if not found
517  *
518  * DESCRIPTION: Find a resource descriptor that corresponds to the bit index
519  *
520  ******************************************************************************/
521
522 static ACPI_NAMESPACE_NODE *
523 AcpiDmGetResourceNode (
524     ACPI_NAMESPACE_NODE     *BufferNode,
525     UINT32                  BitIndex)
526 {
527     ACPI_NAMESPACE_NODE     *Node;
528     UINT32                  ByteIndex = ACPI_DIV_8 (BitIndex);
529
530
531     /*
532      * Child list contains an entry for each resource descriptor. Find
533      * the descriptor that corresponds to the Index.
534      *
535      * If there are no children, this is not a resource template
536      */
537     Node = BufferNode->Child;
538     while (Node)
539     {
540         /*
541          * Check if the Index falls within this resource.
542          *
543          * Value contains the resource offset, Object contains the resource
544          * length (both in bytes)
545          */
546         if ((ByteIndex >= Node->Value) &&
547             (ByteIndex < (Node->Value + Node->Length)))
548         {
549             return (Node);
550         }
551
552         /* List is circular, this flag marks the end */
553
554         if (Node->Flags & ANOBJ_END_OF_PEER_LIST)
555         {
556             return (NULL);
557         }
558
559         Node = Node->Peer;
560     }
561
562     return (NULL);
563 }
564
565
566 /*******************************************************************************
567  *
568  * FUNCTION:    AcpiGetTagPathname
569  *
570  * PARAMETERS:  BufferNode          - Node for the parent buffer
571  *              ResourceNode        - Node for a resource descriptor
572  *              BitIndex            - Index into the resource descriptor
573  *
574  * RETURN:      Full pathname for a resource tag. NULL if no match.
575  *              Path is returned in AML (packed) format.
576  *
577  * DESCRIPTION: Convert a BitIndex into a symbolic resource tag (full pathname)
578  *
579  ******************************************************************************/
580
581 static char *
582 AcpiGetTagPathname (
583     ACPI_NAMESPACE_NODE     *BufferNode,
584     ACPI_NAMESPACE_NODE     *ResourceNode,
585     UINT32                  BitIndex)
586 {
587     ACPI_STATUS             Status;
588     UINT32                  ResourceBitIndex;
589     UINT8                   ResourceTableIndex;
590     ACPI_SIZE               RequiredSize;
591     char                    *Pathname;
592     AML_RESOURCE            *Aml;
593     ACPI_PARSE_OBJECT       *Op;
594     char                    *InternalPath;
595     char                    *Tag;
596
597
598     /* Get the Op that contains the actual buffer data */
599
600     Op = BufferNode->Op->Common.Value.Arg;
601     Op = Op->Common.Next;
602     if (!Op)
603     {
604         return (NULL);
605     }
606
607     /* Get the individual resource descriptor and validate it */
608
609     Aml = ACPI_CAST_PTR (AML_RESOURCE,
610             &Op->Named.Data[ResourceNode->Value]);
611
612     Status = AcpiUtValidateResource (Aml, &ResourceTableIndex);
613     if (ACPI_FAILURE (Status))
614     {
615         return (NULL);
616     }
617
618     /* Get offset into this descriptor (from offset into entire buffer) */
619
620     ResourceBitIndex = BitIndex - ACPI_MUL_8 (ResourceNode->Value);
621
622     /* Get the tag associated with this resource descriptor and offset */
623
624     Tag = AcpiDmGetResourceTag (ResourceBitIndex, Aml, ResourceTableIndex);
625     if (!Tag)
626     {
627         return (NULL);
628     }
629
630     /*
631      * Now that we know that we have a reference that can be converted to a
632      * symbol, change the name of the resource to a unique name.
633      */
634     AcpiDmUpdateResourceName (ResourceNode);
635
636     /* Get the full pathname to the parent buffer */
637
638     RequiredSize = AcpiNsGetPathnameLength (BufferNode);
639     if (!RequiredSize)
640     {
641         return (NULL);
642     }
643
644     Pathname = ACPI_ALLOCATE_ZEROED (RequiredSize + ACPI_PATH_SEGMENT_LENGTH);
645     if (!Pathname)
646     {
647         return (NULL);
648     }
649
650     Status = AcpiNsBuildExternalPath (BufferNode, RequiredSize, Pathname);
651     if (ACPI_FAILURE (Status))
652     {
653         return (NULL);
654     }
655
656     /*
657      * Create the full path to the resource and tag by: remove the buffer name,
658      * append the resource descriptor name, append a dot, append the tag name.
659      *
660      * TBD: Always using the full path is a bit brute force, the path can be
661      * often be optimized with carats (if the original buffer namepath is a
662      * single nameseg). This doesn't really matter, because these paths do not
663      * end up in the final compiled AML, it's just an appearance issue for the
664      * disassembled code.
665      */
666     Pathname[ACPI_STRLEN (Pathname) - ACPI_NAME_SIZE] = 0;
667     ACPI_STRNCAT (Pathname, ResourceNode->Name.Ascii, ACPI_NAME_SIZE);
668     ACPI_STRCAT (Pathname, ".");
669     ACPI_STRNCAT (Pathname, Tag, ACPI_NAME_SIZE);
670
671     /* Internalize the namepath to AML format */
672
673     AcpiNsInternalizeName (Pathname, &InternalPath);
674     ACPI_FREE (Pathname);
675     return (InternalPath);
676 }
677
678
679 /*******************************************************************************
680  *
681  * FUNCTION:    AcpiDmUpdateResourceName
682  *
683  * PARAMETERS:  ResourceNode        - Node for a resource descriptor
684  *
685  * RETURN:      Stores new name in the ResourceNode
686  *
687  * DESCRIPTION: Create a new, unique name for a resource descriptor. Used by
688  *              both the disassembly of the descriptor itself and any symbolic
689  *              references to the descriptor. Ignored if a unique name has
690  *              already been assigned to the resource.
691  *
692  * NOTE: Single threaded, suitable for applications only!
693  *
694  ******************************************************************************/
695
696 static void
697 AcpiDmUpdateResourceName (
698     ACPI_NAMESPACE_NODE     *ResourceNode)
699 {
700     char                    Name[ACPI_NAME_SIZE];
701
702
703     /* Ignore if a unique name has already been assigned */
704
705     if (ResourceNode->Name.Integer != ACPI_DEFAULT_RESNAME)
706     {
707         return;
708     }
709
710     /* Generate a new ACPI name for the descriptor */
711
712     Name[0] = '_';
713     Name[1] = AcpiGbl_Prefix[AcpiGbl_NextPrefix];
714     Name[2] = AcpiUtHexToAsciiChar (AcpiGbl_NextResourceId, 4);
715     Name[3] = AcpiUtHexToAsciiChar (AcpiGbl_NextResourceId, 0);
716
717     /* Update globals for next name */
718
719     AcpiGbl_NextResourceId++;
720     if (AcpiGbl_NextResourceId >= 256)
721     {
722         AcpiGbl_NextResourceId = 0;
723         AcpiGbl_NextPrefix++;
724         if (AcpiGbl_NextPrefix > ACPI_NUM_RES_PREFIX)
725         {
726             AcpiGbl_NextPrefix = 0;
727         }
728     }
729
730     /* Change the resource descriptor name */
731
732     ResourceNode->Name.Integer = *ACPI_CAST_PTR (UINT32, &Name[0]);
733 }
734
735
736 /*******************************************************************************
737  *
738  * FUNCTION:    AcpiDmGetResourceTag
739  *
740  * PARAMETERS:  BitIndex            - Index into the resource descriptor
741  *              Resource            - Pointer to the raw resource data
742  *              ResourceIndex       - Index correspoinding to the resource type
743  *
744  * RETURN:      Pointer to the resource tag (ACPI_NAME). NULL if no match.
745  *
746  * DESCRIPTION: Convert a BitIndex into a symbolic resource tag.
747  *
748  ******************************************************************************/
749
750 static char *
751 AcpiDmGetResourceTag (
752     UINT32                  BitIndex,
753     AML_RESOURCE            *Resource,
754     UINT8                   ResourceIndex)
755 {
756     ACPI_RESOURCE_TAG       *TagList;
757     char                    *Tag = NULL;
758
759
760     /* Get the tag list for this resource descriptor type */
761
762     TagList = AcpiGbl_ResourceTags[ResourceIndex];
763     if (!TagList)
764     {
765         /* There are no tags for this resource type */
766
767         return (NULL);
768     }
769
770     /*
771      * Handle the type-specific flags field for the address descriptors.
772      * Kindof brute force, but just blindly search for an index match.
773      */
774     switch (Resource->DescriptorType)
775     {
776     case ACPI_RESOURCE_NAME_ADDRESS16:
777     case ACPI_RESOURCE_NAME_ADDRESS32:
778     case ACPI_RESOURCE_NAME_ADDRESS64:
779     case ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64:
780
781         if (Resource->Address.ResourceType == ACPI_ADDRESS_TYPE_MEMORY_RANGE)
782         {
783             Tag = AcpiDmSearchTagList (BitIndex, AcpiDmMemoryFlagTags);
784         }
785         else if (Resource->Address.ResourceType == ACPI_ADDRESS_TYPE_IO_RANGE)
786         {
787             Tag = AcpiDmSearchTagList (BitIndex, AcpiDmIoFlagTags);
788         }
789
790         /* If we found a match, all done. Else, drop to normal search below */
791
792         if (Tag)
793         {
794             return (Tag);
795         }
796         break;
797
798     default:
799         break;
800     }
801
802     /* Search the tag list for this descriptor type */
803
804     Tag = AcpiDmSearchTagList (BitIndex, TagList);
805     return (Tag);
806 }
807
808
809 /*******************************************************************************
810  *
811  * FUNCTION:    AcpiDmSearchTagList
812  *
813  * PARAMETERS:  BitIndex            - Index into the resource descriptor
814  *              TagList             - List to search
815  *
816  * RETURN:      Pointer to a tag (ACPI_NAME). NULL if no match found.
817  *
818  * DESCRIPTION: Search a tag list for a match to the input BitIndex. Matches
819  *              a fixed offset to a symbolic resource tag name.
820  *
821  ******************************************************************************/
822
823 static char *
824 AcpiDmSearchTagList (
825     UINT32                  BitIndex,
826     ACPI_RESOURCE_TAG       *TagList)
827 {
828
829     /*
830      * Walk the null-terminated tag list to find a matching bit offset.
831      * We are looking for an exact match.
832      */
833     for ( ; TagList->Tag; TagList++)
834     {
835         if (BitIndex == TagList->BitIndex)
836         {
837             return (TagList->Tag);
838         }
839     }
840
841     /* A matching offset was not found */
842
843     return (NULL);
844 }
845
846
847 /*******************************************************************************
848  *
849  * FUNCTION:    AcpiDmFindResources
850  *
851  * PARAMETERS:  Root                - Root of the parse tree
852  *
853  * RETURN:      None
854  *
855  * DESCRIPTION: Add all ResourceTemplate declarations to the namespace. Each
856  *              resource descriptor in each template is given a node -- used
857  *              for later conversion of resource references to symbolic refs.
858  *
859  ******************************************************************************/
860
861 void
862 AcpiDmFindResources (
863     ACPI_PARSE_OBJECT       *Root)
864 {
865     ACPI_PARSE_OBJECT       *Op = Root;
866     ACPI_PARSE_OBJECT       *Parent;
867
868
869     /* Walk the entire parse tree */
870
871     while (Op)
872     {
873         /* We are interested in Buffer() declarations */
874
875         if (Op->Common.AmlOpcode == AML_BUFFER_OP)
876         {
877             /* And only declarations of the form Name (XXXX, Buffer()... ) */
878
879             Parent = Op->Common.Parent;
880             if (Parent->Common.AmlOpcode == AML_NAME_OP)
881             {
882                 /*
883                  * If the buffer is a resource template, add the individual
884                  * resource descriptors to the namespace, as children of the
885                  * buffer node.
886                  */
887                 if (ACPI_SUCCESS (AcpiDmIsResourceTemplate (Op)))
888                 {
889                     Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
890                     AcpiDmAddResourcesToNamespace (Parent->Common.Node, Op);
891                 }
892             }
893         }
894
895         Op = AcpiPsGetDepthNext (Root, Op);
896     }
897 }
898
899
900 /*******************************************************************************
901  *
902  * FUNCTION:    AcpiDmAddResourcesToNamespace
903  *
904  * PARAMETERS:  BufferNode          - Node for the parent buffer
905  *              Op                  - Parse op for the buffer
906  *
907  * RETURN:      None
908  *
909  * DESCRIPTION: Add an entire resource template to the namespace. Each
910  *              resource descriptor is added as a namespace node.
911  *
912  ******************************************************************************/
913
914 static void
915 AcpiDmAddResourcesToNamespace (
916     ACPI_NAMESPACE_NODE     *BufferNode,
917     ACPI_PARSE_OBJECT       *Op)
918 {
919     ACPI_PARSE_OBJECT       *NextOp;
920
921
922     /* Get to the ByteData list */
923
924     NextOp = Op->Common.Value.Arg;
925     NextOp = NextOp->Common.Next;
926     if (!NextOp)
927     {
928         return;
929     }
930
931     /* Set Node and Op to point to each other */
932
933     BufferNode->Op = Op;
934     Op->Common.Node = BufferNode;
935
936     /*
937      * Insert each resource into the namespace
938      * NextOp contains the Aml pointer and the Aml length
939      */
940     AcpiUtWalkAmlResources ((UINT8 *) NextOp->Named.Data,
941         (ACPI_SIZE) NextOp->Common.Value.Integer,
942         AcpiDmAddResourceToNamespace, BufferNode);
943 }
944
945
946 /*******************************************************************************
947  *
948  * FUNCTION:    AcpiDmAddResourceToNamespace
949  *
950  * PARAMETERS:  ACPI_WALK_AML_CALLBACK
951  *              BufferNode              - Node for the parent buffer
952  *
953  * RETURN:      Status
954  *
955  * DESCRIPTION: Add one resource descriptor to the namespace as a child of the
956  *              parent buffer. The same name is used for each descriptor. This
957  *              is changed later to a unique name if the resource is actually
958  *              referenced by an AML operator.
959  *
960  ******************************************************************************/
961
962 static ACPI_STATUS
963 AcpiDmAddResourceToNamespace (
964     UINT8                   *Aml,
965     UINT32                  Length,
966     UINT32                  Offset,
967     UINT8                   ResourceIndex,
968     void                    *Context)
969 {
970     ACPI_STATUS             Status;
971     ACPI_GENERIC_STATE      ScopeInfo;
972     ACPI_NAMESPACE_NODE     *Node;
973
974
975     /* TBD: Don't need to add descriptors that have no tags defined? */
976
977     /* Add the resource to the namespace, as child of the buffer */
978
979     ScopeInfo.Scope.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Context);
980     Status = AcpiNsLookup (&ScopeInfo, "_TMP", ACPI_TYPE_LOCAL_RESOURCE,
981                 ACPI_IMODE_LOAD_PASS2,
982                 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_PREFIX_IS_SCOPE,
983                 NULL, &Node);
984     if (ACPI_FAILURE (Status))
985     {
986         return (AE_OK);
987     }
988
989     /* Set the name to the default, changed later if resource is referenced */
990
991     Node->Name.Integer = ACPI_DEFAULT_RESNAME;
992
993     /* Save the offset of the descriptor (within the original buffer) */
994
995     Node->Value = Offset;
996     Node->Length = Length;
997     return (AE_OK);
998 }
999