xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/aslmaputils.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
1460301d4Schristos /******************************************************************************
2460301d4Schristos  *
3460301d4Schristos  * Module Name: aslmaputils - Utilities for the resource descriptor/device maps
4460301d4Schristos  *
5460301d4Schristos  *****************************************************************************/
6460301d4Schristos 
7460301d4Schristos /*
8*046a2985Schristos  * Copyright (C) 2000 - 2023, Intel Corp.
9460301d4Schristos  * All rights reserved.
10460301d4Schristos  *
11460301d4Schristos  * Redistribution and use in source and binary forms, with or without
12460301d4Schristos  * modification, are permitted provided that the following conditions
13460301d4Schristos  * are met:
14460301d4Schristos  * 1. Redistributions of source code must retain the above copyright
15460301d4Schristos  *    notice, this list of conditions, and the following disclaimer,
16460301d4Schristos  *    without modification.
17460301d4Schristos  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18460301d4Schristos  *    substantially similar to the "NO WARRANTY" disclaimer below
19460301d4Schristos  *    ("Disclaimer") and any redistribution must be conditioned upon
20460301d4Schristos  *    including a substantially similar Disclaimer requirement for further
21460301d4Schristos  *    binary redistribution.
22460301d4Schristos  * 3. Neither the names of the above-listed copyright holders nor the names
23460301d4Schristos  *    of any contributors may be used to endorse or promote products derived
24460301d4Schristos  *    from this software without specific prior written permission.
25460301d4Schristos  *
26460301d4Schristos  * Alternatively, this software may be distributed under the terms of the
27460301d4Schristos  * GNU General Public License ("GPL") version 2 as published by the Free
28460301d4Schristos  * Software Foundation.
29460301d4Schristos  *
30460301d4Schristos  * NO WARRANTY
31460301d4Schristos  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32460301d4Schristos  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3346a330b4Schristos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34460301d4Schristos  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35460301d4Schristos  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36460301d4Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37460301d4Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38460301d4Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39460301d4Schristos  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40460301d4Schristos  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41460301d4Schristos  * POSSIBILITY OF SUCH DAMAGES.
42460301d4Schristos  */
43460301d4Schristos 
44460301d4Schristos #include "acpi.h"
45460301d4Schristos #include "accommon.h"
46460301d4Schristos #include "acapps.h"
47460301d4Schristos #include "aslcompiler.h"
48460301d4Schristos #include "aslcompiler.y.h"
49460301d4Schristos #include "acinterp.h"
50460301d4Schristos #include "acnamesp.h"
51460301d4Schristos #include "amlcode.h"
52460301d4Schristos 
53460301d4Schristos /* This module used for application-level code only */
54460301d4Schristos 
55460301d4Schristos #define _COMPONENT          ACPI_COMPILER
56460301d4Schristos         ACPI_MODULE_NAME    ("aslmaputils")
57460301d4Schristos 
58460301d4Schristos 
59460301d4Schristos /*******************************************************************************
60460301d4Schristos  *
61460301d4Schristos  * FUNCTION:    MpGetHidFromParseTree
62460301d4Schristos  *
63460301d4Schristos  * PARAMETERS:  HidNode             - Node for a _HID object
64460301d4Schristos  *
65460301d4Schristos  * RETURN:      An _HID string value. Automatically converts _HID integers
66460301d4Schristos  *              to strings. Never NULL.
67460301d4Schristos  *
68460301d4Schristos  * DESCRIPTION: Extract a _HID value from the parse tree, not the namespace.
69460301d4Schristos  *              Used when a fully initialized namespace is not available.
70460301d4Schristos  *
71460301d4Schristos  ******************************************************************************/
72460301d4Schristos 
73460301d4Schristos char *
MpGetHidFromParseTree(ACPI_NAMESPACE_NODE * HidNode)74460301d4Schristos MpGetHidFromParseTree (
75460301d4Schristos     ACPI_NAMESPACE_NODE     *HidNode)
76460301d4Schristos {
77460301d4Schristos     ACPI_PARSE_OBJECT       *Op;
78460301d4Schristos     ACPI_PARSE_OBJECT       *Arg;
79460301d4Schristos     char                    *HidString;
80460301d4Schristos 
81460301d4Schristos 
82460301d4Schristos     Op = HidNode->Op;
83d0e1da26Schristos     if (!Op)
84d0e1da26Schristos     {
85d0e1da26Schristos         /* Object is not resolved, probably an External */
86d0e1da26Schristos 
87d0e1da26Schristos         return ("Unresolved Symbol - referenced but not defined in this table");
88d0e1da26Schristos     }
89460301d4Schristos 
90460301d4Schristos     switch (Op->Asl.ParseOpcode)
91460301d4Schristos     {
92460301d4Schristos     case PARSEOP_NAME:
93460301d4Schristos 
94460301d4Schristos         Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
95460301d4Schristos         Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
96460301d4Schristos 
97460301d4Schristos         switch (Arg->Asl.ParseOpcode)
98460301d4Schristos         {
99460301d4Schristos         case PARSEOP_STRING_LITERAL:
100460301d4Schristos 
101460301d4Schristos             return (Arg->Asl.Value.String);
102460301d4Schristos 
103460301d4Schristos         case PARSEOP_INTEGER:
104460301d4Schristos 
105460301d4Schristos             /* Convert EISAID to a string */
106460301d4Schristos 
107b406f703Schristos             HidString = UtLocalCacheCalloc (ACPI_EISAID_STRING_SIZE);
108460301d4Schristos             AcpiExEisaIdToString (HidString, Arg->Asl.Value.Integer);
109460301d4Schristos             return (HidString);
110460301d4Schristos 
111460301d4Schristos         default:
112460301d4Schristos 
113460301d4Schristos             return ("UNKNOWN");
114460301d4Schristos         }
115460301d4Schristos 
116460301d4Schristos     default:
117460301d4Schristos         return ("-No HID-");
118460301d4Schristos     }
119460301d4Schristos }
120460301d4Schristos 
121460301d4Schristos 
122460301d4Schristos /*******************************************************************************
123460301d4Schristos  *
124460301d4Schristos  * FUNCTION:    MpGetHidValue
125460301d4Schristos  *
126460301d4Schristos  * PARAMETERS:  DeviceNode          - Node for parent device
127460301d4Schristos  *
128460301d4Schristos  * RETURN:      An _HID string value. Automatically converts _HID integers
129460301d4Schristos  *              to strings. Never NULL.
130460301d4Schristos  *
131460301d4Schristos  * DESCRIPTION: Extract _HID value from within a device scope. Does not
132460301d4Schristos  *              actually execute a method, just gets the string or integer
133460301d4Schristos  *              value for the _HID.
134460301d4Schristos  *
135460301d4Schristos  ******************************************************************************/
136460301d4Schristos 
137460301d4Schristos char *
MpGetHidValue(ACPI_NAMESPACE_NODE * DeviceNode)138460301d4Schristos MpGetHidValue (
139460301d4Schristos     ACPI_NAMESPACE_NODE     *DeviceNode)
140460301d4Schristos {
141460301d4Schristos     ACPI_NAMESPACE_NODE     *HidNode;
142460301d4Schristos     char                    *HidString;
143460301d4Schristos     ACPI_STATUS             Status;
144460301d4Schristos 
145460301d4Schristos 
146460301d4Schristos     Status = AcpiNsGetNode (DeviceNode, METHOD_NAME__HID,
147460301d4Schristos         ACPI_NS_NO_UPSEARCH, &HidNode);
148460301d4Schristos     if (ACPI_FAILURE (Status))
149460301d4Schristos     {
150460301d4Schristos         goto ErrorExit;
151460301d4Schristos     }
152460301d4Schristos 
153460301d4Schristos     /* If only partial namespace, get the _HID from the parse tree */
154460301d4Schristos 
155460301d4Schristos     if (!HidNode->Object)
156460301d4Schristos     {
157460301d4Schristos         return (MpGetHidFromParseTree (HidNode));
158460301d4Schristos     }
159460301d4Schristos 
160460301d4Schristos     /* Handle the different _HID flavors */
161460301d4Schristos 
162460301d4Schristos     switch (HidNode->Type)
163460301d4Schristos     {
164460301d4Schristos     case ACPI_TYPE_STRING:
165460301d4Schristos 
166460301d4Schristos         return (HidNode->Object->String.Pointer);
167460301d4Schristos 
168460301d4Schristos     case ACPI_TYPE_INTEGER:
169460301d4Schristos 
170460301d4Schristos         /* Convert EISAID to a string */
171460301d4Schristos 
172b406f703Schristos         HidString = UtLocalCacheCalloc (ACPI_EISAID_STRING_SIZE);
173460301d4Schristos         AcpiExEisaIdToString (HidString, HidNode->Object->Integer.Value);
174460301d4Schristos         return (HidString);
175460301d4Schristos 
176460301d4Schristos     case ACPI_TYPE_METHOD:
177460301d4Schristos 
178460301d4Schristos         return ("-Method-");
179460301d4Schristos 
180460301d4Schristos     default:
181460301d4Schristos 
182460301d4Schristos         FlPrintFile (ASL_FILE_MAP_OUTPUT, "BAD HID TYPE: %u", HidNode->Type);
183460301d4Schristos         break;
184460301d4Schristos     }
185460301d4Schristos 
186460301d4Schristos 
187460301d4Schristos ErrorExit:
188460301d4Schristos     return ("-No HID-");
189460301d4Schristos }
190460301d4Schristos 
191460301d4Schristos 
192460301d4Schristos /*******************************************************************************
193460301d4Schristos  *
194460301d4Schristos  * FUNCTION:    MpGetHidViaNamestring
195460301d4Schristos  *
196460301d4Schristos  * PARAMETERS:  DeviceName          - Namepath for parent device
197460301d4Schristos  *
198460301d4Schristos  * RETURN:      _HID string. Never NULL.
199460301d4Schristos  *
200460301d4Schristos  * DESCRIPTION: Get a _HID value via a device pathname (instead of just simply
201460301d4Schristos  *              a device node.)
202460301d4Schristos  *
203460301d4Schristos  ******************************************************************************/
204460301d4Schristos 
205460301d4Schristos char *
MpGetHidViaNamestring(char * DeviceName)206460301d4Schristos MpGetHidViaNamestring (
207460301d4Schristos     char                    *DeviceName)
208460301d4Schristos {
209460301d4Schristos     ACPI_NAMESPACE_NODE     *DeviceNode;
210460301d4Schristos     ACPI_STATUS             Status;
211460301d4Schristos 
212460301d4Schristos 
213460301d4Schristos     Status = AcpiNsGetNode (NULL, DeviceName, ACPI_NS_NO_UPSEARCH,
214460301d4Schristos         &DeviceNode);
215460301d4Schristos     if (ACPI_FAILURE (Status))
216460301d4Schristos     {
217460301d4Schristos         goto ErrorExit;
218460301d4Schristos     }
219460301d4Schristos 
220460301d4Schristos     return (MpGetHidValue (DeviceNode));
221460301d4Schristos 
222460301d4Schristos 
223460301d4Schristos ErrorExit:
224460301d4Schristos     return ("-No HID-");
225460301d4Schristos }
226460301d4Schristos 
227460301d4Schristos 
228460301d4Schristos /*******************************************************************************
229460301d4Schristos  *
230460301d4Schristos  * FUNCTION:    MpGetParentDeviceHid
231460301d4Schristos  *
232460301d4Schristos  * PARAMETERS:  Op                      - Parse Op to be examined
233460301d4Schristos  *              TargetNode              - Where the field node is returned
234460301d4Schristos  *              ParentDeviceName        - Where the node path is returned
235460301d4Schristos  *
236460301d4Schristos  * RETURN:      _HID string. Never NULL.
237460301d4Schristos  *
238460301d4Schristos  * DESCRIPTION: Find the parent Device or Scope Op, get the full pathname to
239460301d4Schristos  *              the parent, and get the _HID associated with the parent.
240460301d4Schristos  *
241460301d4Schristos  ******************************************************************************/
242460301d4Schristos 
243460301d4Schristos char *
MpGetParentDeviceHid(ACPI_PARSE_OBJECT * Op,ACPI_NAMESPACE_NODE ** TargetNode,char ** ParentDeviceName)244460301d4Schristos MpGetParentDeviceHid (
245460301d4Schristos     ACPI_PARSE_OBJECT       *Op,
246460301d4Schristos     ACPI_NAMESPACE_NODE     **TargetNode,
247460301d4Schristos     char                    **ParentDeviceName)
248460301d4Schristos {
249460301d4Schristos     ACPI_NAMESPACE_NODE     *DeviceNode;
250460301d4Schristos 
251460301d4Schristos 
252460301d4Schristos     /* Find parent Device() or Scope() Op */
253460301d4Schristos 
254460301d4Schristos     while (Op &&
255460301d4Schristos         (Op->Asl.AmlOpcode != AML_DEVICE_OP) &&
256460301d4Schristos         (Op->Asl.AmlOpcode != AML_SCOPE_OP))
257460301d4Schristos     {
258460301d4Schristos         Op = Op->Asl.Parent;
259460301d4Schristos     }
260460301d4Schristos 
261460301d4Schristos     if (!Op)
262460301d4Schristos     {
263460301d4Schristos         FlPrintFile (ASL_FILE_MAP_OUTPUT, " No_Parent_Device ");
264460301d4Schristos         goto ErrorExit;
265460301d4Schristos     }
266460301d4Schristos 
267460301d4Schristos     /* Get the full pathname to the device and the _HID */
268460301d4Schristos 
269460301d4Schristos     DeviceNode = Op->Asl.Node;
270460301d4Schristos     if (!DeviceNode)
271460301d4Schristos     {
272460301d4Schristos         FlPrintFile (ASL_FILE_MAP_OUTPUT, " No_Device_Node ");
273460301d4Schristos         goto ErrorExit;
274460301d4Schristos     }
275460301d4Schristos 
276460301d4Schristos     *ParentDeviceName = AcpiNsGetExternalPathname (DeviceNode);
277460301d4Schristos     return (MpGetHidValue (DeviceNode));
278460301d4Schristos 
279460301d4Schristos 
280460301d4Schristos ErrorExit:
281460301d4Schristos     return ("-No HID-");
282460301d4Schristos }
283460301d4Schristos 
284460301d4Schristos 
285460301d4Schristos /*******************************************************************************
286460301d4Schristos  *
287460301d4Schristos  * FUNCTION:    MpGetDdnValue
288460301d4Schristos  *
289460301d4Schristos  * PARAMETERS:  DeviceName          - Namepath for parent device
290460301d4Schristos  *
291460301d4Schristos  * RETURN:      _DDN description string. NULL on failure.
292460301d4Schristos  *
293460301d4Schristos  * DESCRIPTION: Execute the _DDN method for the device.
294460301d4Schristos  *
295460301d4Schristos  ******************************************************************************/
296460301d4Schristos 
297460301d4Schristos char *
MpGetDdnValue(char * DeviceName)298460301d4Schristos MpGetDdnValue (
299460301d4Schristos     char                    *DeviceName)
300460301d4Schristos {
301460301d4Schristos     ACPI_NAMESPACE_NODE     *DeviceNode;
302460301d4Schristos     ACPI_NAMESPACE_NODE     *DdnNode;
303460301d4Schristos     ACPI_STATUS             Status;
304460301d4Schristos 
305460301d4Schristos 
306460301d4Schristos     Status = AcpiNsGetNode (NULL, DeviceName, ACPI_NS_NO_UPSEARCH,
307460301d4Schristos         &DeviceNode);
308460301d4Schristos     if (ACPI_FAILURE (Status))
309460301d4Schristos     {
310460301d4Schristos         goto ErrorExit;
311460301d4Schristos     }
312460301d4Schristos 
313460301d4Schristos     Status = AcpiNsGetNode (DeviceNode, METHOD_NAME__DDN, ACPI_NS_NO_UPSEARCH,
314460301d4Schristos         &DdnNode);
315460301d4Schristos     if (ACPI_FAILURE (Status))
316460301d4Schristos     {
317460301d4Schristos         goto ErrorExit;
318460301d4Schristos     }
319460301d4Schristos 
320460301d4Schristos     if ((DdnNode->Type != ACPI_TYPE_STRING) ||
321460301d4Schristos         !DdnNode->Object)
322460301d4Schristos     {
323460301d4Schristos         goto ErrorExit;
324460301d4Schristos     }
325460301d4Schristos 
326460301d4Schristos     return (DdnNode->Object->String.Pointer);
327460301d4Schristos 
328460301d4Schristos 
329460301d4Schristos ErrorExit:
330460301d4Schristos     return (NULL);
331460301d4Schristos }
332460301d4Schristos 
333460301d4Schristos 
334460301d4Schristos /*******************************************************************************
335460301d4Schristos  *
336460301d4Schristos  * FUNCTION:    MpGetConnectionInfo
337460301d4Schristos  *
338460301d4Schristos  * PARAMETERS:  Op                      - Parse Op to be examined
339460301d4Schristos  *              PinIndex                - Index into GPIO PinList
340460301d4Schristos  *              TargetNode              - Where the field node is returned
341460301d4Schristos  *              TargetName              - Where the node path is returned
342460301d4Schristos  *
343460301d4Schristos  * RETURN:      A substitute _HID string, indicating that the name is actually
344460301d4Schristos  *              a field. NULL if the Op does not refer to a Connection.
345460301d4Schristos  *
346460301d4Schristos  * DESCRIPTION: Get the Field Unit that corresponds to the PinIndex after
347460301d4Schristos  *              a Connection() invocation.
348460301d4Schristos  *
349460301d4Schristos  ******************************************************************************/
350460301d4Schristos 
351460301d4Schristos char *
MpGetConnectionInfo(ACPI_PARSE_OBJECT * Op,UINT32 PinIndex,ACPI_NAMESPACE_NODE ** TargetNode,char ** TargetName)352460301d4Schristos MpGetConnectionInfo (
353460301d4Schristos     ACPI_PARSE_OBJECT       *Op,
354460301d4Schristos     UINT32                  PinIndex,
355460301d4Schristos     ACPI_NAMESPACE_NODE     **TargetNode,
356460301d4Schristos     char                    **TargetName)
357460301d4Schristos {
358460301d4Schristos     ACPI_PARSE_OBJECT       *NextOp;
359460301d4Schristos     UINT32                  i;
360460301d4Schristos 
361460301d4Schristos 
362460301d4Schristos     /*
363460301d4Schristos      * Handle Connection() here. Find the next named FieldUnit.
364460301d4Schristos      * Note: we look at the ParseOpcode for the compiler, look
365460301d4Schristos      * at the AmlOpcode for the disassembler.
366460301d4Schristos      */
367460301d4Schristos     if ((Op->Asl.AmlOpcode == AML_INT_CONNECTION_OP) ||
368460301d4Schristos         (Op->Asl.ParseOpcode == PARSEOP_CONNECTION))
369460301d4Schristos     {
370460301d4Schristos         /* Find the correct field unit definition */
371460301d4Schristos 
372460301d4Schristos         NextOp = Op;
373460301d4Schristos         for (i = 0; i <= PinIndex;)
374460301d4Schristos         {
375460301d4Schristos             NextOp = NextOp->Asl.Next;
376460301d4Schristos             while (NextOp &&
377460301d4Schristos                 (NextOp->Asl.ParseOpcode != PARSEOP_NAMESEG) &&
378460301d4Schristos                 (NextOp->Asl.AmlOpcode != AML_INT_NAMEDFIELD_OP))
379460301d4Schristos             {
380460301d4Schristos                 NextOp = NextOp->Asl.Next;
381460301d4Schristos             }
382460301d4Schristos 
383460301d4Schristos             if (!NextOp)
384460301d4Schristos             {
385460301d4Schristos                 return ("UNKNOWN");
386460301d4Schristos             }
387460301d4Schristos 
388460301d4Schristos             /* Add length of this field to the current pin index */
389460301d4Schristos 
390460301d4Schristos             if (NextOp->Asl.ParseOpcode == PARSEOP_NAMESEG)
391460301d4Schristos             {
392460301d4Schristos                 i += (UINT32) NextOp->Asl.Child->Asl.Value.Integer;
393460301d4Schristos             }
394460301d4Schristos             else /* AML_INT_NAMEDFIELD_OP */
395460301d4Schristos             {
396460301d4Schristos                 i += (UINT32) NextOp->Asl.Value.Integer;
397460301d4Schristos             }
398460301d4Schristos         }
399460301d4Schristos 
400460301d4Schristos         /* Return the node and pathname for the field unit */
401460301d4Schristos 
402460301d4Schristos         *TargetNode = NextOp->Asl.Node;
403460301d4Schristos         *TargetName = AcpiNsGetExternalPathname (*TargetNode);
404460301d4Schristos         return ("-Field-");
405460301d4Schristos     }
406460301d4Schristos 
407460301d4Schristos     return (NULL);
408460301d4Schristos }
409