1100966Siwasaki/*******************************************************************************
2100966Siwasaki *
3100966Siwasaki * Module Name: dmresrc.c - Resource Descriptor disassembly
4100966Siwasaki *
5100966Siwasaki ******************************************************************************/
6100966Siwasaki
7217365Sjkim/*
8217365Sjkim * Copyright (C) 2000 - 2011, Intel Corp.
9100966Siwasaki * All rights reserved.
10100966Siwasaki *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25100966Siwasaki *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29100966Siwasaki *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43100966Siwasaki
44100966Siwasaki
45193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
46193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
47193341Sjkim#include <contrib/dev/acpica/include/amlcode.h>
48193341Sjkim#include <contrib/dev/acpica/include/acdisasm.h>
49100966Siwasaki
50100966Siwasaki#ifdef ACPI_DISASSEMBLER
51100966Siwasaki
52102550Siwasaki#define _COMPONENT          ACPI_CA_DEBUGGER
53100966Siwasaki        ACPI_MODULE_NAME    ("dbresrc")
54100966Siwasaki
55100966Siwasaki
56151937Sjkim/* Dispatch tables for Resource disassembly functions */
57151937Sjkim
58151937Sjkimtypedef
59151937Sjkimvoid (*ACPI_RESOURCE_HANDLER) (
60151937Sjkim    AML_RESOURCE            *Resource,
61151937Sjkim    UINT32                  Length,
62151937Sjkim    UINT32                  Level);
63151937Sjkim
64193267Sjkimstatic ACPI_RESOURCE_HANDLER    AcpiGbl_DmResourceDispatch [] =
65151937Sjkim{
66167802Sjkim    /* Small descriptors */
67167802Sjkim
68151937Sjkim    NULL,                           /* 0x00, Reserved */
69151937Sjkim    NULL,                           /* 0x01, Reserved */
70151937Sjkim    NULL,                           /* 0x02, Reserved */
71151937Sjkim    NULL,                           /* 0x03, Reserved */
72151937Sjkim    AcpiDmIrqDescriptor,            /* 0x04, ACPI_RESOURCE_NAME_IRQ_FORMAT */
73151937Sjkim    AcpiDmDmaDescriptor,            /* 0x05, ACPI_RESOURCE_NAME_DMA_FORMAT */
74151937Sjkim    AcpiDmStartDependentDescriptor, /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */
75151937Sjkim    AcpiDmEndDependentDescriptor,   /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */
76151937Sjkim    AcpiDmIoDescriptor,             /* 0x08, ACPI_RESOURCE_NAME_IO_PORT */
77151937Sjkim    AcpiDmFixedIoDescriptor,        /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO_PORT */
78151937Sjkim    NULL,                           /* 0x0A, Reserved */
79151937Sjkim    NULL,                           /* 0x0B, Reserved */
80151937Sjkim    NULL,                           /* 0x0C, Reserved */
81151937Sjkim    NULL,                           /* 0x0D, Reserved */
82151937Sjkim    AcpiDmVendorSmallDescriptor,    /* 0x0E, ACPI_RESOURCE_NAME_SMALL_VENDOR */
83167802Sjkim    NULL,                           /* 0x0F, ACPI_RESOURCE_NAME_END_TAG (not used) */
84151937Sjkim
85167802Sjkim    /* Large descriptors */
86167802Sjkim
87151937Sjkim    NULL,                           /* 0x00, Reserved */
88151937Sjkim    AcpiDmMemory24Descriptor,       /* 0x01, ACPI_RESOURCE_NAME_MEMORY_24 */
89151937Sjkim    AcpiDmGenericRegisterDescriptor,/* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */
90151937Sjkim    NULL,                           /* 0x03, Reserved */
91151937Sjkim    AcpiDmVendorLargeDescriptor,    /* 0x04, ACPI_RESOURCE_NAME_LARGE_VENDOR */
92151937Sjkim    AcpiDmMemory32Descriptor,       /* 0x05, ACPI_RESOURCE_NAME_MEMORY_32 */
93151937Sjkim    AcpiDmFixedMemory32Descriptor,  /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY_32 */
94151937Sjkim    AcpiDmDwordDescriptor,          /* 0x07, ACPI_RESOURCE_NAME_DWORD_ADDRESS_SPACE */
95151937Sjkim    AcpiDmWordDescriptor,           /* 0x08, ACPI_RESOURCE_NAME_WORD_ADDRESS_SPACE */
96151937Sjkim    AcpiDmInterruptDescriptor,      /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_XRUPT */
97151937Sjkim    AcpiDmQwordDescriptor,          /* 0x0A, ACPI_RESOURCE_NAME_QWORD_ADDRESS_SPACE */
98151937Sjkim    AcpiDmExtendedDescriptor        /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS_SPACE */
99151937Sjkim};
100151937Sjkim
101151937Sjkim
102167802Sjkim/* Only used for single-threaded applications */
103167802Sjkim/* TBD: remove when name is passed as parameter to the dump functions */
104151937Sjkim
105167802Sjkimstatic UINT32               ResourceName;
106151937Sjkim
107151937Sjkim
108100966Siwasaki/*******************************************************************************
109100966Siwasaki *
110167802Sjkim * FUNCTION:    AcpiDmDescriptorName
111167802Sjkim *
112167802Sjkim * PARAMETERS:  None
113167802Sjkim *
114167802Sjkim * RETURN:      None
115167802Sjkim *
116167802Sjkim * DESCRIPTION: Emit a name for the descriptor if one is present (indicated
117167802Sjkim *              by the name being changed from the default name.) A name is only
118167802Sjkim *              emitted if a reference to the descriptor has been made somewhere
119167802Sjkim *              in the original ASL code.
120167802Sjkim *
121167802Sjkim ******************************************************************************/
122167802Sjkim
123167802Sjkimvoid
124167802SjkimAcpiDmDescriptorName (
125167802Sjkim    void)
126167802Sjkim{
127167802Sjkim
128167802Sjkim    if (ResourceName == ACPI_DEFAULT_RESNAME)
129167802Sjkim    {
130167802Sjkim        return;
131167802Sjkim    }
132167802Sjkim
133167802Sjkim    AcpiOsPrintf ("%4.4s", (char *) &ResourceName);
134167802Sjkim}
135167802Sjkim
136167802Sjkim
137167802Sjkim/*******************************************************************************
138167802Sjkim *
139151937Sjkim * FUNCTION:    AcpiDmDumpInteger*
140151937Sjkim *
141151937Sjkim * PARAMETERS:  Value               - Value to emit
142151937Sjkim *              Name                - Associated name (emitted as a comment)
143151937Sjkim *
144151937Sjkim * RETURN:      None
145151937Sjkim *
146151937Sjkim * DESCRIPTION: Integer output helper functions
147151937Sjkim *
148151937Sjkim ******************************************************************************/
149151937Sjkim
150151937Sjkimvoid
151151937SjkimAcpiDmDumpInteger8 (
152151937Sjkim    UINT8                   Value,
153151937Sjkim    char                    *Name)
154151937Sjkim{
155151937Sjkim    AcpiOsPrintf ("0x%2.2X,               // %s\n", Value, Name);
156151937Sjkim}
157151937Sjkim
158151937Sjkimvoid
159151937SjkimAcpiDmDumpInteger16 (
160151937Sjkim    UINT16                  Value,
161151937Sjkim    char                    *Name)
162151937Sjkim{
163151937Sjkim    AcpiOsPrintf ("0x%4.4X,             // %s\n", Value, Name);
164151937Sjkim}
165151937Sjkim
166151937Sjkimvoid
167151937SjkimAcpiDmDumpInteger32 (
168151937Sjkim    UINT32                  Value,
169151937Sjkim    char                    *Name)
170151937Sjkim{
171151937Sjkim    AcpiOsPrintf ("0x%8.8X,         // %s\n", Value, Name);
172151937Sjkim}
173151937Sjkim
174151937Sjkimvoid
175151937SjkimAcpiDmDumpInteger64 (
176151937Sjkim    UINT64                  Value,
177151937Sjkim    char                    *Name)
178151937Sjkim{
179167802Sjkim    AcpiOsPrintf ("0x%8.8X%8.8X, // %s\n", ACPI_FORMAT_UINT64 (Value), Name);
180151937Sjkim}
181151937Sjkim
182151937Sjkim
183151937Sjkim/*******************************************************************************
184151937Sjkim *
185100966Siwasaki * FUNCTION:    AcpiDmBitList
186100966Siwasaki *
187100966Siwasaki * PARAMETERS:  Mask            - 16-bit value corresponding to 16 interrupt
188100966Siwasaki *                                or DMA values
189100966Siwasaki *
190100966Siwasaki * RETURN:      None
191100966Siwasaki *
192123315Snjl * DESCRIPTION: Dump a bit mask as a list of individual interrupt/DMA levels.
193100966Siwasaki *
194100966Siwasaki ******************************************************************************/
195100966Siwasaki
196100966Siwasakivoid
197100966SiwasakiAcpiDmBitList (
198100966Siwasaki    UINT16                  Mask)
199100966Siwasaki{
200100966Siwasaki    UINT32                  i;
201100966Siwasaki    BOOLEAN                 Previous = FALSE;
202100966Siwasaki
203100966Siwasaki
204100966Siwasaki    /* Open the initializer list */
205100966Siwasaki
206151937Sjkim    AcpiOsPrintf ("{");
207100966Siwasaki
208100966Siwasaki    /* Examine each bit */
209100966Siwasaki
210100966Siwasaki    for (i = 0; i < 16; i++)
211100966Siwasaki    {
212100966Siwasaki        /* Only interested in bits that are set to 1 */
213100966Siwasaki
214100966Siwasaki        if (Mask & 1)
215100966Siwasaki        {
216100966Siwasaki            if (Previous)
217100966Siwasaki            {
218100966Siwasaki                AcpiOsPrintf (",");
219100966Siwasaki            }
220100966Siwasaki            Previous = TRUE;
221209746Sjkim            AcpiOsPrintf ("%u", i);
222100966Siwasaki        }
223100966Siwasaki
224100966Siwasaki        Mask >>= 1;
225100966Siwasaki    }
226100966Siwasaki
227100966Siwasaki    /* Close list */
228100966Siwasaki
229100966Siwasaki    AcpiOsPrintf ("}\n");
230100966Siwasaki}
231100966Siwasaki
232100966Siwasaki
233100966Siwasaki/*******************************************************************************
234100966Siwasaki *
235151937Sjkim * FUNCTION:    AcpiDmResourceTemplate
236100966Siwasaki *
237100966Siwasaki * PARAMETERS:  Info            - Curent parse tree walk info
238100966Siwasaki *              ByteData        - Pointer to the byte list data
239100966Siwasaki *              ByteCount       - Length of the byte list
240100966Siwasaki *
241100966Siwasaki * RETURN:      None
242100966Siwasaki *
243151937Sjkim * DESCRIPTION: Dump the contents of a Resource Template containing a set of
244151937Sjkim *              Resource Descriptors.
245100966Siwasaki *
246100966Siwasaki ******************************************************************************/
247100966Siwasaki
248100966Siwasakivoid
249151937SjkimAcpiDmResourceTemplate (
250100966Siwasaki    ACPI_OP_WALK_INFO       *Info,
251167802Sjkim    ACPI_PARSE_OBJECT       *Op,
252100966Siwasaki    UINT8                   *ByteData,
253100966Siwasaki    UINT32                  ByteCount)
254100966Siwasaki{
255167802Sjkim    ACPI_STATUS             Status;
256193267Sjkim    UINT32                  CurrentByteOffset;
257151937Sjkim    UINT8                   ResourceType;
258151937Sjkim    UINT32                  ResourceLength;
259167802Sjkim    void                    *Aml;
260100966Siwasaki    UINT32                  Level;
261100966Siwasaki    BOOLEAN                 DependentFns = FALSE;
262167802Sjkim    UINT8                   ResourceIndex;
263167802Sjkim    ACPI_NAMESPACE_NODE     *Node;
264100966Siwasaki
265100966Siwasaki
266100966Siwasaki    Level = Info->Level;
267167802Sjkim    ResourceName = ACPI_DEFAULT_RESNAME;
268167802Sjkim    Node = Op->Common.Node;
269167802Sjkim    if (Node)
270167802Sjkim    {
271167802Sjkim        Node = Node->Child;
272167802Sjkim    }
273100966Siwasaki
274193267Sjkim    for (CurrentByteOffset = 0; CurrentByteOffset < ByteCount;)
275100966Siwasaki    {
276167802Sjkim        Aml = &ByteData[CurrentByteOffset];
277167802Sjkim
278151937Sjkim        /* Get the descriptor type and length */
279151937Sjkim
280167802Sjkim        ResourceType = AcpiUtGetResourceType (Aml);
281167802Sjkim        ResourceLength = AcpiUtGetResourceLength (Aml);
282100966Siwasaki
283167802Sjkim        /* Validate the Resource Type and Resource Length */
284100966Siwasaki
285167802Sjkim        Status = AcpiUtValidateResource (Aml, &ResourceIndex);
286167802Sjkim        if (ACPI_FAILURE (Status))
287167802Sjkim        {
288167802Sjkim            AcpiOsPrintf ("/*** Could not validate Resource, type (%X) %s***/\n",
289167802Sjkim                ResourceType, AcpiFormatException (Status));
290167802Sjkim            return;
291167802Sjkim        }
292167802Sjkim
293151937Sjkim        /* Point to next descriptor */
294100966Siwasaki
295167802Sjkim        CurrentByteOffset += AcpiUtGetDescriptorLength (Aml);
296100966Siwasaki
297151937Sjkim        /* Descriptor pre-processing */
298151937Sjkim
299151937Sjkim        switch (ResourceType)
300100966Siwasaki        {
301151937Sjkim        case ACPI_RESOURCE_NAME_START_DEPENDENT:
302100966Siwasaki
303100966Siwasaki            /* Finish a previous StartDependentFns */
304100966Siwasaki
305100966Siwasaki            if (DependentFns)
306100966Siwasaki            {
307100966Siwasaki                Level--;
308100966Siwasaki                AcpiDmIndent (Level);
309100966Siwasaki                AcpiOsPrintf ("}\n");
310100966Siwasaki            }
311100966Siwasaki            break;
312100966Siwasaki
313151937Sjkim        case ACPI_RESOURCE_NAME_END_DEPENDENT:
314100966Siwasaki
315100966Siwasaki            Level--;
316100966Siwasaki            DependentFns = FALSE;
317100966Siwasaki            break;
318100966Siwasaki
319151937Sjkim        case ACPI_RESOURCE_NAME_END_TAG:
320100966Siwasaki
321151937Sjkim            /* Normal exit, the resource list is finished */
322100966Siwasaki
323100966Siwasaki            if (DependentFns)
324100966Siwasaki            {
325100966Siwasaki                /*
326151937Sjkim                 * Close an open StartDependentDescriptor. This indicates a
327151937Sjkim                 * missing EndDependentDescriptor.
328100966Siwasaki                 */
329100966Siwasaki                Level--;
330100966Siwasaki                DependentFns = FALSE;
331100966Siwasaki
332151937Sjkim                /* Go ahead and insert EndDependentFn() */
333100966Siwasaki
334167802Sjkim                AcpiDmEndDependentDescriptor (Aml, ResourceLength, Level);
335151937Sjkim
336151937Sjkim                AcpiDmIndent (Level);
337151937Sjkim                AcpiOsPrintf (
338151937Sjkim                    "/*** Disassembler: inserted missing EndDependentFn () ***/\n");
339100966Siwasaki            }
340100966Siwasaki            return;
341100966Siwasaki
342151937Sjkim        default:
343100966Siwasaki            break;
344151937Sjkim        }
345100966Siwasaki
346167802Sjkim        /* Disassemble the resource structure */
347100966Siwasaki
348167802Sjkim        if (Node)
349151937Sjkim        {
350167802Sjkim            ResourceName = Node->Name.Integer;
351167802Sjkim            Node = Node->Peer;
352100966Siwasaki        }
353151937Sjkim
354193267Sjkim        AcpiGbl_DmResourceDispatch [ResourceIndex] (
355167802Sjkim            Aml, ResourceLength, Level);
356151937Sjkim
357151937Sjkim        /* Descriptor post-processing */
358151937Sjkim
359151937Sjkim        if (ResourceType == ACPI_RESOURCE_NAME_START_DEPENDENT)
360151937Sjkim        {
361151937Sjkim            DependentFns = TRUE;
362151937Sjkim            Level++;
363151937Sjkim        }
364100966Siwasaki    }
365100966Siwasaki}
366100966Siwasaki
367100966Siwasaki
368100966Siwasaki/*******************************************************************************
369100966Siwasaki *
370151937Sjkim * FUNCTION:    AcpiDmIsResourceTemplate
371100966Siwasaki *
372100966Siwasaki * PARAMETERS:  Op          - Buffer Op to be examined
373100966Siwasaki *
374167802Sjkim * RETURN:      Status. AE_OK if valid template
375100966Siwasaki *
376100966Siwasaki * DESCRIPTION: Walk a byte list to determine if it consists of a valid set
377100966Siwasaki *              of resource descriptors.  Nothing is output.
378100966Siwasaki *
379100966Siwasaki ******************************************************************************/
380100966Siwasaki
381167802SjkimACPI_STATUS
382151937SjkimAcpiDmIsResourceTemplate (
383100966Siwasaki    ACPI_PARSE_OBJECT       *Op)
384100966Siwasaki{
385167802Sjkim    ACPI_STATUS             Status;
386100966Siwasaki    ACPI_PARSE_OBJECT       *NextOp;
387167802Sjkim    UINT8                   *Aml;
388167802Sjkim    UINT8                   *EndAml;
389167802Sjkim    ACPI_SIZE               Length;
390100966Siwasaki
391100966Siwasaki
392100966Siwasaki    /* This op must be a buffer */
393100966Siwasaki
394100966Siwasaki    if (Op->Common.AmlOpcode != AML_BUFFER_OP)
395100966Siwasaki    {
396167802Sjkim        return (AE_TYPE);
397100966Siwasaki    }
398100966Siwasaki
399167802Sjkim    /* Get the ByteData list and length */
400100966Siwasaki
401100966Siwasaki    NextOp = Op->Common.Value.Arg;
402100966Siwasaki    NextOp = NextOp->Common.Next;
403100966Siwasaki    if (!NextOp)
404100966Siwasaki    {
405167802Sjkim        return (AE_TYPE);
406100966Siwasaki    }
407100966Siwasaki
408167802Sjkim    Aml = NextOp->Named.Data;
409167802Sjkim    Length = (ACPI_SIZE) NextOp->Common.Value.Integer;
410100966Siwasaki
411167802Sjkim    /* Walk the byte list, abort on any invalid descriptor type or length */
412100966Siwasaki
413167802Sjkim    Status = AcpiUtWalkAmlResources (Aml, Length, NULL, &EndAml);
414167802Sjkim    if (ACPI_FAILURE (Status))
415100966Siwasaki    {
416167802Sjkim        return (AE_TYPE);
417126372Snjl    }
418126372Snjl
419167802Sjkim    /*
420167802Sjkim     * For the resource template to be valid, one EndTag must appear
421167802Sjkim     * at the very end of the ByteList, not before. (For proper disassembly
422167802Sjkim     * of a ResourceTemplate, the buffer must not have any extra data after
423167802Sjkim     * the EndTag.)
424167802Sjkim     */
425167802Sjkim    if ((Aml + Length - sizeof (AML_RESOURCE_END_TAG)) != EndAml)
426100966Siwasaki    {
427167802Sjkim        return (AE_AML_NO_RESOURCE_END_TAG);
428100966Siwasaki    }
429100966Siwasaki
430167802Sjkim    /*
431167802Sjkim     * All resource descriptors are valid, therefore this list appears
432167802Sjkim     * to be a valid resource template
433167802Sjkim     */
434167802Sjkim    return (AE_OK);
435100966Siwasaki}
436100966Siwasaki
437100966Siwasaki#endif
438