dmresrc.c revision 217365
191621Sphantom/*******************************************************************************
291621Sphantom *
391621Sphantom * Module Name: dmresrc.c - Resource Descriptor disassembly
491621Sphantom *
591621Sphantom ******************************************************************************/
691621Sphantom
791621Sphantom/*
891621Sphantom * Copyright (C) 2000 - 2011, Intel Corp.
991621Sphantom * All rights reserved.
1091621Sphantom *
1191621Sphantom * Redistribution and use in source and binary forms, with or without
1291621Sphantom * modification, are permitted provided that the following conditions
1391621Sphantom * are met:
1491621Sphantom * 1. Redistributions of source code must retain the above copyright
1591621Sphantom *    notice, this list of conditions, and the following disclaimer,
1691621Sphantom *    without modification.
1791621Sphantom * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1891621Sphantom *    substantially similar to the "NO WARRANTY" disclaimer below
1991621Sphantom *    ("Disclaimer") and any redistribution must be conditioned upon
2091621Sphantom *    including a substantially similar Disclaimer requirement for further
2191621Sphantom *    binary redistribution.
2291621Sphantom * 3. Neither the names of the above-listed copyright holders nor the names
2391621Sphantom *    of any contributors may be used to endorse or promote products derived
2491621Sphantom *    from this software without specific prior written permission.
2591621Sphantom *
2691621Sphantom * Alternatively, this software may be distributed under the terms of the
2791621Sphantom * GNU General Public License ("GPL") version 2 as published by the Free
2891621Sphantom * Software Foundation.
2991621Sphantom *
3091621Sphantom * NO WARRANTY
3191621Sphantom * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3291621Sphantom * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3391621Sphantom * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3491621Sphantom * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3591621Sphantom * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3691621Sphantom * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3791621Sphantom * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3891621Sphantom * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3991621Sphantom * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4091632Sphantom * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4191621Sphantom * POSSIBILITY OF SUCH DAMAGES.
4291621Sphantom */
4391621Sphantom
4491621Sphantom
4591621Sphantom#include <contrib/dev/acpica/include/acpi.h>
4691621Sphantom#include <contrib/dev/acpica/include/accommon.h>
4791621Sphantom#include <contrib/dev/acpica/include/amlcode.h>
4891621Sphantom#include <contrib/dev/acpica/include/acdisasm.h>
4991621Sphantom
5091621Sphantom#ifdef ACPI_DISASSEMBLER
5191621Sphantom
5291621Sphantom#define _COMPONENT          ACPI_CA_DEBUGGER
5391628Sphantom        ACPI_MODULE_NAME    ("dbresrc")
5491628Sphantom
5591628Sphantom
5691628Sphantom/* Dispatch tables for Resource disassembly functions */
5791628Sphantom
5891628Sphantomtypedef
5991628Sphantomvoid (*ACPI_RESOURCE_HANDLER) (
6091621Sphantom    AML_RESOURCE            *Resource,
6191621Sphantom    UINT32                  Length,
6291621Sphantom    UINT32                  Level);
6391621Sphantom
6491628Sphantomstatic ACPI_RESOURCE_HANDLER    AcpiGbl_DmResourceDispatch [] =
6591621Sphantom{
6691632Sphantom    /* Small descriptors */
6791632Sphantom
6891632Sphantom    NULL,                           /* 0x00, Reserved */
6991632Sphantom    NULL,                           /* 0x01, Reserved */
7091621Sphantom    NULL,                           /* 0x02, Reserved */
7191621Sphantom    NULL,                           /* 0x03, Reserved */
7291621Sphantom    AcpiDmIrqDescriptor,            /* 0x04, ACPI_RESOURCE_NAME_IRQ_FORMAT */
7391621Sphantom    AcpiDmDmaDescriptor,            /* 0x05, ACPI_RESOURCE_NAME_DMA_FORMAT */
7491621Sphantom    AcpiDmStartDependentDescriptor, /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */
7591621Sphantom    AcpiDmEndDependentDescriptor,   /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */
7691621Sphantom    AcpiDmIoDescriptor,             /* 0x08, ACPI_RESOURCE_NAME_IO_PORT */
7791621Sphantom    AcpiDmFixedIoDescriptor,        /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO_PORT */
7891621Sphantom    NULL,                           /* 0x0A, Reserved */
7991621Sphantom    NULL,                           /* 0x0B, Reserved */
8091621Sphantom    NULL,                           /* 0x0C, Reserved */
8191621Sphantom    NULL,                           /* 0x0D, Reserved */
8291621Sphantom    AcpiDmVendorSmallDescriptor,    /* 0x0E, ACPI_RESOURCE_NAME_SMALL_VENDOR */
8391621Sphantom    NULL,                           /* 0x0F, ACPI_RESOURCE_NAME_END_TAG (not used) */
8491621Sphantom
8591621Sphantom    /* Large descriptors */
8691621Sphantom
8791621Sphantom    NULL,                           /* 0x00, Reserved */
8891621Sphantom    AcpiDmMemory24Descriptor,       /* 0x01, ACPI_RESOURCE_NAME_MEMORY_24 */
8991621Sphantom    AcpiDmGenericRegisterDescriptor,/* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */
9091621Sphantom    NULL,                           /* 0x03, Reserved */
9191621Sphantom    AcpiDmVendorLargeDescriptor,    /* 0x04, ACPI_RESOURCE_NAME_LARGE_VENDOR */
9291621Sphantom    AcpiDmMemory32Descriptor,       /* 0x05, ACPI_RESOURCE_NAME_MEMORY_32 */
9391632Sphantom    AcpiDmFixedMemory32Descriptor,  /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY_32 */
9491632Sphantom    AcpiDmDwordDescriptor,          /* 0x07, ACPI_RESOURCE_NAME_DWORD_ADDRESS_SPACE */
9591632Sphantom    AcpiDmWordDescriptor,           /* 0x08, ACPI_RESOURCE_NAME_WORD_ADDRESS_SPACE */
9691632Sphantom    AcpiDmInterruptDescriptor,      /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_XRUPT */
9791632Sphantom    AcpiDmQwordDescriptor,          /* 0x0A, ACPI_RESOURCE_NAME_QWORD_ADDRESS_SPACE */
9891632Sphantom    AcpiDmExtendedDescriptor        /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS_SPACE */
9991632Sphantom};
10091632Sphantom
10191632Sphantom
10291632Sphantom/* Only used for single-threaded applications */
10391621Sphantom/* TBD: remove when name is passed as parameter to the dump functions */
10491621Sphantom
10591621Sphantomstatic UINT32               ResourceName;
10691621Sphantom
10791621Sphantom
10891621Sphantom/*******************************************************************************
10991621Sphantom *
11091621Sphantom * FUNCTION:    AcpiDmDescriptorName
11191632Sphantom *
11291632Sphantom * PARAMETERS:  None
11391632Sphantom *
11491632Sphantom * RETURN:      None
11591632Sphantom *
11691632Sphantom * DESCRIPTION: Emit a name for the descriptor if one is present (indicated
11791621Sphantom *              by the name being changed from the default name.) A name is only
11891632Sphantom *              emitted if a reference to the descriptor has been made somewhere
11991621Sphantom *              in the original ASL code.
12091621Sphantom *
12191621Sphantom ******************************************************************************/
12291621Sphantom
12391621Sphantomvoid
12491621SphantomAcpiDmDescriptorName (
12591621Sphantom    void)
12691621Sphantom{
12791621Sphantom
12891621Sphantom    if (ResourceName == ACPI_DEFAULT_RESNAME)
12991621Sphantom    {
13091621Sphantom        return;
13191621Sphantom    }
13291621Sphantom
133    AcpiOsPrintf ("%4.4s", (char *) &ResourceName);
134}
135
136
137/*******************************************************************************
138 *
139 * FUNCTION:    AcpiDmDumpInteger*
140 *
141 * PARAMETERS:  Value               - Value to emit
142 *              Name                - Associated name (emitted as a comment)
143 *
144 * RETURN:      None
145 *
146 * DESCRIPTION: Integer output helper functions
147 *
148 ******************************************************************************/
149
150void
151AcpiDmDumpInteger8 (
152    UINT8                   Value,
153    char                    *Name)
154{
155    AcpiOsPrintf ("0x%2.2X,               // %s\n", Value, Name);
156}
157
158void
159AcpiDmDumpInteger16 (
160    UINT16                  Value,
161    char                    *Name)
162{
163    AcpiOsPrintf ("0x%4.4X,             // %s\n", Value, Name);
164}
165
166void
167AcpiDmDumpInteger32 (
168    UINT32                  Value,
169    char                    *Name)
170{
171    AcpiOsPrintf ("0x%8.8X,         // %s\n", Value, Name);
172}
173
174void
175AcpiDmDumpInteger64 (
176    UINT64                  Value,
177    char                    *Name)
178{
179    AcpiOsPrintf ("0x%8.8X%8.8X, // %s\n", ACPI_FORMAT_UINT64 (Value), Name);
180}
181
182
183/*******************************************************************************
184 *
185 * FUNCTION:    AcpiDmBitList
186 *
187 * PARAMETERS:  Mask            - 16-bit value corresponding to 16 interrupt
188 *                                or DMA values
189 *
190 * RETURN:      None
191 *
192 * DESCRIPTION: Dump a bit mask as a list of individual interrupt/DMA levels.
193 *
194 ******************************************************************************/
195
196void
197AcpiDmBitList (
198    UINT16                  Mask)
199{
200    UINT32                  i;
201    BOOLEAN                 Previous = FALSE;
202
203
204    /* Open the initializer list */
205
206    AcpiOsPrintf ("{");
207
208    /* Examine each bit */
209
210    for (i = 0; i < 16; i++)
211    {
212        /* Only interested in bits that are set to 1 */
213
214        if (Mask & 1)
215        {
216            if (Previous)
217            {
218                AcpiOsPrintf (",");
219            }
220            Previous = TRUE;
221            AcpiOsPrintf ("%u", i);
222        }
223
224        Mask >>= 1;
225    }
226
227    /* Close list */
228
229    AcpiOsPrintf ("}\n");
230}
231
232
233/*******************************************************************************
234 *
235 * FUNCTION:    AcpiDmResourceTemplate
236 *
237 * PARAMETERS:  Info            - Curent parse tree walk info
238 *              ByteData        - Pointer to the byte list data
239 *              ByteCount       - Length of the byte list
240 *
241 * RETURN:      None
242 *
243 * DESCRIPTION: Dump the contents of a Resource Template containing a set of
244 *              Resource Descriptors.
245 *
246 ******************************************************************************/
247
248void
249AcpiDmResourceTemplate (
250    ACPI_OP_WALK_INFO       *Info,
251    ACPI_PARSE_OBJECT       *Op,
252    UINT8                   *ByteData,
253    UINT32                  ByteCount)
254{
255    ACPI_STATUS             Status;
256    UINT32                  CurrentByteOffset;
257    UINT8                   ResourceType;
258    UINT32                  ResourceLength;
259    void                    *Aml;
260    UINT32                  Level;
261    BOOLEAN                 DependentFns = FALSE;
262    UINT8                   ResourceIndex;
263    ACPI_NAMESPACE_NODE     *Node;
264
265
266    Level = Info->Level;
267    ResourceName = ACPI_DEFAULT_RESNAME;
268    Node = Op->Common.Node;
269    if (Node)
270    {
271        Node = Node->Child;
272    }
273
274    for (CurrentByteOffset = 0; CurrentByteOffset < ByteCount;)
275    {
276        Aml = &ByteData[CurrentByteOffset];
277
278        /* Get the descriptor type and length */
279
280        ResourceType = AcpiUtGetResourceType (Aml);
281        ResourceLength = AcpiUtGetResourceLength (Aml);
282
283        /* Validate the Resource Type and Resource Length */
284
285        Status = AcpiUtValidateResource (Aml, &ResourceIndex);
286        if (ACPI_FAILURE (Status))
287        {
288            AcpiOsPrintf ("/*** Could not validate Resource, type (%X) %s***/\n",
289                ResourceType, AcpiFormatException (Status));
290            return;
291        }
292
293        /* Point to next descriptor */
294
295        CurrentByteOffset += AcpiUtGetDescriptorLength (Aml);
296
297        /* Descriptor pre-processing */
298
299        switch (ResourceType)
300        {
301        case ACPI_RESOURCE_NAME_START_DEPENDENT:
302
303            /* Finish a previous StartDependentFns */
304
305            if (DependentFns)
306            {
307                Level--;
308                AcpiDmIndent (Level);
309                AcpiOsPrintf ("}\n");
310            }
311            break;
312
313        case ACPI_RESOURCE_NAME_END_DEPENDENT:
314
315            Level--;
316            DependentFns = FALSE;
317            break;
318
319        case ACPI_RESOURCE_NAME_END_TAG:
320
321            /* Normal exit, the resource list is finished */
322
323            if (DependentFns)
324            {
325                /*
326                 * Close an open StartDependentDescriptor. This indicates a
327                 * missing EndDependentDescriptor.
328                 */
329                Level--;
330                DependentFns = FALSE;
331
332                /* Go ahead and insert EndDependentFn() */
333
334                AcpiDmEndDependentDescriptor (Aml, ResourceLength, Level);
335
336                AcpiDmIndent (Level);
337                AcpiOsPrintf (
338                    "/*** Disassembler: inserted missing EndDependentFn () ***/\n");
339            }
340            return;
341
342        default:
343            break;
344        }
345
346        /* Disassemble the resource structure */
347
348        if (Node)
349        {
350            ResourceName = Node->Name.Integer;
351            Node = Node->Peer;
352        }
353
354        AcpiGbl_DmResourceDispatch [ResourceIndex] (
355            Aml, ResourceLength, Level);
356
357        /* Descriptor post-processing */
358
359        if (ResourceType == ACPI_RESOURCE_NAME_START_DEPENDENT)
360        {
361            DependentFns = TRUE;
362            Level++;
363        }
364    }
365}
366
367
368/*******************************************************************************
369 *
370 * FUNCTION:    AcpiDmIsResourceTemplate
371 *
372 * PARAMETERS:  Op          - Buffer Op to be examined
373 *
374 * RETURN:      Status. AE_OK if valid template
375 *
376 * DESCRIPTION: Walk a byte list to determine if it consists of a valid set
377 *              of resource descriptors.  Nothing is output.
378 *
379 ******************************************************************************/
380
381ACPI_STATUS
382AcpiDmIsResourceTemplate (
383    ACPI_PARSE_OBJECT       *Op)
384{
385    ACPI_STATUS             Status;
386    ACPI_PARSE_OBJECT       *NextOp;
387    UINT8                   *Aml;
388    UINT8                   *EndAml;
389    ACPI_SIZE               Length;
390
391
392    /* This op must be a buffer */
393
394    if (Op->Common.AmlOpcode != AML_BUFFER_OP)
395    {
396        return (AE_TYPE);
397    }
398
399    /* Get the ByteData list and length */
400
401    NextOp = Op->Common.Value.Arg;
402    NextOp = NextOp->Common.Next;
403    if (!NextOp)
404    {
405        return (AE_TYPE);
406    }
407
408    Aml = NextOp->Named.Data;
409    Length = (ACPI_SIZE) NextOp->Common.Value.Integer;
410
411    /* Walk the byte list, abort on any invalid descriptor type or length */
412
413    Status = AcpiUtWalkAmlResources (Aml, Length, NULL, &EndAml);
414    if (ACPI_FAILURE (Status))
415    {
416        return (AE_TYPE);
417    }
418
419    /*
420     * For the resource template to be valid, one EndTag must appear
421     * at the very end of the ByteList, not before. (For proper disassembly
422     * of a ResourceTemplate, the buffer must not have any extra data after
423     * the EndTag.)
424     */
425    if ((Aml + Length - sizeof (AML_RESOURCE_END_TAG)) != EndAml)
426    {
427        return (AE_AML_NO_RESOURCE_END_TAG);
428    }
429
430    /*
431     * All resource descriptors are valid, therefore this list appears
432     * to be a valid resource template
433     */
434    return (AE_OK);
435}
436
437#endif
438