Subversion Repositories Kolibri OS

Rev

Rev 1498 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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 - 2011, 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 "acpi.h"
  118. #include "accommon.h"
  119. #include "acparser.h"
  120. #include "acdisasm.h"
  121. #include "acnamesp.h"
  122. #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.         Node = Node->Peer;
  553.     }
  554.  
  555.     return (NULL);
  556. }
  557.  
  558.  
  559. /*******************************************************************************
  560.  *
  561.  * FUNCTION:    AcpiGetTagPathname
  562.  *
  563.  * PARAMETERS:  BufferNode          - Node for the parent buffer
  564.  *              ResourceNode        - Node for a resource descriptor
  565.  *              BitIndex            - Index into the resource descriptor
  566.  *
  567.  * RETURN:      Full pathname for a resource tag. NULL if no match.
  568.  *              Path is returned in AML (packed) format.
  569.  *
  570.  * DESCRIPTION: Convert a BitIndex into a symbolic resource tag (full pathname)
  571.  *
  572.  ******************************************************************************/
  573.  
  574. static char *
  575. AcpiGetTagPathname (
  576.     ACPI_NAMESPACE_NODE     *BufferNode,
  577.     ACPI_NAMESPACE_NODE     *ResourceNode,
  578.     UINT32                  BitIndex)
  579. {
  580.     ACPI_STATUS             Status;
  581.     UINT32                  ResourceBitIndex;
  582.     UINT8                   ResourceTableIndex;
  583.     ACPI_SIZE               RequiredSize;
  584.     char                    *Pathname;
  585.     AML_RESOURCE            *Aml;
  586.     ACPI_PARSE_OBJECT       *Op;
  587.     char                    *InternalPath;
  588.     char                    *Tag;
  589.  
  590.  
  591.     /* Get the Op that contains the actual buffer data */
  592.  
  593.     Op = BufferNode->Op->Common.Value.Arg;
  594.     Op = Op->Common.Next;
  595.     if (!Op)
  596.     {
  597.         return (NULL);
  598.     }
  599.  
  600.     /* Get the individual resource descriptor and validate it */
  601.  
  602.     Aml = ACPI_CAST_PTR (AML_RESOURCE,
  603.             &Op->Named.Data[ResourceNode->Value]);
  604.  
  605.     Status = AcpiUtValidateResource (Aml, &ResourceTableIndex);
  606.     if (ACPI_FAILURE (Status))
  607.     {
  608.         return (NULL);
  609.     }
  610.  
  611.     /* Get offset into this descriptor (from offset into entire buffer) */
  612.  
  613.     ResourceBitIndex = BitIndex - ACPI_MUL_8 (ResourceNode->Value);
  614.  
  615.     /* Get the tag associated with this resource descriptor and offset */
  616.  
  617.     Tag = AcpiDmGetResourceTag (ResourceBitIndex, Aml, ResourceTableIndex);
  618.     if (!Tag)
  619.     {
  620.         return (NULL);
  621.     }
  622.  
  623.     /*
  624.      * Now that we know that we have a reference that can be converted to a
  625.      * symbol, change the name of the resource to a unique name.
  626.      */
  627.     AcpiDmUpdateResourceName (ResourceNode);
  628.  
  629.     /* Get the full pathname to the parent buffer */
  630.  
  631.     RequiredSize = AcpiNsGetPathnameLength (BufferNode);
  632.     if (!RequiredSize)
  633.     {
  634.         return (NULL);
  635.     }
  636.  
  637.     Pathname = ACPI_ALLOCATE_ZEROED (RequiredSize + ACPI_PATH_SEGMENT_LENGTH);
  638.     if (!Pathname)
  639.     {
  640.         return (NULL);
  641.     }
  642.  
  643.     Status = AcpiNsBuildExternalPath (BufferNode, RequiredSize, Pathname);
  644.     if (ACPI_FAILURE (Status))
  645.     {
  646.         return (NULL);
  647.     }
  648.  
  649.     /*
  650.      * Create the full path to the resource and tag by: remove the buffer name,
  651.      * append the resource descriptor name, append a dot, append the tag name.
  652.      *
  653.      * TBD: Always using the full path is a bit brute force, the path can be
  654.      * often be optimized with carats (if the original buffer namepath is a
  655.      * single nameseg). This doesn't really matter, because these paths do not
  656.      * end up in the final compiled AML, it's just an appearance issue for the
  657.      * disassembled code.
  658.      */
  659.     Pathname[ACPI_STRLEN (Pathname) - ACPI_NAME_SIZE] = 0;
  660.     ACPI_STRNCAT (Pathname, ResourceNode->Name.Ascii, ACPI_NAME_SIZE);
  661.     ACPI_STRCAT (Pathname, ".");
  662.     ACPI_STRNCAT (Pathname, Tag, ACPI_NAME_SIZE);
  663.  
  664.     /* Internalize the namepath to AML format */
  665.  
  666.     AcpiNsInternalizeName (Pathname, &InternalPath);
  667.     ACPI_FREE (Pathname);
  668.     return (InternalPath);
  669. }
  670.  
  671.  
  672. /*******************************************************************************
  673.  *
  674.  * FUNCTION:    AcpiDmUpdateResourceName
  675.  *
  676.  * PARAMETERS:  ResourceNode        - Node for a resource descriptor
  677.  *
  678.  * RETURN:      Stores new name in the ResourceNode
  679.  *
  680.  * DESCRIPTION: Create a new, unique name for a resource descriptor. Used by
  681.  *              both the disassembly of the descriptor itself and any symbolic
  682.  *              references to the descriptor. Ignored if a unique name has
  683.  *              already been assigned to the resource.
  684.  *
  685.  * NOTE: Single threaded, suitable for applications only!
  686.  *
  687.  ******************************************************************************/
  688.  
  689. static void
  690. AcpiDmUpdateResourceName (
  691.     ACPI_NAMESPACE_NODE     *ResourceNode)
  692. {
  693.     char                    Name[ACPI_NAME_SIZE];
  694.  
  695.  
  696.     /* Ignore if a unique name has already been assigned */
  697.  
  698.     if (ResourceNode->Name.Integer != ACPI_DEFAULT_RESNAME)
  699.     {
  700.         return;
  701.     }
  702.  
  703.     /* Generate a new ACPI name for the descriptor */
  704.  
  705.     Name[0] = '_';
  706.     Name[1] = AcpiGbl_Prefix[AcpiGbl_NextPrefix];
  707.     Name[2] = AcpiUtHexToAsciiChar ((UINT64) AcpiGbl_NextResourceId, 4);
  708.     Name[3] = AcpiUtHexToAsciiChar ((UINT64) AcpiGbl_NextResourceId, 0);
  709.  
  710.     /* Update globals for next name */
  711.  
  712.     AcpiGbl_NextResourceId++;
  713.     if (AcpiGbl_NextResourceId >= 256)
  714.     {
  715.         AcpiGbl_NextResourceId = 0;
  716.         AcpiGbl_NextPrefix++;
  717.         if (AcpiGbl_NextPrefix > ACPI_NUM_RES_PREFIX)
  718.         {
  719.             AcpiGbl_NextPrefix = 0;
  720.         }
  721.     }
  722.  
  723.     /* Change the resource descriptor name */
  724.  
  725.     ResourceNode->Name.Integer = *ACPI_CAST_PTR (UINT32, &Name[0]);
  726. }
  727.  
  728.  
  729. /*******************************************************************************
  730.  *
  731.  * FUNCTION:    AcpiDmGetResourceTag
  732.  *
  733.  * PARAMETERS:  BitIndex            - Index into the resource descriptor
  734.  *              Resource            - Pointer to the raw resource data
  735.  *              ResourceIndex       - Index correspoinding to the resource type
  736.  *
  737.  * RETURN:      Pointer to the resource tag (ACPI_NAME). NULL if no match.
  738.  *
  739.  * DESCRIPTION: Convert a BitIndex into a symbolic resource tag.
  740.  *
  741.  ******************************************************************************/
  742.  
  743. static char *
  744. AcpiDmGetResourceTag (
  745.     UINT32                  BitIndex,
  746.     AML_RESOURCE            *Resource,
  747.     UINT8                   ResourceIndex)
  748. {
  749.     ACPI_RESOURCE_TAG       *TagList;
  750.     char                    *Tag = NULL;
  751.  
  752.  
  753.     /* Get the tag list for this resource descriptor type */
  754.  
  755.     TagList = AcpiGbl_ResourceTags[ResourceIndex];
  756.     if (!TagList)
  757.     {
  758.         /* There are no tags for this resource type */
  759.  
  760.         return (NULL);
  761.     }
  762.  
  763.     /*
  764.      * Handle the type-specific flags field for the address descriptors.
  765.      * Kindof brute force, but just blindly search for an index match.
  766.      */
  767.     switch (Resource->DescriptorType)
  768.     {
  769.     case ACPI_RESOURCE_NAME_ADDRESS16:
  770.     case ACPI_RESOURCE_NAME_ADDRESS32:
  771.     case ACPI_RESOURCE_NAME_ADDRESS64:
  772.     case ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64:
  773.  
  774.         if (Resource->Address.ResourceType == ACPI_ADDRESS_TYPE_MEMORY_RANGE)
  775.         {
  776.             Tag = AcpiDmSearchTagList (BitIndex, AcpiDmMemoryFlagTags);
  777.         }
  778.         else if (Resource->Address.ResourceType == ACPI_ADDRESS_TYPE_IO_RANGE)
  779.         {
  780.             Tag = AcpiDmSearchTagList (BitIndex, AcpiDmIoFlagTags);
  781.         }
  782.  
  783.         /* If we found a match, all done. Else, drop to normal search below */
  784.  
  785.         if (Tag)
  786.         {
  787.             return (Tag);
  788.         }
  789.         break;
  790.  
  791.     default:
  792.         break;
  793.     }
  794.  
  795.     /* Search the tag list for this descriptor type */
  796.  
  797.     Tag = AcpiDmSearchTagList (BitIndex, TagList);
  798.     return (Tag);
  799. }
  800.  
  801.  
  802. /*******************************************************************************
  803.  *
  804.  * FUNCTION:    AcpiDmSearchTagList
  805.  *
  806.  * PARAMETERS:  BitIndex            - Index into the resource descriptor
  807.  *              TagList             - List to search
  808.  *
  809.  * RETURN:      Pointer to a tag (ACPI_NAME). NULL if no match found.
  810.  *
  811.  * DESCRIPTION: Search a tag list for a match to the input BitIndex. Matches
  812.  *              a fixed offset to a symbolic resource tag name.
  813.  *
  814.  ******************************************************************************/
  815.  
  816. static char *
  817. AcpiDmSearchTagList (
  818.     UINT32                  BitIndex,
  819.     ACPI_RESOURCE_TAG       *TagList)
  820. {
  821.  
  822.     /*
  823.      * Walk the null-terminated tag list to find a matching bit offset.
  824.      * We are looking for an exact match.
  825.      */
  826.     for ( ; TagList->Tag; TagList++)
  827.     {
  828.         if (BitIndex == TagList->BitIndex)
  829.         {
  830.             return (TagList->Tag);
  831.         }
  832.     }
  833.  
  834.     /* A matching offset was not found */
  835.  
  836.     return (NULL);
  837. }
  838.  
  839.  
  840. /*******************************************************************************
  841.  *
  842.  * FUNCTION:    AcpiDmFindResources
  843.  *
  844.  * PARAMETERS:  Root                - Root of the parse tree
  845.  *
  846.  * RETURN:      None
  847.  *
  848.  * DESCRIPTION: Add all ResourceTemplate declarations to the namespace. Each
  849.  *              resource descriptor in each template is given a node -- used
  850.  *              for later conversion of resource references to symbolic refs.
  851.  *
  852.  ******************************************************************************/
  853.  
  854. void
  855. AcpiDmFindResources (
  856.     ACPI_PARSE_OBJECT       *Root)
  857. {
  858.     ACPI_PARSE_OBJECT       *Op = Root;
  859.     ACPI_PARSE_OBJECT       *Parent;
  860.  
  861.  
  862.     /* Walk the entire parse tree */
  863.  
  864.     while (Op)
  865.     {
  866.         /* We are interested in Buffer() declarations */
  867.  
  868.         if (Op->Common.AmlOpcode == AML_BUFFER_OP)
  869.         {
  870.             /* And only declarations of the form Name (XXXX, Buffer()... ) */
  871.  
  872.             Parent = Op->Common.Parent;
  873.             if (Parent->Common.AmlOpcode == AML_NAME_OP)
  874.             {
  875.                 /*
  876.                  * If the buffer is a resource template, add the individual
  877.                  * resource descriptors to the namespace, as children of the
  878.                  * buffer node.
  879.                  */
  880.                 if (ACPI_SUCCESS (AcpiDmIsResourceTemplate (Op)))
  881.                 {
  882.                     Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
  883.                     AcpiDmAddResourcesToNamespace (Parent->Common.Node, Op);
  884.                 }
  885.             }
  886.         }
  887.  
  888.         Op = AcpiPsGetDepthNext (Root, Op);
  889.     }
  890. }
  891.  
  892.  
  893. /*******************************************************************************
  894.  *
  895.  * FUNCTION:    AcpiDmAddResourcesToNamespace
  896.  *
  897.  * PARAMETERS:  BufferNode          - Node for the parent buffer
  898.  *              Op                  - Parse op for the buffer
  899.  *
  900.  * RETURN:      None
  901.  *
  902.  * DESCRIPTION: Add an entire resource template to the namespace. Each
  903.  *              resource descriptor is added as a namespace node.
  904.  *
  905.  ******************************************************************************/
  906.  
  907. static void
  908. AcpiDmAddResourcesToNamespace (
  909.     ACPI_NAMESPACE_NODE     *BufferNode,
  910.     ACPI_PARSE_OBJECT       *Op)
  911. {
  912.     ACPI_PARSE_OBJECT       *NextOp;
  913.  
  914.  
  915.     /* Get to the ByteData list */
  916.  
  917.     NextOp = Op->Common.Value.Arg;
  918.     NextOp = NextOp->Common.Next;
  919.     if (!NextOp)
  920.     {
  921.         return;
  922.     }
  923.  
  924.     /* Set Node and Op to point to each other */
  925.  
  926.     BufferNode->Op = Op;
  927.     Op->Common.Node = BufferNode;
  928.  
  929.     /*
  930.      * Insert each resource into the namespace
  931.      * NextOp contains the Aml pointer and the Aml length
  932.      */
  933.     AcpiUtWalkAmlResources ((UINT8 *) NextOp->Named.Data,
  934.         (ACPI_SIZE) NextOp->Common.Value.Integer,
  935.         AcpiDmAddResourceToNamespace, BufferNode);
  936. }
  937.  
  938.  
  939. /*******************************************************************************
  940.  *
  941.  * FUNCTION:    AcpiDmAddResourceToNamespace
  942.  *
  943.  * PARAMETERS:  ACPI_WALK_AML_CALLBACK
  944.  *              BufferNode              - Node for the parent buffer
  945.  *
  946.  * RETURN:      Status
  947.  *
  948.  * DESCRIPTION: Add one resource descriptor to the namespace as a child of the
  949.  *              parent buffer. The same name is used for each descriptor. This
  950.  *              is changed later to a unique name if the resource is actually
  951.  *              referenced by an AML operator.
  952.  *
  953.  ******************************************************************************/
  954.  
  955. static ACPI_STATUS
  956. AcpiDmAddResourceToNamespace (
  957.     UINT8                   *Aml,
  958.     UINT32                  Length,
  959.     UINT32                  Offset,
  960.     UINT8                   ResourceIndex,
  961.     void                    *Context)
  962. {
  963.     ACPI_STATUS             Status;
  964.     ACPI_GENERIC_STATE      ScopeInfo;
  965.     ACPI_NAMESPACE_NODE     *Node;
  966.  
  967.  
  968.     /* TBD: Don't need to add descriptors that have no tags defined? */
  969.  
  970.     /* Add the resource to the namespace, as child of the buffer */
  971.  
  972.     ScopeInfo.Scope.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Context);
  973.     Status = AcpiNsLookup (&ScopeInfo, "_TMP", ACPI_TYPE_LOCAL_RESOURCE,
  974.                 ACPI_IMODE_LOAD_PASS2,
  975.                 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_PREFIX_IS_SCOPE,
  976.                 NULL, &Node);
  977.     if (ACPI_FAILURE (Status))
  978.     {
  979.         return (AE_OK);
  980.     }
  981.  
  982.     /* Set the name to the default, changed later if resource is referenced */
  983.  
  984.     Node->Name.Integer = ACPI_DEFAULT_RESNAME;
  985.  
  986.     /* Save the offset of the descriptor (within the original buffer) */
  987.  
  988.     Node->Value = Offset;
  989.     Node->Length = Length;
  990.     return (AE_OK);
  991. }
  992.  
  993.