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