dmrestag.c revision 237412
1272343Sngie/******************************************************************************
2272343Sngie *
3272343Sngie * Module Name: dmrestag - Add tags to resource descriptors (Application-level)
4272343Sngie *
5272343Sngie *****************************************************************************/
6272343Sngie
7272343Sngie/*
8272343Sngie * Copyright (C) 2000 - 2012, Intel Corp.
9272343Sngie * All rights reserved.
10272343Sngie *
11272343Sngie * Redistribution and use in source and binary forms, with or without
12272343Sngie * modification, are permitted provided that the following conditions
13272343Sngie * are met:
14272343Sngie * 1. Redistributions of source code must retain the above copyright
15272343Sngie *    notice, this list of conditions, and the following disclaimer,
16272343Sngie *    without modification.
17272343Sngie * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18272343Sngie *    substantially similar to the "NO WARRANTY" disclaimer below
19272343Sngie *    ("Disclaimer") and any redistribution must be conditioned upon
20272343Sngie *    including a substantially similar Disclaimer requirement for further
21272343Sngie *    binary redistribution.
22272343Sngie * 3. Neither the names of the above-listed copyright holders nor the names
23272343Sngie *    of any contributors may be used to endorse or promote products derived
24272343Sngie *    from this software without specific prior written permission.
25272343Sngie *
26272343Sngie * Alternatively, this software may be distributed under the terms of the
27272343Sngie * GNU General Public License ("GPL") version 2 as published by the Free
28272343Sngie * Software Foundation.
29272343Sngie *
30272343Sngie * NO WARRANTY
31272343Sngie * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32272343Sngie * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33272343Sngie * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34272343Sngie * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35272343Sngie * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36272343Sngie * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37272343Sngie * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38272343Sngie * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39272343Sngie * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40272343Sngie * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41272343Sngie * POSSIBILITY OF SUCH DAMAGES.
42272343Sngie */
43272343Sngie
44272343Sngie
45272343Sngie#include <contrib/dev/acpica/include/acpi.h>
46272343Sngie#include <contrib/dev/acpica/include/accommon.h>
47272343Sngie#include <contrib/dev/acpica/include/acparser.h>
48272343Sngie#include <contrib/dev/acpica/include/acdisasm.h>
49272343Sngie#include <contrib/dev/acpica/include/acnamesp.h>
50272343Sngie#include <contrib/dev/acpica/include/amlcode.h>
51272343Sngie
52272343Sngie/* This module used for application-level code only */
53272343Sngie
54272343Sngie#define _COMPONENT          ACPI_CA_DISASSEMBLER
55272343Sngie        ACPI_MODULE_NAME    ("dmrestag")
56272343Sngie
57272343Sngie/* Local prototypes */
58272343Sngie
59272343Sngiestatic void
60272343SngieAcpiDmUpdateResourceName (
61272343Sngie    ACPI_NAMESPACE_NODE     *ResourceNode);
62272343Sngie
63272343Sngiestatic char *
64AcpiDmSearchTagList (
65    UINT32                  BitIndex,
66    const ACPI_RESOURCE_TAG *TagList);
67
68static char *
69AcpiDmGetResourceTag (
70    UINT32                  BitIndex,
71    AML_RESOURCE            *Resource,
72    UINT8                   ResourceIndex);
73
74static char *
75AcpiGetTagPathname (
76    ACPI_PARSE_OBJECT       *Op,
77    ACPI_NAMESPACE_NODE     *BufferNode,
78    ACPI_NAMESPACE_NODE     *ResourceNode,
79    UINT32                  BitIndex);
80
81static ACPI_NAMESPACE_NODE *
82AcpiDmGetResourceNode (
83    ACPI_NAMESPACE_NODE     *BufferNode,
84    UINT32                  BitIndex);
85
86static ACPI_STATUS
87AcpiDmAddResourceToNamespace (
88    UINT8                   *Aml,
89    UINT32                  Length,
90    UINT32                  Offset,
91    UINT8                   ResourceIndex,
92    void                    *Context);
93
94static void
95AcpiDmAddResourcesToNamespace (
96    ACPI_NAMESPACE_NODE     *BufferNode,
97    ACPI_PARSE_OBJECT       *Op);
98
99
100/******************************************************************************
101 *
102 * Resource Tag tables
103 *
104 * These are the predefined tags that refer to elements of a resource
105 * descriptor. Each name and offset is defined in the ACPI specification.
106 *
107 * Each table entry contains the bit offset of the field and the associated
108 * name.
109 *
110 ******************************************************************************/
111
112static const ACPI_RESOURCE_TAG      AcpiDmIrqTags[] =
113{
114    {( 1 * 8),      ACPI_RESTAG_INTERRUPT},
115    {( 3 * 8) + 0,  ACPI_RESTAG_INTERRUPTTYPE},
116    {( 3 * 8) + 3,  ACPI_RESTAG_INTERRUPTLEVEL},
117    {( 3 * 8) + 4,  ACPI_RESTAG_INTERRUPTSHARE},
118    {0,             NULL}
119};
120
121static const ACPI_RESOURCE_TAG      AcpiDmDmaTags[] =
122{
123    {( 1 * 8),      ACPI_RESTAG_DMA},
124    {( 2 * 8) + 0,  ACPI_RESTAG_XFERTYPE},
125    {( 2 * 8) + 2,  ACPI_RESTAG_BUSMASTER},
126    {( 2 * 8) + 5,  ACPI_RESTAG_DMATYPE},
127    {0,             NULL}
128};
129
130static const ACPI_RESOURCE_TAG      AcpiDmIoTags[] =
131{
132    {( 1 * 8) + 0,  ACPI_RESTAG_DECODE},
133    {( 2 * 8),      ACPI_RESTAG_MINADDR},
134    {( 4 * 8),      ACPI_RESTAG_MAXADDR},
135    {( 6 * 8),      ACPI_RESTAG_ALIGNMENT},
136    {( 7 * 8),      ACPI_RESTAG_LENGTH},
137    {0,             NULL}
138};
139
140static const ACPI_RESOURCE_TAG      AcpiDmFixedIoTags[] =
141{
142    {( 1 * 8),      ACPI_RESTAG_BASEADDRESS},
143    {( 3 * 8),      ACPI_RESTAG_LENGTH},
144    {0,             NULL}
145};
146
147static const ACPI_RESOURCE_TAG      AcpiDmFixedDmaTags[] =
148{
149    {( 1 * 8),      ACPI_RESTAG_DMA},
150    {( 3 * 8),      ACPI_RESTAG_DMATYPE},
151    {( 5 * 8),      ACPI_RESTAG_XFERTYPE},
152    {0,             NULL}
153};
154
155static const ACPI_RESOURCE_TAG      AcpiDmMemory24Tags[] =
156{
157    {( 3 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
158    {( 4 * 8),      ACPI_RESTAG_MINADDR},
159    {( 6 * 8),      ACPI_RESTAG_MAXADDR},
160    {( 8 * 8),      ACPI_RESTAG_ALIGNMENT},
161    {(10 * 8),      ACPI_RESTAG_LENGTH},
162    {0,             NULL}
163};
164
165static const ACPI_RESOURCE_TAG      AcpiDmRegisterTags[] =
166{
167    {( 3 * 8),      ACPI_RESTAG_ADDRESSSPACE},
168    {( 4 * 8),      ACPI_RESTAG_REGISTERBITWIDTH},
169    {( 5 * 8),      ACPI_RESTAG_REGISTERBITOFFSET},
170    {( 6 * 8),      ACPI_RESTAG_ACCESSSIZE},
171    {( 7 * 8),      ACPI_RESTAG_ADDRESS},
172    {0,             NULL}
173};
174
175static const ACPI_RESOURCE_TAG      AcpiDmMemory32Tags[] =
176{
177    {( 3 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
178    {( 4 * 8),      ACPI_RESTAG_MINADDR},
179    {( 8 * 8),      ACPI_RESTAG_MAXADDR},
180    {(12 * 8),      ACPI_RESTAG_ALIGNMENT},
181    {(16 * 8),      ACPI_RESTAG_LENGTH},
182    {0,             NULL}
183};
184
185static const ACPI_RESOURCE_TAG      AcpiDmFixedMemory32Tags[] =
186{
187    {( 3 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
188    {( 4 * 8),      ACPI_RESTAG_BASEADDRESS},
189    {( 8 * 8),      ACPI_RESTAG_LENGTH},
190    {0,             NULL}
191};
192
193static const ACPI_RESOURCE_TAG      AcpiDmInterruptTags[] =
194{
195    {( 3 * 8) + 1,  ACPI_RESTAG_INTERRUPTTYPE},
196    {( 3 * 8) + 2,  ACPI_RESTAG_INTERRUPTLEVEL},
197    {( 3 * 8) + 3,  ACPI_RESTAG_INTERRUPTSHARE},
198    {( 5 * 8),      ACPI_RESTAG_INTERRUPT},
199    {0,             NULL}
200};
201
202static const ACPI_RESOURCE_TAG      AcpiDmAddress16Tags[] =
203{
204    {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
205    {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
206    {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
207    {( 6 * 8),      ACPI_RESTAG_GRANULARITY},
208    {( 8 * 8),      ACPI_RESTAG_MINADDR},
209    {(10 * 8),      ACPI_RESTAG_MAXADDR},
210    {(12 * 8),      ACPI_RESTAG_TRANSLATION},
211    {(14 * 8),      ACPI_RESTAG_LENGTH},
212    {0,             NULL}
213};
214
215static const ACPI_RESOURCE_TAG      AcpiDmAddress32Tags[] =
216{
217    {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
218    {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
219    {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
220    {( 6 * 8),      ACPI_RESTAG_GRANULARITY},
221    {(10 * 8),      ACPI_RESTAG_MINADDR},
222    {(14 * 8),      ACPI_RESTAG_MAXADDR},
223    {(18 * 8),      ACPI_RESTAG_TRANSLATION},
224    {(22 * 8),      ACPI_RESTAG_LENGTH},
225    {0,             NULL}
226};
227
228static const ACPI_RESOURCE_TAG      AcpiDmAddress64Tags[] =
229{
230    {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
231    {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
232    {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
233    {( 6 * 8),      ACPI_RESTAG_GRANULARITY},
234    {(14 * 8),      ACPI_RESTAG_MINADDR},
235    {(22 * 8),      ACPI_RESTAG_MAXADDR},
236    {(30 * 8),      ACPI_RESTAG_TRANSLATION},
237    {(38 * 8),      ACPI_RESTAG_LENGTH},
238    {0,             NULL}
239};
240
241static const ACPI_RESOURCE_TAG      AcpiDmExtendedAddressTags[] =
242{
243    {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
244    {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
245    {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
246    {( 8 * 8),      ACPI_RESTAG_GRANULARITY},
247    {(16 * 8),      ACPI_RESTAG_MINADDR},
248    {(24 * 8),      ACPI_RESTAG_MAXADDR},
249    {(32 * 8),      ACPI_RESTAG_TRANSLATION},
250    {(40 * 8),      ACPI_RESTAG_LENGTH},
251    {(48 * 8),      ACPI_RESTAG_TYPESPECIFICATTRIBUTES},
252    {0,             NULL}
253};
254
255/* Subtype tables for GPIO descriptors */
256
257static const ACPI_RESOURCE_TAG      AcpiDmGpioIntTags[] =
258{
259    {( 7 * 8) + 0,  ACPI_RESTAG_MODE},
260    {( 7 * 8) + 1,  ACPI_RESTAG_POLARITY},
261    {( 7 * 8) + 3,  ACPI_RESTAG_INTERRUPTSHARE},
262    {( 9 * 8),      ACPI_RESTAG_PINCONFIG},
263    {(10 * 8),      ACPI_RESTAG_DRIVESTRENGTH},
264    {(12 * 8),      ACPI_RESTAG_DEBOUNCETIME},
265    {0,             NULL}
266};
267
268static const ACPI_RESOURCE_TAG      AcpiDmGpioIoTags[] =
269{
270    {( 7 * 8) + 0,  ACPI_RESTAG_IORESTRICTION},
271    {( 7 * 8) + 3,  ACPI_RESTAG_INTERRUPTSHARE},
272    {( 9 * 8),      ACPI_RESTAG_PINCONFIG},
273    {(10 * 8),      ACPI_RESTAG_DRIVESTRENGTH},
274    {(12 * 8),      ACPI_RESTAG_DEBOUNCETIME},
275    {0,             NULL}
276};
277
278/* Subtype tables for SerialBus descriptors */
279
280static const ACPI_RESOURCE_TAG      AcpiDmI2cSerialBusTags[] =
281{
282    {( 6 * 8) + 0,  ACPI_RESTAG_SLAVEMODE},
283    {( 7 * 8) + 0,  ACPI_RESTAG_MODE},
284    {(12 * 8),      ACPI_RESTAG_SPEED},
285    {(16 * 8),      ACPI_RESTAG_ADDRESS},
286    {0,             NULL}
287};
288
289static const ACPI_RESOURCE_TAG      AcpiDmSpiSerialBusTags[] =
290{
291    {( 6 * 8) + 0,  ACPI_RESTAG_SLAVEMODE},
292    {( 7 * 8) + 0,  ACPI_RESTAG_MODE},
293    {( 7 * 8) + 1,  ACPI_RESTAG_DEVICEPOLARITY},
294    {(12 * 8),      ACPI_RESTAG_SPEED},
295    {(16 * 8),      ACPI_RESTAG_LENGTH},
296    {(17 * 8),      ACPI_RESTAG_PHASE},
297    {(18 * 8),      ACPI_RESTAG_POLARITY},
298    {(19 * 8),      ACPI_RESTAG_ADDRESS},
299    {0,             NULL}
300};
301
302static const ACPI_RESOURCE_TAG      AcpiDmUartSerialBusTags[] =
303{
304    {( 6 * 8) + 0,  ACPI_RESTAG_SLAVEMODE}, /* Note: not part of original macro */
305    {( 7 * 8) + 0,  ACPI_RESTAG_FLOWCONTROL},
306    {( 7 * 8) + 2,  ACPI_RESTAG_STOPBITS},
307    {( 7 * 8) + 4,  ACPI_RESTAG_LENGTH},
308    {( 7 * 8) + 7,  ACPI_RESTAG_ENDIANNESS},
309    {(12 * 8),      ACPI_RESTAG_SPEED},
310    {(16 * 8),      ACPI_RESTAG_LENGTH_RX},
311    {(18 * 8),      ACPI_RESTAG_LENGTH_TX},
312    {(20 * 8),      ACPI_RESTAG_PARITY},
313    {(21 * 8),      ACPI_RESTAG_LINE},
314    {0,             NULL}
315};
316
317/* Subtype tables for Address descriptor type-specific flags */
318
319static const ACPI_RESOURCE_TAG      AcpiDmMemoryFlagTags[] =
320{
321    {( 5 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
322    {( 5 * 8) + 1,  ACPI_RESTAG_MEMTYPE},
323    {( 5 * 8) + 3,  ACPI_RESTAG_MEMATTRIBUTES},
324    {( 5 * 8) + 5,  ACPI_RESTAG_TYPE},
325    {0,             NULL}
326};
327
328static const ACPI_RESOURCE_TAG      AcpiDmIoFlagTags[] =
329{
330    {( 5 * 8) + 0,  ACPI_RESTAG_RANGETYPE},
331    {( 5 * 8) + 4,  ACPI_RESTAG_TYPE},
332    {( 5 * 8) + 5,  ACPI_RESTAG_TRANSTYPE},
333    {0,             NULL}
334};
335
336
337/*
338 * Dispatch table used to obtain the correct tag table for a descriptor.
339 *
340 * A NULL in this table means one of three things:
341 * 1) The descriptor ID is reserved and invalid
342 * 2) The descriptor has no tags associated with it
343 * 3) The descriptor has subtypes and a separate table will be used.
344 */
345static const ACPI_RESOURCE_TAG      *AcpiGbl_ResourceTags[] =
346{
347    /* Small descriptors */
348
349    NULL,                           /* 0x00, Reserved */
350    NULL,                           /* 0x01, Reserved */
351    NULL,                           /* 0x02, Reserved */
352    NULL,                           /* 0x03, Reserved */
353    AcpiDmIrqTags,                  /* 0x04, ACPI_RESOURCE_NAME_IRQ_FORMAT */
354    AcpiDmDmaTags,                  /* 0x05, ACPI_RESOURCE_NAME_DMA_FORMAT */
355    NULL,                           /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */
356    NULL,                           /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */
357    AcpiDmIoTags,                   /* 0x08, ACPI_RESOURCE_NAME_IO_PORT */
358    AcpiDmFixedIoTags,              /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO_PORT */
359    AcpiDmFixedDmaTags,             /* 0x0A, ACPI_RESOURCE_NAME_FIXED_DMA */
360    NULL,                           /* 0x0B, Reserved */
361    NULL,                           /* 0x0C, Reserved */
362    NULL,                           /* 0x0D, Reserved */
363    NULL,                           /* 0x0E, ACPI_RESOURCE_NAME_SMALL_VENDOR */
364    NULL,                           /* 0x0F, ACPI_RESOURCE_NAME_END_TAG (not used) */
365
366    /* Large descriptors */
367
368    NULL,                           /* 0x00, Reserved */
369    AcpiDmMemory24Tags,             /* 0x01, ACPI_RESOURCE_NAME_MEMORY_24 */
370    AcpiDmRegisterTags,             /* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */
371    NULL,                           /* 0x03, Reserved */
372    NULL,                           /* 0x04, ACPI_RESOURCE_NAME_LARGE_VENDOR */
373    AcpiDmMemory32Tags,             /* 0x05, ACPI_RESOURCE_NAME_MEMORY_32 */
374    AcpiDmFixedMemory32Tags,        /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY_32 */
375    AcpiDmAddress32Tags,            /* 0x07, ACPI_RESOURCE_NAME_DWORD_ADDRESS_SPACE */
376    AcpiDmAddress16Tags,            /* 0x08, ACPI_RESOURCE_NAME_WORD_ADDRESS_SPACE */
377    AcpiDmInterruptTags,            /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_XRUPT */
378    AcpiDmAddress64Tags,            /* 0x0A, ACPI_RESOURCE_NAME_QWORD_ADDRESS_SPACE */
379    AcpiDmExtendedAddressTags,      /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS_SPACE */
380    NULL,                           /* 0x0C, ACPI_RESOURCE_NAME_GPIO - Use Subtype table below */
381    NULL,                           /* 0x0D, Reserved */
382    NULL                            /* 0x0E, ACPI_RESOURCE_NAME_SERIAL_BUS - Use Subtype table below */
383};
384
385/* GPIO Subtypes */
386
387static const ACPI_RESOURCE_TAG      *AcpiGbl_GpioResourceTags[] =
388{
389    AcpiDmGpioIntTags,              /* 0x00 Interrupt Connection */
390    AcpiDmGpioIoTags                /* 0x01 I/O Connection */
391};
392
393/* Serial Bus Subtypes */
394
395static const ACPI_RESOURCE_TAG      *AcpiGbl_SerialResourceTags[] =
396{
397    NULL,                           /* 0x00 Reserved */
398    AcpiDmI2cSerialBusTags,         /* 0x01 I2C SerialBus */
399    AcpiDmSpiSerialBusTags,         /* 0x02 SPI SerialBus */
400    AcpiDmUartSerialBusTags         /* 0x03 UART SerialBus */
401};
402
403/*
404 * Globals used to generate unique resource descriptor names. We use names that
405 * start with underscore and a prefix letter that is not used by other ACPI
406 * reserved names. To this, we append hex 0x00 through 0xFF. These 5 prefixes
407 * allow for 5*256 = 1280 unique names, probably sufficient for any single ASL
408 * file. If this becomes too small, we can use alpha+numerals for a total
409 * of 5*36*36 = 6480.
410 */
411#define ACPI_NUM_RES_PREFIX     5
412
413static UINT32                   AcpiGbl_NextResourceId = 0;
414static UINT8                    AcpiGbl_NextPrefix = 0;
415static char                     AcpiGbl_Prefix[ACPI_NUM_RES_PREFIX] =
416                                    {'Y','Z','J','K','X'};
417
418
419/*******************************************************************************
420 *
421 * FUNCTION:    AcpiDmCheckResourceReference
422 *
423 * PARAMETERS:  Op                  - Parse Op for the AML opcode
424 *              WalkState           - Current walk state (with valid scope)
425 *
426 * RETURN:      None
427 *
428 * DESCRIPTION: Convert a reference to a resource descriptor to a symbolic
429 *              reference if possible
430 *
431 * NOTE:        Bit index is used to transparently handle both resource bit
432 *              fields and byte fields.
433 *
434 ******************************************************************************/
435
436void
437AcpiDmCheckResourceReference (
438    ACPI_PARSE_OBJECT       *Op,
439    ACPI_WALK_STATE         *WalkState)
440{
441    ACPI_STATUS             Status;
442    ACPI_PARSE_OBJECT       *BufferNameOp;
443    ACPI_PARSE_OBJECT       *IndexOp;
444    ACPI_NAMESPACE_NODE     *BufferNode;
445    ACPI_NAMESPACE_NODE     *ResourceNode;
446    const ACPI_OPCODE_INFO  *OpInfo;
447    UINT32                  BitIndex;
448
449
450    /* We are only interested in the CreateXxxxField opcodes */
451
452    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
453    if (OpInfo->Type != AML_TYPE_CREATE_FIELD)
454    {
455        return;
456    }
457
458    /* Get the buffer term operand */
459
460    BufferNameOp = AcpiPsGetDepthNext (NULL, Op);
461
462    /* Must be a named buffer, not an arg or local or method call */
463
464    if (BufferNameOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)
465    {
466        return;
467    }
468
469    /* Get the Index term, must be an integer constant to convert */
470
471    IndexOp = BufferNameOp->Common.Next;
472    OpInfo = AcpiPsGetOpcodeInfo (IndexOp->Common.AmlOpcode);
473    if (OpInfo->ObjectType != ACPI_TYPE_INTEGER)
474    {
475        return;
476    }
477
478    /* Get the bit offset of the descriptor within the buffer */
479
480    if ((Op->Common.AmlOpcode == AML_CREATE_BIT_FIELD_OP) ||
481        (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP))
482    {
483        /* Index operand is a bit offset */
484
485        BitIndex = (UINT32) IndexOp->Common.Value.Integer;
486    }
487    else
488    {
489        /* Index operand is a byte offset, convert to bits */
490
491        BitIndex = (UINT32) ACPI_MUL_8 (IndexOp->Common.Value.Integer);
492    }
493
494    /* Lookup the buffer in the namespace */
495
496    Status = AcpiNsLookup (WalkState->ScopeInfo,
497                BufferNameOp->Common.Value.String, ACPI_TYPE_BUFFER,
498                ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState,
499                &BufferNode);
500    if (ACPI_FAILURE (Status))
501    {
502        return;
503    }
504
505    /* Validate object type, we must have a buffer */
506
507    if (BufferNode->Type != ACPI_TYPE_BUFFER)
508    {
509        return;
510    }
511
512    /* Find the resource descriptor node corresponding to the index */
513
514    ResourceNode = AcpiDmGetResourceNode (BufferNode, BitIndex);
515    if (!ResourceNode)
516    {
517        return;
518    }
519
520    /* Translate the Index to a resource tag pathname */
521
522    AcpiGetTagPathname (IndexOp, BufferNode, ResourceNode, BitIndex);
523}
524
525
526/*******************************************************************************
527 *
528 * FUNCTION:    AcpiDmGetResourceNode
529 *
530 * PARAMETERS:  BufferNode          - Node for the parent buffer
531 *              BitIndex            - Index into the resource descriptor
532 *
533 * RETURN:      Namespace node for the resource descriptor. NULL if not found
534 *
535 * DESCRIPTION: Find a resource descriptor that corresponds to the bit index
536 *
537 ******************************************************************************/
538
539static ACPI_NAMESPACE_NODE *
540AcpiDmGetResourceNode (
541    ACPI_NAMESPACE_NODE     *BufferNode,
542    UINT32                  BitIndex)
543{
544    ACPI_NAMESPACE_NODE     *Node;
545    UINT32                  ByteIndex = ACPI_DIV_8 (BitIndex);
546
547
548    /*
549     * Child list contains an entry for each resource descriptor. Find
550     * the descriptor that corresponds to the Index.
551     *
552     * If there are no children, this is not a resource template
553     */
554    Node = BufferNode->Child;
555    while (Node)
556    {
557        /*
558         * Check if the Index falls within this resource.
559         *
560         * Value contains the resource offset, Object contains the resource
561         * length (both in bytes)
562         */
563        if ((ByteIndex >= Node->Value) &&
564            (ByteIndex < (Node->Value + Node->Length)))
565        {
566            return (Node);
567        }
568
569        Node = Node->Peer;
570    }
571
572    return (NULL);
573}
574
575
576/*******************************************************************************
577 *
578 * FUNCTION:    AcpiGetTagPathname
579 *
580 * PARAMETERS:  BufferNode          - Node for the parent buffer
581 *              ResourceNode        - Node for a resource descriptor
582 *              BitIndex            - Index into the resource descriptor
583 *
584 * RETURN:      Full pathname for a resource tag. NULL if no match.
585 *              Path is returned in AML (packed) format.
586 *
587 * DESCRIPTION: Convert a BitIndex into a symbolic resource tag (full pathname)
588 *
589 ******************************************************************************/
590
591static char *
592AcpiGetTagPathname (
593    ACPI_PARSE_OBJECT       *IndexOp,
594    ACPI_NAMESPACE_NODE     *BufferNode,
595    ACPI_NAMESPACE_NODE     *ResourceNode,
596    UINT32                  BitIndex)
597{
598    ACPI_STATUS             Status;
599    UINT32                  ResourceBitIndex;
600    UINT8                   ResourceTableIndex;
601    ACPI_SIZE               RequiredSize;
602    char                    *Pathname;
603    AML_RESOURCE            *Aml;
604    ACPI_PARSE_OBJECT       *Op;
605    char                    *InternalPath;
606    char                    *Tag;
607
608
609    /* Get the Op that contains the actual buffer data */
610
611    Op = BufferNode->Op->Common.Value.Arg;
612    Op = Op->Common.Next;
613    if (!Op)
614    {
615        return (NULL);
616    }
617
618    /* Get the individual resource descriptor and validate it */
619
620    Aml = ACPI_CAST_PTR (AML_RESOURCE,
621            &Op->Named.Data[ResourceNode->Value]);
622
623    Status = AcpiUtValidateResource (Aml, &ResourceTableIndex);
624    if (ACPI_FAILURE (Status))
625    {
626        return (NULL);
627    }
628
629    /* Get offset into this descriptor (from offset into entire buffer) */
630
631    ResourceBitIndex = BitIndex - ACPI_MUL_8 (ResourceNode->Value);
632
633    /* Get the tag associated with this resource descriptor and offset */
634
635    Tag = AcpiDmGetResourceTag (ResourceBitIndex, Aml, ResourceTableIndex);
636    if (!Tag)
637    {
638        return (NULL);
639    }
640
641    /*
642     * Now that we know that we have a reference that can be converted to a
643     * symbol, change the name of the resource to a unique name.
644     */
645    AcpiDmUpdateResourceName (ResourceNode);
646
647    /* Get the full pathname to the parent buffer */
648
649    RequiredSize = AcpiNsGetPathnameLength (BufferNode);
650    if (!RequiredSize)
651    {
652        return (NULL);
653    }
654
655    Pathname = ACPI_ALLOCATE_ZEROED (RequiredSize + ACPI_PATH_SEGMENT_LENGTH);
656    if (!Pathname)
657    {
658        return (NULL);
659    }
660
661    Status = AcpiNsBuildExternalPath (BufferNode, RequiredSize, Pathname);
662    if (ACPI_FAILURE (Status))
663    {
664        return (NULL);
665    }
666
667    /*
668     * Create the full path to the resource and tag by: remove the buffer name,
669     * append the resource descriptor name, append a dot, append the tag name.
670     *
671     * TBD: Always using the full path is a bit brute force, the path can be
672     * often be optimized with carats (if the original buffer namepath is a
673     * single nameseg). This doesn't really matter, because these paths do not
674     * end up in the final compiled AML, it's just an appearance issue for the
675     * disassembled code.
676     */
677    Pathname[ACPI_STRLEN (Pathname) - ACPI_NAME_SIZE] = 0;
678    ACPI_STRNCAT (Pathname, ResourceNode->Name.Ascii, ACPI_NAME_SIZE);
679    ACPI_STRCAT (Pathname, ".");
680    ACPI_STRNCAT (Pathname, Tag, ACPI_NAME_SIZE);
681
682    /* Internalize the namepath to AML format */
683
684    AcpiNsInternalizeName (Pathname, &InternalPath);
685    ACPI_FREE (Pathname);
686
687    /* Update the Op with the symbol */
688
689    AcpiPsInitOp (IndexOp, AML_INT_NAMEPATH_OP);
690    IndexOp->Common.Value.String = InternalPath;
691
692    /* We will need the tag later. Cheat by putting it in the Node field */
693
694    IndexOp->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Tag);
695    return (InternalPath);
696}
697
698
699/*******************************************************************************
700 *
701 * FUNCTION:    AcpiDmUpdateResourceName
702 *
703 * PARAMETERS:  ResourceNode        - Node for a resource descriptor
704 *
705 * RETURN:      Stores new name in the ResourceNode
706 *
707 * DESCRIPTION: Create a new, unique name for a resource descriptor. Used by
708 *              both the disassembly of the descriptor itself and any symbolic
709 *              references to the descriptor. Ignored if a unique name has
710 *              already been assigned to the resource.
711 *
712 * NOTE: Single threaded, suitable for applications only!
713 *
714 ******************************************************************************/
715
716static void
717AcpiDmUpdateResourceName (
718    ACPI_NAMESPACE_NODE     *ResourceNode)
719{
720    char                    Name[ACPI_NAME_SIZE];
721
722
723    /* Ignore if a unique name has already been assigned */
724
725    if (ResourceNode->Name.Integer != ACPI_DEFAULT_RESNAME)
726    {
727        return;
728    }
729
730    /* Generate a new ACPI name for the descriptor */
731
732    Name[0] = '_';
733    Name[1] = AcpiGbl_Prefix[AcpiGbl_NextPrefix];
734    Name[2] = AcpiUtHexToAsciiChar ((UINT64) AcpiGbl_NextResourceId, 4);
735    Name[3] = AcpiUtHexToAsciiChar ((UINT64) AcpiGbl_NextResourceId, 0);
736
737    /* Update globals for next name */
738
739    AcpiGbl_NextResourceId++;
740    if (AcpiGbl_NextResourceId >= 256)
741    {
742        AcpiGbl_NextResourceId = 0;
743        AcpiGbl_NextPrefix++;
744        if (AcpiGbl_NextPrefix > ACPI_NUM_RES_PREFIX)
745        {
746            AcpiGbl_NextPrefix = 0;
747        }
748    }
749
750    /* Change the resource descriptor name */
751
752    ResourceNode->Name.Integer = *ACPI_CAST_PTR (UINT32, &Name[0]);
753}
754
755
756/*******************************************************************************
757 *
758 * FUNCTION:    AcpiDmGetResourceTag
759 *
760 * PARAMETERS:  BitIndex            - Index into the resource descriptor
761 *              Resource            - Pointer to the raw resource data
762 *              ResourceIndex       - Index correspoinding to the resource type
763 *
764 * RETURN:      Pointer to the resource tag (ACPI_NAME). NULL if no match.
765 *
766 * DESCRIPTION: Convert a BitIndex into a symbolic resource tag.
767 *
768 * Note: ResourceIndex should be previously validated and guaranteed to ve
769 *       valid.
770 *
771 ******************************************************************************/
772
773static char *
774AcpiDmGetResourceTag (
775    UINT32                  BitIndex,
776    AML_RESOURCE            *Resource,
777    UINT8                   ResourceIndex)
778{
779    const ACPI_RESOURCE_TAG *TagList;
780    char                    *Tag = NULL;
781
782
783    /* Get the tag list for this resource descriptor type */
784
785    TagList = AcpiGbl_ResourceTags[ResourceIndex];
786
787    /*
788     * Handle descriptors that have multiple subtypes
789     */
790    switch (Resource->DescriptorType)
791    {
792    case ACPI_RESOURCE_NAME_ADDRESS16:
793    case ACPI_RESOURCE_NAME_ADDRESS32:
794    case ACPI_RESOURCE_NAME_ADDRESS64:
795    case ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64:
796
797        /*
798         * Subtype differentiation is the flags.
799         * Kindof brute force, but just blindly search for an index match
800         */
801        if (Resource->Address.ResourceType == ACPI_ADDRESS_TYPE_MEMORY_RANGE)
802        {
803            Tag = AcpiDmSearchTagList (BitIndex, AcpiDmMemoryFlagTags);
804        }
805        else if (Resource->Address.ResourceType == ACPI_ADDRESS_TYPE_IO_RANGE)
806        {
807            Tag = AcpiDmSearchTagList (BitIndex, AcpiDmIoFlagTags);
808        }
809
810        /* If we found a match, all done. Else, drop to normal search below */
811
812        if (Tag)
813        {
814            return (Tag);
815        }
816        break;
817
818    case ACPI_RESOURCE_NAME_GPIO:
819
820        /* GPIO connection has 2 subtypes: Interrupt and I/O */
821
822        if (Resource->Gpio.ConnectionType > AML_RESOURCE_MAX_GPIOTYPE)
823        {
824            return (NULL);
825        }
826
827        TagList = AcpiGbl_GpioResourceTags[Resource->Gpio.ConnectionType];
828        break;
829
830    case ACPI_RESOURCE_NAME_SERIAL_BUS:
831
832        /* SerialBus has 3 subtypes: I2C, SPI, and UART */
833
834        if ((Resource->CommonSerialBus.Type == 0) ||
835            (Resource->CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE))
836        {
837            return (NULL);
838        }
839
840        TagList = AcpiGbl_SerialResourceTags[Resource->CommonSerialBus.Type];
841        break;
842
843    default:
844        break;
845    }
846
847    /* Search for a match against the BitIndex */
848
849    if (TagList)
850    {
851        Tag = AcpiDmSearchTagList (BitIndex, TagList);
852    }
853
854    return (Tag);
855}
856
857
858/*******************************************************************************
859 *
860 * FUNCTION:    AcpiDmSearchTagList
861 *
862 * PARAMETERS:  BitIndex            - Index into the resource descriptor
863 *              TagList             - List to search
864 *
865 * RETURN:      Pointer to a tag (ACPI_NAME). NULL if no match found.
866 *
867 * DESCRIPTION: Search a tag list for a match to the input BitIndex. Matches
868 *              a fixed offset to a symbolic resource tag name.
869 *
870 ******************************************************************************/
871
872static char *
873AcpiDmSearchTagList (
874    UINT32                  BitIndex,
875    const ACPI_RESOURCE_TAG *TagList)
876{
877
878    /*
879     * Walk the null-terminated tag list to find a matching bit offset.
880     * We are looking for an exact match.
881     */
882    for ( ; TagList->Tag; TagList++)
883    {
884        if (BitIndex == TagList->BitIndex)
885        {
886            return (TagList->Tag);
887        }
888    }
889
890    /* A matching offset was not found */
891
892    return (NULL);
893}
894
895
896/*******************************************************************************
897 *
898 * FUNCTION:    AcpiDmFindResources
899 *
900 * PARAMETERS:  Root                - Root of the parse tree
901 *
902 * RETURN:      None
903 *
904 * DESCRIPTION: Add all ResourceTemplate declarations to the namespace. Each
905 *              resource descriptor in each template is given a node -- used
906 *              for later conversion of resource references to symbolic refs.
907 *
908 ******************************************************************************/
909
910void
911AcpiDmFindResources (
912    ACPI_PARSE_OBJECT       *Root)
913{
914    ACPI_PARSE_OBJECT       *Op = Root;
915    ACPI_PARSE_OBJECT       *Parent;
916
917
918    /* Walk the entire parse tree */
919
920    while (Op)
921    {
922        /* We are interested in Buffer() declarations */
923
924        if (Op->Common.AmlOpcode == AML_BUFFER_OP)
925        {
926            /* And only declarations of the form Name (XXXX, Buffer()... ) */
927
928            Parent = Op->Common.Parent;
929            if (Parent->Common.AmlOpcode == AML_NAME_OP)
930            {
931                /*
932                 * If the buffer is a resource template, add the individual
933                 * resource descriptors to the namespace, as children of the
934                 * buffer node.
935                 */
936                if (ACPI_SUCCESS (AcpiDmIsResourceTemplate (Op)))
937                {
938                    Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
939                    AcpiDmAddResourcesToNamespace (Parent->Common.Node, Op);
940                }
941            }
942        }
943
944        Op = AcpiPsGetDepthNext (Root, Op);
945    }
946}
947
948
949/*******************************************************************************
950 *
951 * FUNCTION:    AcpiDmAddResourcesToNamespace
952 *
953 * PARAMETERS:  BufferNode          - Node for the parent buffer
954 *              Op                  - Parse op for the buffer
955 *
956 * RETURN:      None
957 *
958 * DESCRIPTION: Add an entire resource template to the namespace. Each
959 *              resource descriptor is added as a namespace node.
960 *
961 ******************************************************************************/
962
963static void
964AcpiDmAddResourcesToNamespace (
965    ACPI_NAMESPACE_NODE     *BufferNode,
966    ACPI_PARSE_OBJECT       *Op)
967{
968    ACPI_PARSE_OBJECT       *NextOp;
969
970
971    /* Get to the ByteData list */
972
973    NextOp = Op->Common.Value.Arg;
974    NextOp = NextOp->Common.Next;
975    if (!NextOp)
976    {
977        return;
978    }
979
980    /* Set Node and Op to point to each other */
981
982    BufferNode->Op = Op;
983    Op->Common.Node = BufferNode;
984
985    /*
986     * Insert each resource into the namespace
987     * NextOp contains the Aml pointer and the Aml length
988     */
989    AcpiUtWalkAmlResources ((UINT8 *) NextOp->Named.Data,
990        (ACPI_SIZE) NextOp->Common.Value.Integer,
991        AcpiDmAddResourceToNamespace, BufferNode);
992}
993
994
995/*******************************************************************************
996 *
997 * FUNCTION:    AcpiDmAddResourceToNamespace
998 *
999 * PARAMETERS:  ACPI_WALK_AML_CALLBACK
1000 *              BufferNode              - Node for the parent buffer
1001 *
1002 * RETURN:      Status
1003 *
1004 * DESCRIPTION: Add one resource descriptor to the namespace as a child of the
1005 *              parent buffer. The same name is used for each descriptor. This
1006 *              is changed later to a unique name if the resource is actually
1007 *              referenced by an AML operator.
1008 *
1009 ******************************************************************************/
1010
1011static ACPI_STATUS
1012AcpiDmAddResourceToNamespace (
1013    UINT8                   *Aml,
1014    UINT32                  Length,
1015    UINT32                  Offset,
1016    UINT8                   ResourceIndex,
1017    void                    *Context)
1018{
1019    ACPI_STATUS             Status;
1020    ACPI_GENERIC_STATE      ScopeInfo;
1021    ACPI_NAMESPACE_NODE     *Node;
1022
1023
1024    /* TBD: Don't need to add descriptors that have no tags defined? */
1025
1026    /* Add the resource to the namespace, as child of the buffer */
1027
1028    ScopeInfo.Scope.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Context);
1029    Status = AcpiNsLookup (&ScopeInfo, "_TMP", ACPI_TYPE_LOCAL_RESOURCE,
1030                ACPI_IMODE_LOAD_PASS2,
1031                ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_PREFIX_IS_SCOPE,
1032                NULL, &Node);
1033    if (ACPI_FAILURE (Status))
1034    {
1035        return (AE_OK);
1036    }
1037
1038    /* Set the name to the default, changed later if resource is referenced */
1039
1040    Node->Name.Integer = ACPI_DEFAULT_RESNAME;
1041
1042    /* Save the offset of the descriptor (within the original buffer) */
1043
1044    Node->Value = Offset;
1045    Node->Length = Length;
1046    return (AE_OK);
1047}
1048
1049