1272286Sjkim/******************************************************************************
2272286Sjkim *
3272286Sjkim * Module Name: aslmaputils - Utilities for the resource descriptor/device maps
4272286Sjkim *
5272286Sjkim *****************************************************************************/
6272286Sjkim
7272286Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
9272286Sjkim * All rights reserved.
10272286Sjkim *
11272286Sjkim * Redistribution and use in source and binary forms, with or without
12272286Sjkim * modification, are permitted provided that the following conditions
13272286Sjkim * are met:
14272286Sjkim * 1. Redistributions of source code must retain the above copyright
15272286Sjkim *    notice, this list of conditions, and the following disclaimer,
16272286Sjkim *    without modification.
17272286Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18272286Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19272286Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20272286Sjkim *    including a substantially similar Disclaimer requirement for further
21272286Sjkim *    binary redistribution.
22272286Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23272286Sjkim *    of any contributors may be used to endorse or promote products derived
24272286Sjkim *    from this software without specific prior written permission.
25272286Sjkim *
26272286Sjkim * Alternatively, this software may be distributed under the terms of the
27272286Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28272286Sjkim * Software Foundation.
29272286Sjkim *
30272286Sjkim * NO WARRANTY
31272286Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32272286Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33272286Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34272286Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35272286Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36272286Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37272286Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38272286Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39272286Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40272286Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41272286Sjkim * POSSIBILITY OF SUCH DAMAGES.
42272286Sjkim */
43272286Sjkim
44272444Sjkim#include <contrib/dev/acpica/include/acpi.h>
45272444Sjkim#include <contrib/dev/acpica/include/accommon.h>
46272444Sjkim#include <contrib/dev/acpica/include/acapps.h>
47272444Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
48272286Sjkim#include "aslcompiler.y.h"
49272444Sjkim#include <contrib/dev/acpica/include/acinterp.h>
50272444Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
51272444Sjkim#include <contrib/dev/acpica/include/amlcode.h>
52272286Sjkim
53272286Sjkim/* This module used for application-level code only */
54272286Sjkim
55272286Sjkim#define _COMPONENT          ACPI_COMPILER
56272286Sjkim        ACPI_MODULE_NAME    ("aslmaputils")
57272286Sjkim
58272286Sjkim
59272286Sjkim/*******************************************************************************
60272286Sjkim *
61272286Sjkim * FUNCTION:    MpGetHidFromParseTree
62272286Sjkim *
63272286Sjkim * PARAMETERS:  HidNode             - Node for a _HID object
64272286Sjkim *
65272286Sjkim * RETURN:      An _HID string value. Automatically converts _HID integers
66272286Sjkim *              to strings. Never NULL.
67272286Sjkim *
68272286Sjkim * DESCRIPTION: Extract a _HID value from the parse tree, not the namespace.
69272286Sjkim *              Used when a fully initialized namespace is not available.
70272286Sjkim *
71272286Sjkim ******************************************************************************/
72272286Sjkim
73272286Sjkimchar *
74272286SjkimMpGetHidFromParseTree (
75272286Sjkim    ACPI_NAMESPACE_NODE     *HidNode)
76272286Sjkim{
77272286Sjkim    ACPI_PARSE_OBJECT       *Op;
78272286Sjkim    ACPI_PARSE_OBJECT       *Arg;
79272286Sjkim    char                    *HidString;
80272286Sjkim
81272286Sjkim
82272286Sjkim    Op = HidNode->Op;
83272286Sjkim
84272286Sjkim    switch (Op->Asl.ParseOpcode)
85272286Sjkim    {
86272286Sjkim    case PARSEOP_NAME:
87272286Sjkim
88272286Sjkim        Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
89272286Sjkim        Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
90272286Sjkim
91272286Sjkim        switch (Arg->Asl.ParseOpcode)
92272286Sjkim        {
93272286Sjkim        case PARSEOP_STRING_LITERAL:
94272286Sjkim
95272286Sjkim            return (Arg->Asl.Value.String);
96272286Sjkim
97272286Sjkim        case PARSEOP_INTEGER:
98272286Sjkim
99272286Sjkim            /* Convert EISAID to a string */
100272286Sjkim
101272286Sjkim            HidString = UtStringCacheCalloc (ACPI_EISAID_STRING_SIZE);
102272286Sjkim            AcpiExEisaIdToString (HidString, Arg->Asl.Value.Integer);
103272286Sjkim            return (HidString);
104272286Sjkim
105272286Sjkim        default:
106272286Sjkim
107272286Sjkim            return ("UNKNOWN");
108272286Sjkim        }
109272286Sjkim
110272286Sjkim    default:
111272286Sjkim        return ("-No HID-");
112272286Sjkim    }
113272286Sjkim}
114272286Sjkim
115272286Sjkim
116272286Sjkim/*******************************************************************************
117272286Sjkim *
118272286Sjkim * FUNCTION:    MpGetHidValue
119272286Sjkim *
120272286Sjkim * PARAMETERS:  DeviceNode          - Node for parent device
121272286Sjkim *
122272286Sjkim * RETURN:      An _HID string value. Automatically converts _HID integers
123272286Sjkim *              to strings. Never NULL.
124272286Sjkim *
125272286Sjkim * DESCRIPTION: Extract _HID value from within a device scope. Does not
126272286Sjkim *              actually execute a method, just gets the string or integer
127272286Sjkim *              value for the _HID.
128272286Sjkim *
129272286Sjkim ******************************************************************************/
130272286Sjkim
131272286Sjkimchar *
132272286SjkimMpGetHidValue (
133272286Sjkim    ACPI_NAMESPACE_NODE     *DeviceNode)
134272286Sjkim{
135272286Sjkim    ACPI_NAMESPACE_NODE     *HidNode;
136272286Sjkim    char                    *HidString;
137272286Sjkim    ACPI_STATUS             Status;
138272286Sjkim
139272286Sjkim
140272286Sjkim    Status = AcpiNsGetNode (DeviceNode, METHOD_NAME__HID,
141272286Sjkim        ACPI_NS_NO_UPSEARCH, &HidNode);
142272286Sjkim    if (ACPI_FAILURE (Status))
143272286Sjkim    {
144272286Sjkim        goto ErrorExit;
145272286Sjkim    }
146272286Sjkim
147272286Sjkim    /* If only partial namespace, get the _HID from the parse tree */
148272286Sjkim
149272286Sjkim    if (!HidNode->Object)
150272286Sjkim    {
151272286Sjkim        return (MpGetHidFromParseTree (HidNode));
152272286Sjkim    }
153272286Sjkim
154272286Sjkim    /* Handle the different _HID flavors */
155272286Sjkim
156272286Sjkim    switch (HidNode->Type)
157272286Sjkim    {
158272286Sjkim    case ACPI_TYPE_STRING:
159272286Sjkim
160272286Sjkim        return (HidNode->Object->String.Pointer);
161272286Sjkim
162272286Sjkim    case ACPI_TYPE_INTEGER:
163272286Sjkim
164272286Sjkim        /* Convert EISAID to a string */
165272286Sjkim
166272286Sjkim        HidString = UtStringCacheCalloc (ACPI_EISAID_STRING_SIZE);
167272286Sjkim        AcpiExEisaIdToString (HidString, HidNode->Object->Integer.Value);
168272286Sjkim        return (HidString);
169272286Sjkim
170272286Sjkim    case ACPI_TYPE_METHOD:
171272286Sjkim
172272286Sjkim        return ("-Method-");
173272286Sjkim
174272286Sjkim    default:
175272286Sjkim
176272286Sjkim        FlPrintFile (ASL_FILE_MAP_OUTPUT, "BAD HID TYPE: %u", HidNode->Type);
177272286Sjkim        break;
178272286Sjkim    }
179272286Sjkim
180272286Sjkim
181272286SjkimErrorExit:
182272286Sjkim    return ("-No HID-");
183272286Sjkim}
184272286Sjkim
185272286Sjkim
186272286Sjkim/*******************************************************************************
187272286Sjkim *
188272286Sjkim * FUNCTION:    MpGetHidViaNamestring
189272286Sjkim *
190272286Sjkim * PARAMETERS:  DeviceName          - Namepath for parent device
191272286Sjkim *
192272286Sjkim * RETURN:      _HID string. Never NULL.
193272286Sjkim *
194272286Sjkim * DESCRIPTION: Get a _HID value via a device pathname (instead of just simply
195272286Sjkim *              a device node.)
196272286Sjkim *
197272286Sjkim ******************************************************************************/
198272286Sjkim
199272286Sjkimchar *
200272286SjkimMpGetHidViaNamestring (
201272286Sjkim    char                    *DeviceName)
202272286Sjkim{
203272286Sjkim    ACPI_NAMESPACE_NODE     *DeviceNode;
204272286Sjkim    ACPI_STATUS             Status;
205272286Sjkim
206272286Sjkim
207272286Sjkim    Status = AcpiNsGetNode (NULL, DeviceName, ACPI_NS_NO_UPSEARCH,
208272286Sjkim        &DeviceNode);
209272286Sjkim    if (ACPI_FAILURE (Status))
210272286Sjkim    {
211272286Sjkim        goto ErrorExit;
212272286Sjkim    }
213272286Sjkim
214272286Sjkim    return (MpGetHidValue (DeviceNode));
215272286Sjkim
216272286Sjkim
217272286SjkimErrorExit:
218272286Sjkim    return ("-No HID-");
219272286Sjkim}
220272286Sjkim
221272286Sjkim
222272286Sjkim/*******************************************************************************
223272286Sjkim *
224272286Sjkim * FUNCTION:    MpGetParentDeviceHid
225272286Sjkim *
226272286Sjkim * PARAMETERS:  Op                      - Parse Op to be examined
227272286Sjkim *              TargetNode              - Where the field node is returned
228272286Sjkim *              ParentDeviceName        - Where the node path is returned
229272286Sjkim *
230272286Sjkim * RETURN:      _HID string. Never NULL.
231272286Sjkim *
232272286Sjkim * DESCRIPTION: Find the parent Device or Scope Op, get the full pathname to
233272286Sjkim *              the parent, and get the _HID associated with the parent.
234272286Sjkim *
235272286Sjkim ******************************************************************************/
236272286Sjkim
237272286Sjkimchar *
238272286SjkimMpGetParentDeviceHid (
239272286Sjkim    ACPI_PARSE_OBJECT       *Op,
240272286Sjkim    ACPI_NAMESPACE_NODE     **TargetNode,
241272286Sjkim    char                    **ParentDeviceName)
242272286Sjkim{
243272286Sjkim    ACPI_NAMESPACE_NODE     *DeviceNode;
244272286Sjkim
245272286Sjkim
246272286Sjkim    /* Find parent Device() or Scope() Op */
247272286Sjkim
248272286Sjkim    while (Op &&
249272286Sjkim        (Op->Asl.AmlOpcode != AML_DEVICE_OP) &&
250272286Sjkim        (Op->Asl.AmlOpcode != AML_SCOPE_OP))
251272286Sjkim    {
252272286Sjkim        Op = Op->Asl.Parent;
253272286Sjkim    }
254272286Sjkim
255272286Sjkim    if (!Op)
256272286Sjkim    {
257272286Sjkim        FlPrintFile (ASL_FILE_MAP_OUTPUT, " No_Parent_Device ");
258272286Sjkim        goto ErrorExit;
259272286Sjkim    }
260272286Sjkim
261272286Sjkim    /* Get the full pathname to the device and the _HID */
262272286Sjkim
263272286Sjkim    DeviceNode = Op->Asl.Node;
264272286Sjkim    if (!DeviceNode)
265272286Sjkim    {
266272286Sjkim        FlPrintFile (ASL_FILE_MAP_OUTPUT, " No_Device_Node ");
267272286Sjkim        goto ErrorExit;
268272286Sjkim    }
269272286Sjkim
270272286Sjkim    *ParentDeviceName = AcpiNsGetExternalPathname (DeviceNode);
271272286Sjkim    return (MpGetHidValue (DeviceNode));
272272286Sjkim
273272286Sjkim
274272286SjkimErrorExit:
275272286Sjkim    return ("-No HID-");
276272286Sjkim}
277272286Sjkim
278272286Sjkim
279272286Sjkim/*******************************************************************************
280272286Sjkim *
281272286Sjkim * FUNCTION:    MpGetDdnValue
282272286Sjkim *
283272286Sjkim * PARAMETERS:  DeviceName          - Namepath for parent device
284272286Sjkim *
285272286Sjkim * RETURN:      _DDN description string. NULL on failure.
286272286Sjkim *
287272286Sjkim * DESCRIPTION: Execute the _DDN method for the device.
288272286Sjkim *
289272286Sjkim ******************************************************************************/
290272286Sjkim
291272286Sjkimchar *
292272286SjkimMpGetDdnValue (
293272286Sjkim    char                    *DeviceName)
294272286Sjkim{
295272286Sjkim    ACPI_NAMESPACE_NODE     *DeviceNode;
296272286Sjkim    ACPI_NAMESPACE_NODE     *DdnNode;
297272286Sjkim    ACPI_STATUS             Status;
298272286Sjkim
299272286Sjkim
300272286Sjkim    Status = AcpiNsGetNode (NULL, DeviceName, ACPI_NS_NO_UPSEARCH,
301272286Sjkim        &DeviceNode);
302272286Sjkim    if (ACPI_FAILURE (Status))
303272286Sjkim    {
304272286Sjkim        goto ErrorExit;
305272286Sjkim    }
306272286Sjkim
307272286Sjkim    Status = AcpiNsGetNode (DeviceNode, METHOD_NAME__DDN, ACPI_NS_NO_UPSEARCH,
308272286Sjkim        &DdnNode);
309272286Sjkim    if (ACPI_FAILURE (Status))
310272286Sjkim    {
311272286Sjkim        goto ErrorExit;
312272286Sjkim    }
313272286Sjkim
314272286Sjkim    if ((DdnNode->Type != ACPI_TYPE_STRING) ||
315272286Sjkim        !DdnNode->Object)
316272286Sjkim    {
317272286Sjkim        goto ErrorExit;
318272286Sjkim    }
319272286Sjkim
320272286Sjkim    return (DdnNode->Object->String.Pointer);
321272286Sjkim
322272286Sjkim
323272286SjkimErrorExit:
324272286Sjkim    return (NULL);
325272286Sjkim}
326272286Sjkim
327272286Sjkim
328272286Sjkim/*******************************************************************************
329272286Sjkim *
330272286Sjkim * FUNCTION:    MpGetConnectionInfo
331272286Sjkim *
332272286Sjkim * PARAMETERS:  Op                      - Parse Op to be examined
333272286Sjkim *              PinIndex                - Index into GPIO PinList
334272286Sjkim *              TargetNode              - Where the field node is returned
335272286Sjkim *              TargetName              - Where the node path is returned
336272286Sjkim *
337272286Sjkim * RETURN:      A substitute _HID string, indicating that the name is actually
338272286Sjkim *              a field. NULL if the Op does not refer to a Connection.
339272286Sjkim *
340272286Sjkim * DESCRIPTION: Get the Field Unit that corresponds to the PinIndex after
341272286Sjkim *              a Connection() invocation.
342272286Sjkim *
343272286Sjkim ******************************************************************************/
344272286Sjkim
345272286Sjkimchar *
346272286SjkimMpGetConnectionInfo (
347272286Sjkim    ACPI_PARSE_OBJECT       *Op,
348272286Sjkim    UINT32                  PinIndex,
349272286Sjkim    ACPI_NAMESPACE_NODE     **TargetNode,
350272286Sjkim    char                    **TargetName)
351272286Sjkim{
352272286Sjkim    ACPI_PARSE_OBJECT       *NextOp;
353272286Sjkim    UINT32                  i;
354272286Sjkim
355272286Sjkim
356272286Sjkim    /*
357272286Sjkim     * Handle Connection() here. Find the next named FieldUnit.
358272286Sjkim     * Note: we look at the ParseOpcode for the compiler, look
359272286Sjkim     * at the AmlOpcode for the disassembler.
360272286Sjkim     */
361272286Sjkim    if ((Op->Asl.AmlOpcode == AML_INT_CONNECTION_OP) ||
362272286Sjkim        (Op->Asl.ParseOpcode == PARSEOP_CONNECTION))
363272286Sjkim    {
364272286Sjkim        /* Find the correct field unit definition */
365272286Sjkim
366272286Sjkim        NextOp = Op;
367272286Sjkim        for (i = 0; i <= PinIndex;)
368272286Sjkim        {
369272286Sjkim            NextOp = NextOp->Asl.Next;
370272286Sjkim            while (NextOp &&
371272286Sjkim                (NextOp->Asl.ParseOpcode != PARSEOP_NAMESEG) &&
372272286Sjkim                (NextOp->Asl.AmlOpcode != AML_INT_NAMEDFIELD_OP))
373272286Sjkim            {
374272286Sjkim                NextOp = NextOp->Asl.Next;
375272286Sjkim            }
376272286Sjkim
377272286Sjkim            if (!NextOp)
378272286Sjkim            {
379272286Sjkim                return ("UNKNOWN");
380272286Sjkim            }
381272286Sjkim
382272286Sjkim            /* Add length of this field to the current pin index */
383272286Sjkim
384272286Sjkim            if (NextOp->Asl.ParseOpcode == PARSEOP_NAMESEG)
385272286Sjkim            {
386272286Sjkim                i += (UINT32) NextOp->Asl.Child->Asl.Value.Integer;
387272286Sjkim            }
388272286Sjkim            else /* AML_INT_NAMEDFIELD_OP */
389272286Sjkim            {
390272286Sjkim                i += (UINT32) NextOp->Asl.Value.Integer;
391272286Sjkim            }
392272286Sjkim        }
393272286Sjkim
394272286Sjkim        /* Return the node and pathname for the field unit */
395272286Sjkim
396272286Sjkim        *TargetNode = NextOp->Asl.Node;
397272286Sjkim        *TargetName = AcpiNsGetExternalPathname (*TargetNode);
398272286Sjkim        return ("-Field-");
399272286Sjkim    }
400272286Sjkim
401272286Sjkim    return (NULL);
402272286Sjkim}
403