dmextern.c revision 1.1.1.16 1 1.1 jruoho /******************************************************************************
2 1.1 jruoho *
3 1.1 jruoho * Module Name: dmextern - Support for External() ASL statements
4 1.1 jruoho *
5 1.1 jruoho *****************************************************************************/
6 1.1 jruoho
7 1.1.1.2 jruoho /*
8 1.1.1.16 christos * Copyright (C) 2000 - 2020, Intel Corp.
9 1.1 jruoho * All rights reserved.
10 1.1 jruoho *
11 1.1.1.2 jruoho * Redistribution and use in source and binary forms, with or without
12 1.1.1.2 jruoho * modification, are permitted provided that the following conditions
13 1.1.1.2 jruoho * are met:
14 1.1.1.2 jruoho * 1. Redistributions of source code must retain the above copyright
15 1.1.1.2 jruoho * notice, this list of conditions, and the following disclaimer,
16 1.1.1.2 jruoho * without modification.
17 1.1.1.2 jruoho * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 1.1.1.2 jruoho * substantially similar to the "NO WARRANTY" disclaimer below
19 1.1.1.2 jruoho * ("Disclaimer") and any redistribution must be conditioned upon
20 1.1.1.2 jruoho * including a substantially similar Disclaimer requirement for further
21 1.1.1.2 jruoho * binary redistribution.
22 1.1.1.2 jruoho * 3. Neither the names of the above-listed copyright holders nor the names
23 1.1.1.2 jruoho * of any contributors may be used to endorse or promote products derived
24 1.1.1.2 jruoho * from this software without specific prior written permission.
25 1.1.1.2 jruoho *
26 1.1.1.2 jruoho * Alternatively, this software may be distributed under the terms of the
27 1.1.1.2 jruoho * GNU General Public License ("GPL") version 2 as published by the Free
28 1.1.1.2 jruoho * Software Foundation.
29 1.1.1.2 jruoho *
30 1.1.1.2 jruoho * NO WARRANTY
31 1.1.1.2 jruoho * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 1.1.1.2 jruoho * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 1.1.1.2 jruoho * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 1.1.1.2 jruoho * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 1.1.1.2 jruoho * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 1.1.1.2 jruoho * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 1.1.1.2 jruoho * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 1.1.1.2 jruoho * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 1.1.1.2 jruoho * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 1.1.1.2 jruoho * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 1.1.1.2 jruoho * POSSIBILITY OF SUCH DAMAGES.
42 1.1.1.2 jruoho */
43 1.1 jruoho
44 1.1 jruoho #include "acpi.h"
45 1.1 jruoho #include "accommon.h"
46 1.1 jruoho #include "amlcode.h"
47 1.1 jruoho #include "acnamesp.h"
48 1.1 jruoho #include "acdisasm.h"
49 1.1.1.3 christos #include "aslcompiler.h"
50 1.1.1.3 christos #include <stdio.h>
51 1.1.1.3 christos #include <errno.h>
52 1.1 jruoho
53 1.1 jruoho
54 1.1 jruoho /*
55 1.1 jruoho * This module is used for application-level code (iASL disassembler) only.
56 1.1 jruoho *
57 1.1 jruoho * It contains the code to create and emit any necessary External() ASL
58 1.1 jruoho * statements for the module being disassembled.
59 1.1 jruoho */
60 1.1 jruoho #define _COMPONENT ACPI_CA_DISASSEMBLER
61 1.1 jruoho ACPI_MODULE_NAME ("dmextern")
62 1.1 jruoho
63 1.1 jruoho
64 1.1 jruoho /*
65 1.1 jruoho * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
66 1.1 jruoho * ObjectTypeKeyword. Used to generate typed external declarations
67 1.1 jruoho */
68 1.1 jruoho static const char *AcpiGbl_DmTypeNames[] =
69 1.1 jruoho {
70 1.1.1.4 christos /* 00 */ ", UnknownObj", /* Type ANY */
71 1.1 jruoho /* 01 */ ", IntObj",
72 1.1 jruoho /* 02 */ ", StrObj",
73 1.1 jruoho /* 03 */ ", BuffObj",
74 1.1 jruoho /* 04 */ ", PkgObj",
75 1.1 jruoho /* 05 */ ", FieldUnitObj",
76 1.1 jruoho /* 06 */ ", DeviceObj",
77 1.1 jruoho /* 07 */ ", EventObj",
78 1.1 jruoho /* 08 */ ", MethodObj",
79 1.1 jruoho /* 09 */ ", MutexObj",
80 1.1 jruoho /* 10 */ ", OpRegionObj",
81 1.1 jruoho /* 11 */ ", PowerResObj",
82 1.1 jruoho /* 12 */ ", ProcessorObj",
83 1.1 jruoho /* 13 */ ", ThermalZoneObj",
84 1.1 jruoho /* 14 */ ", BuffFieldObj",
85 1.1 jruoho /* 15 */ ", DDBHandleObj",
86 1.1 jruoho /* 16 */ "", /* Debug object */
87 1.1 jruoho /* 17 */ ", FieldUnitObj",
88 1.1 jruoho /* 18 */ ", FieldUnitObj",
89 1.1 jruoho /* 19 */ ", FieldUnitObj"
90 1.1 jruoho };
91 1.1 jruoho
92 1.1.1.3 christos #define METHOD_SEPARATORS " \t,()\n"
93 1.1.1.3 christos
94 1.1.1.11 christos static const char *ExternalConflictMessage =
95 1.1.1.11 christos " // Conflicts with a later declaration";
96 1.1.1.11 christos
97 1.1 jruoho
98 1.1 jruoho /* Local prototypes */
99 1.1 jruoho
100 1.1 jruoho static const char *
101 1.1 jruoho AcpiDmGetObjectTypeName (
102 1.1 jruoho ACPI_OBJECT_TYPE Type);
103 1.1 jruoho
104 1.1 jruoho static char *
105 1.1 jruoho AcpiDmNormalizeParentPrefix (
106 1.1 jruoho ACPI_PARSE_OBJECT *Op,
107 1.1 jruoho char *Path);
108 1.1 jruoho
109 1.1.1.11 christos static ACPI_STATUS
110 1.1.1.11 christos AcpiDmGetExternalAndInternalPath (
111 1.1.1.11 christos ACPI_NAMESPACE_NODE *Node,
112 1.1.1.11 christos char **ExternalPath,
113 1.1.1.11 christos char **InternalPath);
114 1.1.1.11 christos
115 1.1.1.11 christos static ACPI_STATUS
116 1.1.1.11 christos AcpiDmRemoveRootPrefix (
117 1.1.1.11 christos char **Path);
118 1.1.1.11 christos
119 1.1.1.3 christos static void
120 1.1.1.3 christos AcpiDmAddPathToExternalList (
121 1.1.1.3 christos char *Path,
122 1.1.1.3 christos UINT8 Type,
123 1.1.1.3 christos UINT32 Value,
124 1.1.1.3 christos UINT16 Flags);
125 1.1.1.3 christos
126 1.1.1.3 christos static ACPI_STATUS
127 1.1.1.3 christos AcpiDmCreateNewExternal (
128 1.1.1.3 christos char *ExternalPath,
129 1.1.1.3 christos char *InternalPath,
130 1.1.1.3 christos UINT8 Type,
131 1.1.1.3 christos UINT32 Value,
132 1.1.1.3 christos UINT16 Flags);
133 1.1.1.3 christos
134 1.1.1.11 christos static void
135 1.1.1.11 christos AcpiDmCheckForExternalConflict (
136 1.1.1.11 christos char *Path);
137 1.1.1.11 christos
138 1.1.1.11 christos static ACPI_STATUS
139 1.1.1.11 christos AcpiDmResolveExternal (
140 1.1.1.11 christos char *Path,
141 1.1.1.11 christos UINT8 Type,
142 1.1.1.11 christos ACPI_NAMESPACE_NODE **Node);
143 1.1.1.11 christos
144 1.1.1.11 christos
145 1.1.1.11 christos static void
146 1.1.1.11 christos AcpiDmConflictingDeclaration (
147 1.1.1.11 christos char *Path);
148 1.1.1.11 christos
149 1.1 jruoho
150 1.1 jruoho /*******************************************************************************
151 1.1 jruoho *
152 1.1 jruoho * FUNCTION: AcpiDmGetObjectTypeName
153 1.1 jruoho *
154 1.1 jruoho * PARAMETERS: Type - An ACPI_OBJECT_TYPE
155 1.1 jruoho *
156 1.1 jruoho * RETURN: Pointer to a string
157 1.1 jruoho *
158 1.1 jruoho * DESCRIPTION: Map an object type to the ASL object type string.
159 1.1 jruoho *
160 1.1 jruoho ******************************************************************************/
161 1.1 jruoho
162 1.1 jruoho static const char *
163 1.1 jruoho AcpiDmGetObjectTypeName (
164 1.1 jruoho ACPI_OBJECT_TYPE Type)
165 1.1 jruoho {
166 1.1 jruoho
167 1.1 jruoho if (Type == ACPI_TYPE_LOCAL_SCOPE)
168 1.1 jruoho {
169 1.1 jruoho Type = ACPI_TYPE_DEVICE;
170 1.1 jruoho }
171 1.1 jruoho else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)
172 1.1 jruoho {
173 1.1 jruoho return ("");
174 1.1 jruoho }
175 1.1 jruoho
176 1.1 jruoho return (AcpiGbl_DmTypeNames[Type]);
177 1.1 jruoho }
178 1.1 jruoho
179 1.1 jruoho
180 1.1 jruoho /*******************************************************************************
181 1.1 jruoho *
182 1.1 jruoho * FUNCTION: AcpiDmNormalizeParentPrefix
183 1.1 jruoho *
184 1.1 jruoho * PARAMETERS: Op - Parse op
185 1.1 jruoho * Path - Path with parent prefix
186 1.1 jruoho *
187 1.1 jruoho * RETURN: The full pathname to the object (from the namespace root)
188 1.1 jruoho *
189 1.1 jruoho * DESCRIPTION: Returns the full pathname of a path with parent prefix
190 1.1 jruoho * The caller must free the fullpath returned.
191 1.1 jruoho *
192 1.1 jruoho ******************************************************************************/
193 1.1 jruoho
194 1.1 jruoho static char *
195 1.1 jruoho AcpiDmNormalizeParentPrefix (
196 1.1 jruoho ACPI_PARSE_OBJECT *Op,
197 1.1 jruoho char *Path)
198 1.1 jruoho {
199 1.1 jruoho ACPI_NAMESPACE_NODE *Node;
200 1.1 jruoho char *Fullpath;
201 1.1 jruoho char *ParentPath;
202 1.1 jruoho ACPI_SIZE Length;
203 1.1.1.3 christos UINT32 Index = 0;
204 1.1 jruoho
205 1.1 jruoho
206 1.1.1.3 christos if (!Op)
207 1.1.1.3 christos {
208 1.1.1.3 christos return (NULL);
209 1.1.1.3 christos }
210 1.1.1.3 christos
211 1.1.1.3 christos /* Search upwards in the parse tree until we reach the next namespace node */
212 1.1 jruoho
213 1.1.1.3 christos Op = Op->Common.Parent;
214 1.1 jruoho while (Op)
215 1.1 jruoho {
216 1.1 jruoho if (Op->Common.Node)
217 1.1 jruoho {
218 1.1 jruoho break;
219 1.1 jruoho }
220 1.1 jruoho
221 1.1 jruoho Op = Op->Common.Parent;
222 1.1 jruoho }
223 1.1 jruoho
224 1.1 jruoho if (!Op)
225 1.1 jruoho {
226 1.1 jruoho return (NULL);
227 1.1 jruoho }
228 1.1 jruoho
229 1.1 jruoho /*
230 1.1 jruoho * Find the actual parent node for the reference:
231 1.1 jruoho * Remove all carat prefixes from the input path.
232 1.1 jruoho * There may be multiple parent prefixes (For example, ^^^M000)
233 1.1 jruoho */
234 1.1 jruoho Node = Op->Common.Node;
235 1.1 jruoho while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))
236 1.1 jruoho {
237 1.1 jruoho Node = Node->Parent;
238 1.1 jruoho Path++;
239 1.1 jruoho }
240 1.1 jruoho
241 1.1 jruoho if (!Node)
242 1.1 jruoho {
243 1.1 jruoho return (NULL);
244 1.1 jruoho }
245 1.1 jruoho
246 1.1 jruoho /* Get the full pathname for the parent node */
247 1.1 jruoho
248 1.1 jruoho ParentPath = AcpiNsGetExternalPathname (Node);
249 1.1 jruoho if (!ParentPath)
250 1.1 jruoho {
251 1.1 jruoho return (NULL);
252 1.1 jruoho }
253 1.1 jruoho
254 1.1.1.6 christos Length = (strlen (ParentPath) + strlen (Path) + 1);
255 1.1 jruoho if (ParentPath[1])
256 1.1 jruoho {
257 1.1 jruoho /*
258 1.1 jruoho * If ParentPath is not just a simple '\', increment the length
259 1.1 jruoho * for the required dot separator (ParentPath.Path)
260 1.1 jruoho */
261 1.1 jruoho Length++;
262 1.1.1.3 christos
263 1.1.1.3 christos /* For External() statements, we do not want a leading '\' */
264 1.1.1.3 christos
265 1.1.1.3 christos if (*ParentPath == AML_ROOT_PREFIX)
266 1.1.1.3 christos {
267 1.1.1.3 christos Index = 1;
268 1.1.1.3 christos }
269 1.1 jruoho }
270 1.1 jruoho
271 1.1 jruoho Fullpath = ACPI_ALLOCATE_ZEROED (Length);
272 1.1 jruoho if (!Fullpath)
273 1.1 jruoho {
274 1.1 jruoho goto Cleanup;
275 1.1 jruoho }
276 1.1 jruoho
277 1.1 jruoho /*
278 1.1 jruoho * Concatenate parent fullpath and path. For example,
279 1.1 jruoho * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
280 1.1 jruoho *
281 1.1 jruoho * Copy the parent path
282 1.1 jruoho */
283 1.1.1.6 christos strcpy (Fullpath, &ParentPath[Index]);
284 1.1 jruoho
285 1.1.1.3 christos /*
286 1.1.1.3 christos * Add dot separator
287 1.1.1.3 christos * (don't need dot if parent fullpath is a single backslash)
288 1.1.1.3 christos */
289 1.1 jruoho if (ParentPath[1])
290 1.1 jruoho {
291 1.1.1.6 christos strcat (Fullpath, ".");
292 1.1 jruoho }
293 1.1 jruoho
294 1.1 jruoho /* Copy child path (carat parent prefix(es) were skipped above) */
295 1.1 jruoho
296 1.1.1.6 christos strcat (Fullpath, Path);
297 1.1 jruoho
298 1.1 jruoho Cleanup:
299 1.1 jruoho ACPI_FREE (ParentPath);
300 1.1 jruoho return (Fullpath);
301 1.1 jruoho }
302 1.1 jruoho
303 1.1 jruoho
304 1.1 jruoho /*******************************************************************************
305 1.1 jruoho *
306 1.1.1.2 jruoho * FUNCTION: AcpiDmAddToExternalFileList
307 1.1.1.2 jruoho *
308 1.1.1.2 jruoho * PARAMETERS: PathList - Single path or list separated by comma
309 1.1.1.2 jruoho *
310 1.1.1.2 jruoho * RETURN: None
311 1.1.1.2 jruoho *
312 1.1.1.2 jruoho * DESCRIPTION: Add external files to global list
313 1.1.1.2 jruoho *
314 1.1.1.2 jruoho ******************************************************************************/
315 1.1.1.2 jruoho
316 1.1.1.2 jruoho ACPI_STATUS
317 1.1.1.2 jruoho AcpiDmAddToExternalFileList (
318 1.1.1.3 christos char *Pathname)
319 1.1.1.2 jruoho {
320 1.1.1.2 jruoho ACPI_EXTERNAL_FILE *ExternalFile;
321 1.1.1.3 christos char *LocalPathname;
322 1.1.1.2 jruoho
323 1.1.1.2 jruoho
324 1.1.1.3 christos if (!Pathname)
325 1.1.1.2 jruoho {
326 1.1.1.2 jruoho return (AE_OK);
327 1.1.1.2 jruoho }
328 1.1.1.2 jruoho
329 1.1.1.3 christos LocalPathname = ACPI_ALLOCATE (strlen (Pathname) + 1);
330 1.1.1.3 christos if (!LocalPathname)
331 1.1.1.2 jruoho {
332 1.1.1.3 christos return (AE_NO_MEMORY);
333 1.1.1.3 christos }
334 1.1.1.2 jruoho
335 1.1.1.3 christos ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
336 1.1.1.3 christos if (!ExternalFile)
337 1.1.1.3 christos {
338 1.1.1.3 christos ACPI_FREE (LocalPathname);
339 1.1.1.3 christos return (AE_NO_MEMORY);
340 1.1.1.3 christos }
341 1.1.1.2 jruoho
342 1.1.1.3 christos /* Take a copy of the file pathname */
343 1.1.1.2 jruoho
344 1.1.1.3 christos strcpy (LocalPathname, Pathname);
345 1.1.1.3 christos ExternalFile->Path = LocalPathname;
346 1.1.1.2 jruoho
347 1.1.1.3 christos if (AcpiGbl_ExternalFileList)
348 1.1.1.3 christos {
349 1.1.1.3 christos ExternalFile->Next = AcpiGbl_ExternalFileList;
350 1.1.1.2 jruoho }
351 1.1.1.2 jruoho
352 1.1.1.3 christos AcpiGbl_ExternalFileList = ExternalFile;
353 1.1.1.2 jruoho return (AE_OK);
354 1.1.1.2 jruoho }
355 1.1.1.2 jruoho
356 1.1.1.2 jruoho
357 1.1.1.2 jruoho /*******************************************************************************
358 1.1.1.2 jruoho *
359 1.1.1.2 jruoho * FUNCTION: AcpiDmClearExternalFileList
360 1.1.1.2 jruoho *
361 1.1.1.2 jruoho * PARAMETERS: None
362 1.1.1.2 jruoho *
363 1.1.1.2 jruoho * RETURN: None
364 1.1.1.2 jruoho *
365 1.1.1.2 jruoho * DESCRIPTION: Clear the external file list
366 1.1.1.2 jruoho *
367 1.1.1.2 jruoho ******************************************************************************/
368 1.1.1.2 jruoho
369 1.1.1.2 jruoho void
370 1.1.1.2 jruoho AcpiDmClearExternalFileList (
371 1.1.1.2 jruoho void)
372 1.1.1.2 jruoho {
373 1.1.1.2 jruoho ACPI_EXTERNAL_FILE *NextExternal;
374 1.1.1.2 jruoho
375 1.1.1.2 jruoho
376 1.1.1.2 jruoho while (AcpiGbl_ExternalFileList)
377 1.1.1.2 jruoho {
378 1.1.1.2 jruoho NextExternal = AcpiGbl_ExternalFileList->Next;
379 1.1.1.2 jruoho ACPI_FREE (AcpiGbl_ExternalFileList->Path);
380 1.1.1.2 jruoho ACPI_FREE (AcpiGbl_ExternalFileList);
381 1.1.1.2 jruoho AcpiGbl_ExternalFileList = NextExternal;
382 1.1.1.2 jruoho }
383 1.1.1.2 jruoho }
384 1.1.1.2 jruoho
385 1.1.1.2 jruoho
386 1.1.1.2 jruoho /*******************************************************************************
387 1.1.1.2 jruoho *
388 1.1.1.3 christos * FUNCTION: AcpiDmGetExternalsFromFile
389 1.1.1.3 christos *
390 1.1.1.3 christos * PARAMETERS: None
391 1.1.1.3 christos *
392 1.1.1.3 christos * RETURN: None
393 1.1.1.3 christos *
394 1.1.1.3 christos * DESCRIPTION: Process the optional external reference file.
395 1.1.1.3 christos *
396 1.1.1.3 christos * Each line in the file should be of the form:
397 1.1.1.3 christos * External (<Method namepath>, MethodObj, <ArgCount>)
398 1.1.1.3 christos *
399 1.1.1.3 christos * Example:
400 1.1.1.3 christos * External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
401 1.1.1.3 christos *
402 1.1.1.3 christos ******************************************************************************/
403 1.1.1.3 christos
404 1.1.1.3 christos void
405 1.1.1.3 christos AcpiDmGetExternalsFromFile (
406 1.1.1.3 christos void)
407 1.1.1.3 christos {
408 1.1.1.3 christos FILE *ExternalRefFile;
409 1.1.1.3 christos char *Token;
410 1.1.1.3 christos char *MethodName;
411 1.1.1.3 christos UINT32 ArgCount;
412 1.1.1.3 christos UINT32 ImportCount = 0;
413 1.1.1.3 christos
414 1.1.1.3 christos
415 1.1.1.14 christos if (!AslGbl_ExternalRefFilename)
416 1.1.1.3 christos {
417 1.1.1.3 christos return;
418 1.1.1.3 christos }
419 1.1.1.3 christos
420 1.1.1.3 christos /* Open the file */
421 1.1.1.3 christos
422 1.1.1.14 christos ExternalRefFile = fopen (AslGbl_ExternalRefFilename, "r");
423 1.1.1.3 christos if (!ExternalRefFile)
424 1.1.1.3 christos {
425 1.1.1.3 christos fprintf (stderr, "Could not open external reference file \"%s\"\n",
426 1.1.1.14 christos AslGbl_ExternalRefFilename);
427 1.1.1.4 christos AslAbort ();
428 1.1.1.3 christos return;
429 1.1.1.3 christos }
430 1.1.1.3 christos
431 1.1.1.3 christos /* Each line defines a method */
432 1.1.1.3 christos
433 1.1.1.14 christos while (fgets (AslGbl_StringBuffer, ASL_STRING_BUFFER_SIZE, ExternalRefFile))
434 1.1.1.3 christos {
435 1.1.1.14 christos Token = strtok (AslGbl_StringBuffer, METHOD_SEPARATORS); /* "External" */
436 1.1.1.4 christos if (!Token)
437 1.1.1.4 christos {
438 1.1.1.4 christos continue;
439 1.1.1.4 christos }
440 1.1.1.7 christos
441 1.1.1.4 christos if (strcmp (Token, "External"))
442 1.1.1.4 christos {
443 1.1.1.4 christos continue;
444 1.1.1.4 christos }
445 1.1.1.3 christos
446 1.1.1.3 christos MethodName = strtok (NULL, METHOD_SEPARATORS); /* Method namepath */
447 1.1.1.4 christos if (!MethodName)
448 1.1.1.4 christos {
449 1.1.1.4 christos continue;
450 1.1.1.4 christos }
451 1.1.1.3 christos
452 1.1.1.3 christos Token = strtok (NULL, METHOD_SEPARATORS); /* "MethodObj" */
453 1.1.1.4 christos if (!Token)
454 1.1.1.4 christos {
455 1.1.1.4 christos continue;
456 1.1.1.4 christos }
457 1.1.1.4 christos
458 1.1.1.4 christos if (strcmp (Token, "MethodObj"))
459 1.1.1.4 christos {
460 1.1.1.4 christos continue;
461 1.1.1.4 christos }
462 1.1.1.3 christos
463 1.1.1.3 christos Token = strtok (NULL, METHOD_SEPARATORS); /* Arg count */
464 1.1.1.4 christos if (!Token)
465 1.1.1.4 christos {
466 1.1.1.4 christos continue;
467 1.1.1.4 christos }
468 1.1.1.3 christos
469 1.1.1.3 christos /* Convert arg count string to an integer */
470 1.1.1.3 christos
471 1.1.1.3 christos errno = 0;
472 1.1.1.3 christos ArgCount = strtoul (Token, NULL, 0);
473 1.1.1.3 christos if (errno)
474 1.1.1.3 christos {
475 1.1.1.3 christos fprintf (stderr, "Invalid argument count (%s)\n", Token);
476 1.1.1.3 christos continue;
477 1.1.1.3 christos }
478 1.1.1.7 christos
479 1.1.1.3 christos if (ArgCount > 7)
480 1.1.1.3 christos {
481 1.1.1.3 christos fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);
482 1.1.1.3 christos continue;
483 1.1.1.3 christos }
484 1.1.1.3 christos
485 1.1.1.3 christos /* Add this external to the global list */
486 1.1.1.3 christos
487 1.1.1.3 christos AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
488 1.1.1.14 christos AslGbl_ExternalRefFilename, ArgCount, MethodName);
489 1.1.1.3 christos
490 1.1.1.3 christos AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD,
491 1.1.1.3 christos ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE));
492 1.1.1.3 christos ImportCount++;
493 1.1.1.3 christos }
494 1.1.1.3 christos
495 1.1.1.3 christos if (!ImportCount)
496 1.1.1.3 christos {
497 1.1.1.7 christos fprintf (stderr,
498 1.1.1.7 christos "Did not find any external methods in reference file \"%s\"\n",
499 1.1.1.14 christos AslGbl_ExternalRefFilename);
500 1.1.1.3 christos }
501 1.1.1.3 christos else
502 1.1.1.3 christos {
503 1.1.1.3 christos /* Add the external(s) to the namespace */
504 1.1.1.3 christos
505 1.1.1.11 christos AcpiDmAddExternalListToNamespace ();
506 1.1.1.3 christos
507 1.1.1.3 christos AcpiOsPrintf ("%s: Imported %u external method definitions\n",
508 1.1.1.14 christos AslGbl_ExternalRefFilename, ImportCount);
509 1.1.1.3 christos }
510 1.1.1.3 christos
511 1.1.1.3 christos fclose (ExternalRefFile);
512 1.1.1.3 christos }
513 1.1.1.3 christos
514 1.1.1.3 christos
515 1.1.1.3 christos /*******************************************************************************
516 1.1.1.3 christos *
517 1.1.1.3 christos * FUNCTION: AcpiDmAddOpToExternalList
518 1.1 jruoho *
519 1.1 jruoho * PARAMETERS: Op - Current parser Op
520 1.1 jruoho * Path - Internal (AML) path to the object
521 1.1 jruoho * Type - ACPI object type to be added
522 1.1 jruoho * Value - Arg count if adding a Method object
523 1.1.1.3 christos * Flags - To be passed to the external object
524 1.1 jruoho *
525 1.1 jruoho * RETURN: None
526 1.1 jruoho *
527 1.1 jruoho * DESCRIPTION: Insert a new name into the global list of Externals which
528 1.1 jruoho * will in turn be later emitted as an External() declaration
529 1.1 jruoho * in the disassembled output.
530 1.1 jruoho *
531 1.1.1.3 christos * This function handles the most common case where the referenced
532 1.1.1.3 christos * name is simply not found in the constructed namespace.
533 1.1.1.3 christos *
534 1.1 jruoho ******************************************************************************/
535 1.1 jruoho
536 1.1 jruoho void
537 1.1.1.3 christos AcpiDmAddOpToExternalList (
538 1.1 jruoho ACPI_PARSE_OBJECT *Op,
539 1.1 jruoho char *Path,
540 1.1 jruoho UINT8 Type,
541 1.1.1.3 christos UINT32 Value,
542 1.1.1.3 christos UINT16 Flags)
543 1.1 jruoho {
544 1.1 jruoho char *ExternalPath;
545 1.1.1.3 christos char *InternalPath = Path;
546 1.1.1.3 christos char *Temp;
547 1.1 jruoho ACPI_STATUS Status;
548 1.1 jruoho
549 1.1 jruoho
550 1.1.1.3 christos ACPI_FUNCTION_TRACE (DmAddOpToExternalList);
551 1.1.1.3 christos
552 1.1.1.3 christos
553 1.1 jruoho if (!Path)
554 1.1 jruoho {
555 1.1.1.3 christos return_VOID;
556 1.1.1.3 christos }
557 1.1.1.3 christos
558 1.1.1.3 christos /* Remove a root backslash if present */
559 1.1.1.3 christos
560 1.1.1.3 christos if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
561 1.1.1.3 christos {
562 1.1.1.3 christos Path++;
563 1.1 jruoho }
564 1.1 jruoho
565 1.1.1.3 christos /* Externalize the pathname */
566 1.1 jruoho
567 1.1 jruoho Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
568 1.1.1.3 christos NULL, &ExternalPath);
569 1.1 jruoho if (ACPI_FAILURE (Status))
570 1.1 jruoho {
571 1.1.1.3 christos return_VOID;
572 1.1 jruoho }
573 1.1 jruoho
574 1.1.1.3 christos /*
575 1.1.1.3 christos * Get the full pathname from the root if "Path" has one or more
576 1.1.1.3 christos * parent prefixes (^). Note: path will not contain a leading '\'.
577 1.1.1.3 christos */
578 1.1 jruoho if (*Path == (UINT8) AML_PARENT_PREFIX)
579 1.1 jruoho {
580 1.1.1.3 christos Temp = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
581 1.1.1.3 christos
582 1.1.1.3 christos /* Set new external path */
583 1.1.1.3 christos
584 1.1.1.3 christos ACPI_FREE (ExternalPath);
585 1.1.1.3 christos ExternalPath = Temp;
586 1.1.1.3 christos if (!Temp)
587 1.1 jruoho {
588 1.1.1.3 christos return_VOID;
589 1.1.1.3 christos }
590 1.1.1.3 christos
591 1.1.1.3 christos /* Create the new internal pathname */
592 1.1 jruoho
593 1.1.1.3 christos Flags |= ACPI_EXT_INTERNAL_PATH_ALLOCATED;
594 1.1.1.3 christos Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
595 1.1.1.3 christos if (ACPI_FAILURE (Status))
596 1.1.1.3 christos {
597 1.1 jruoho ACPI_FREE (ExternalPath);
598 1.1.1.3 christos return_VOID;
599 1.1.1.3 christos }
600 1.1.1.3 christos }
601 1.1.1.3 christos
602 1.1.1.3 christos /* Create the new External() declaration node */
603 1.1.1.3 christos
604 1.1.1.3 christos Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
605 1.1.1.3 christos Type, Value, Flags);
606 1.1.1.3 christos if (ACPI_FAILURE (Status))
607 1.1.1.3 christos {
608 1.1.1.3 christos ACPI_FREE (ExternalPath);
609 1.1.1.3 christos if (Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
610 1.1.1.3 christos {
611 1.1.1.3 christos ACPI_FREE (InternalPath);
612 1.1 jruoho }
613 1.1 jruoho }
614 1.1 jruoho
615 1.1.1.3 christos return_VOID;
616 1.1.1.3 christos }
617 1.1.1.3 christos
618 1.1.1.3 christos
619 1.1.1.3 christos /*******************************************************************************
620 1.1.1.3 christos *
621 1.1.1.11 christos * FUNCTION: AcpiDmGetExternalAndInternalPath
622 1.1.1.11 christos *
623 1.1.1.11 christos * PARAMETERS: Node - Namespace node for object to be added
624 1.1.1.11 christos * ExternalPath - Will contain the external path of the node
625 1.1.1.11 christos * InternalPath - Will contain the internal path of the node
626 1.1.1.11 christos *
627 1.1.1.11 christos * RETURN: None
628 1.1.1.11 christos *
629 1.1.1.11 christos * DESCRIPTION: Get the External and Internal path from the given node.
630 1.1.1.11 christos *
631 1.1.1.11 christos ******************************************************************************/
632 1.1.1.11 christos
633 1.1.1.11 christos static ACPI_STATUS
634 1.1.1.11 christos AcpiDmGetExternalAndInternalPath (
635 1.1.1.11 christos ACPI_NAMESPACE_NODE *Node,
636 1.1.1.11 christos char **ExternalPath,
637 1.1.1.11 christos char **InternalPath)
638 1.1.1.11 christos {
639 1.1.1.11 christos ACPI_STATUS Status;
640 1.1.1.11 christos
641 1.1.1.11 christos
642 1.1.1.11 christos if (!Node)
643 1.1.1.11 christos {
644 1.1.1.11 christos return (AE_BAD_PARAMETER);
645 1.1.1.11 christos }
646 1.1.1.11 christos
647 1.1.1.11 christos /* Get the full external and internal pathnames to the node */
648 1.1.1.11 christos
649 1.1.1.11 christos *ExternalPath = AcpiNsGetExternalPathname (Node);
650 1.1.1.11 christos if (!*ExternalPath)
651 1.1.1.11 christos {
652 1.1.1.11 christos return (AE_BAD_PATHNAME);
653 1.1.1.11 christos }
654 1.1.1.11 christos
655 1.1.1.11 christos Status = AcpiNsInternalizeName (*ExternalPath, InternalPath);
656 1.1.1.11 christos if (ACPI_FAILURE (Status))
657 1.1.1.11 christos {
658 1.1.1.11 christos ACPI_FREE (*ExternalPath);
659 1.1.1.11 christos return (Status);
660 1.1.1.11 christos }
661 1.1.1.11 christos
662 1.1.1.11 christos return (AE_OK);
663 1.1.1.11 christos }
664 1.1.1.11 christos
665 1.1.1.11 christos
666 1.1.1.11 christos /*******************************************************************************
667 1.1.1.11 christos *
668 1.1.1.11 christos * FUNCTION: AcpiDmRemoveRootPrefix
669 1.1.1.11 christos *
670 1.1.1.11 christos * PARAMETERS: Path - Remove Root prefix from this Path
671 1.1.1.11 christos *
672 1.1.1.11 christos * RETURN: None
673 1.1.1.11 christos *
674 1.1.1.11 christos * DESCRIPTION: Remove the root prefix character '\' from Path.
675 1.1.1.11 christos *
676 1.1.1.11 christos ******************************************************************************/
677 1.1.1.11 christos
678 1.1.1.11 christos static ACPI_STATUS
679 1.1.1.11 christos AcpiDmRemoveRootPrefix (
680 1.1.1.11 christos char **Path)
681 1.1.1.11 christos {
682 1.1.1.11 christos char *InputPath = *Path;
683 1.1.1.11 christos
684 1.1.1.11 christos
685 1.1.1.11 christos if ((*InputPath == AML_ROOT_PREFIX) && (InputPath[1]))
686 1.1.1.11 christos {
687 1.1.1.11 christos if (!memmove(InputPath, InputPath+1, strlen(InputPath)))
688 1.1.1.11 christos {
689 1.1.1.11 christos return (AE_ERROR);
690 1.1.1.11 christos }
691 1.1.1.11 christos
692 1.1.1.11 christos *Path = InputPath;
693 1.1.1.11 christos }
694 1.1.1.11 christos
695 1.1.1.11 christos return (AE_OK);
696 1.1.1.11 christos }
697 1.1.1.11 christos
698 1.1.1.11 christos
699 1.1.1.11 christos /*******************************************************************************
700 1.1.1.11 christos *
701 1.1.1.3 christos * FUNCTION: AcpiDmAddNodeToExternalList
702 1.1.1.3 christos *
703 1.1.1.3 christos * PARAMETERS: Node - Namespace node for object to be added
704 1.1.1.3 christos * Type - ACPI object type to be added
705 1.1.1.3 christos * Value - Arg count if adding a Method object
706 1.1.1.3 christos * Flags - To be passed to the external object
707 1.1.1.3 christos *
708 1.1.1.3 christos * RETURN: None
709 1.1.1.3 christos *
710 1.1.1.3 christos * DESCRIPTION: Insert a new name into the global list of Externals which
711 1.1.1.3 christos * will in turn be later emitted as an External() declaration
712 1.1.1.3 christos * in the disassembled output.
713 1.1.1.3 christos *
714 1.1.1.3 christos * This function handles the case where the referenced name has
715 1.1.1.3 christos * been found in the namespace, but the name originated in a
716 1.1.1.3 christos * table other than the one that is being disassembled (such
717 1.1.1.3 christos * as a table that is added via the iASL -e option).
718 1.1.1.3 christos *
719 1.1.1.3 christos ******************************************************************************/
720 1.1.1.3 christos
721 1.1.1.3 christos void
722 1.1.1.3 christos AcpiDmAddNodeToExternalList (
723 1.1.1.3 christos ACPI_NAMESPACE_NODE *Node,
724 1.1.1.3 christos UINT8 Type,
725 1.1.1.3 christos UINT32 Value,
726 1.1.1.3 christos UINT16 Flags)
727 1.1.1.3 christos {
728 1.1.1.3 christos char *ExternalPath;
729 1.1.1.3 christos char *InternalPath;
730 1.1.1.3 christos ACPI_STATUS Status;
731 1.1.1.3 christos
732 1.1.1.3 christos
733 1.1.1.3 christos ACPI_FUNCTION_TRACE (DmAddNodeToExternalList);
734 1.1.1.3 christos
735 1.1.1.3 christos /* Get the full external and internal pathnames to the node */
736 1.1.1.3 christos
737 1.1.1.11 christos Status = AcpiDmGetExternalAndInternalPath (Node, &ExternalPath, &InternalPath);
738 1.1.1.3 christos if (ACPI_FAILURE (Status))
739 1.1.1.3 christos {
740 1.1.1.3 christos return_VOID;
741 1.1.1.3 christos }
742 1.1.1.3 christos
743 1.1.1.3 christos /* Remove the root backslash */
744 1.1.1.3 christos
745 1.1.1.11 christos Status = AcpiDmRemoveRootPrefix (&ExternalPath);
746 1.1.1.11 christos if (ACPI_FAILURE (Status))
747 1.1.1.3 christos {
748 1.1.1.3 christos ACPI_FREE (ExternalPath);
749 1.1.1.11 christos ACPI_FREE (InternalPath);
750 1.1.1.11 christos return_VOID;
751 1.1.1.3 christos }
752 1.1.1.3 christos
753 1.1.1.3 christos /* Create the new External() declaration node */
754 1.1.1.3 christos
755 1.1.1.3 christos Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type,
756 1.1.1.3 christos Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
757 1.1.1.3 christos if (ACPI_FAILURE (Status))
758 1.1.1.3 christos {
759 1.1.1.3 christos ACPI_FREE (ExternalPath);
760 1.1.1.3 christos ACPI_FREE (InternalPath);
761 1.1.1.3 christos }
762 1.1.1.3 christos
763 1.1.1.3 christos return_VOID;
764 1.1.1.3 christos }
765 1.1.1.3 christos
766 1.1.1.3 christos
767 1.1.1.3 christos /*******************************************************************************
768 1.1.1.3 christos *
769 1.1.1.3 christos * FUNCTION: AcpiDmAddPathToExternalList
770 1.1.1.3 christos *
771 1.1.1.3 christos * PARAMETERS: Path - External name of the object to be added
772 1.1.1.3 christos * Type - ACPI object type to be added
773 1.1.1.3 christos * Value - Arg count if adding a Method object
774 1.1.1.3 christos * Flags - To be passed to the external object
775 1.1.1.3 christos *
776 1.1.1.3 christos * RETURN: None
777 1.1.1.3 christos *
778 1.1.1.3 christos * DESCRIPTION: Insert a new name into the global list of Externals which
779 1.1.1.3 christos * will in turn be later emitted as an External() declaration
780 1.1.1.3 christos * in the disassembled output.
781 1.1.1.3 christos *
782 1.1.1.3 christos * This function currently is used to add externals via a
783 1.1.1.3 christos * reference file (via the -fe iASL option).
784 1.1.1.3 christos *
785 1.1.1.3 christos ******************************************************************************/
786 1.1.1.3 christos
787 1.1.1.3 christos static void
788 1.1.1.3 christos AcpiDmAddPathToExternalList (
789 1.1.1.3 christos char *Path,
790 1.1.1.3 christos UINT8 Type,
791 1.1.1.3 christos UINT32 Value,
792 1.1.1.3 christos UINT16 Flags)
793 1.1.1.3 christos {
794 1.1.1.3 christos char *InternalPath;
795 1.1.1.3 christos char *ExternalPath;
796 1.1.1.3 christos ACPI_STATUS Status;
797 1.1.1.3 christos
798 1.1.1.3 christos
799 1.1.1.3 christos ACPI_FUNCTION_TRACE (DmAddPathToExternalList);
800 1.1.1.3 christos
801 1.1.1.3 christos
802 1.1.1.3 christos if (!Path)
803 1.1.1.3 christos {
804 1.1.1.3 christos return_VOID;
805 1.1.1.3 christos }
806 1.1.1.3 christos
807 1.1.1.3 christos /* Remove a root backslash if present */
808 1.1.1.3 christos
809 1.1.1.3 christos if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
810 1.1.1.3 christos {
811 1.1.1.3 christos Path++;
812 1.1.1.3 christos }
813 1.1.1.3 christos
814 1.1.1.3 christos /* Create the internal and external pathnames */
815 1.1.1.3 christos
816 1.1.1.3 christos Status = AcpiNsInternalizeName (Path, &InternalPath);
817 1.1.1.3 christos if (ACPI_FAILURE (Status))
818 1.1.1.3 christos {
819 1.1.1.3 christos return_VOID;
820 1.1.1.3 christos }
821 1.1.1.3 christos
822 1.1.1.3 christos Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,
823 1.1.1.3 christos NULL, &ExternalPath);
824 1.1.1.3 christos if (ACPI_FAILURE (Status))
825 1.1.1.3 christos {
826 1.1.1.3 christos ACPI_FREE (InternalPath);
827 1.1.1.3 christos return_VOID;
828 1.1.1.3 christos }
829 1.1.1.3 christos
830 1.1.1.3 christos /* Create the new External() declaration node */
831 1.1.1.3 christos
832 1.1.1.3 christos Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
833 1.1.1.3 christos Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
834 1.1.1.3 christos if (ACPI_FAILURE (Status))
835 1.1.1.3 christos {
836 1.1.1.3 christos ACPI_FREE (ExternalPath);
837 1.1.1.3 christos ACPI_FREE (InternalPath);
838 1.1.1.3 christos }
839 1.1.1.3 christos
840 1.1.1.3 christos return_VOID;
841 1.1.1.3 christos }
842 1.1.1.3 christos
843 1.1.1.3 christos
844 1.1.1.3 christos /*******************************************************************************
845 1.1.1.3 christos *
846 1.1.1.3 christos * FUNCTION: AcpiDmCreateNewExternal
847 1.1.1.3 christos *
848 1.1.1.3 christos * PARAMETERS: ExternalPath - External path to the object
849 1.1.1.3 christos * InternalPath - Internal (AML) path to the object
850 1.1.1.3 christos * Type - ACPI object type to be added
851 1.1.1.3 christos * Value - Arg count if adding a Method object
852 1.1.1.3 christos * Flags - To be passed to the external object
853 1.1.1.3 christos *
854 1.1.1.3 christos * RETURN: Status
855 1.1.1.3 christos *
856 1.1.1.3 christos * DESCRIPTION: Common low-level function to insert a new name into the global
857 1.1.1.3 christos * list of Externals which will in turn be later emitted as
858 1.1.1.3 christos * External() declarations in the disassembled output.
859 1.1.1.3 christos *
860 1.1.1.3 christos * Note: The external name should not include a root prefix
861 1.1.1.3 christos * (backslash). We do not want External() statements to contain
862 1.1.1.3 christos * a leading '\', as this prevents duplicate external statements
863 1.1.1.3 christos * of the form:
864 1.1.1.3 christos *
865 1.1.1.3 christos * External (\ABCD)
866 1.1.1.3 christos * External (ABCD)
867 1.1.1.3 christos *
868 1.1.1.3 christos * This would cause a compile time error when the disassembled
869 1.1.1.3 christos * output file is recompiled.
870 1.1.1.3 christos *
871 1.1.1.3 christos * There are two cases that are handled here. For both, we emit
872 1.1.1.3 christos * an External() statement:
873 1.1.1.3 christos * 1) The name was simply not found in the namespace.
874 1.1.1.3 christos * 2) The name was found, but it originated in a table other than
875 1.1.1.3 christos * the table that is being disassembled.
876 1.1.1.3 christos *
877 1.1.1.3 christos ******************************************************************************/
878 1.1.1.3 christos
879 1.1.1.3 christos static ACPI_STATUS
880 1.1.1.3 christos AcpiDmCreateNewExternal (
881 1.1.1.3 christos char *ExternalPath,
882 1.1.1.3 christos char *InternalPath,
883 1.1.1.3 christos UINT8 Type,
884 1.1.1.3 christos UINT32 Value,
885 1.1.1.3 christos UINT16 Flags)
886 1.1.1.3 christos {
887 1.1.1.3 christos ACPI_EXTERNAL_LIST *NewExternal;
888 1.1.1.3 christos ACPI_EXTERNAL_LIST *NextExternal;
889 1.1.1.3 christos ACPI_EXTERNAL_LIST *PrevExternal = NULL;
890 1.1.1.3 christos
891 1.1.1.3 christos
892 1.1.1.3 christos ACPI_FUNCTION_TRACE (DmCreateNewExternal);
893 1.1.1.3 christos
894 1.1.1.3 christos
895 1.1 jruoho /* Check all existing externals to ensure no duplicates */
896 1.1 jruoho
897 1.1 jruoho NextExternal = AcpiGbl_ExternalList;
898 1.1 jruoho while (NextExternal)
899 1.1 jruoho {
900 1.1.1.8 christos /* Check for duplicates */
901 1.1.1.8 christos
902 1.1.1.6 christos if (!strcmp (ExternalPath, NextExternal->Path))
903 1.1 jruoho {
904 1.1.1.8 christos /*
905 1.1.1.8 christos * If this external came from an External() opcode, we are
906 1.1.1.8 christos * finished with this one. (No need to check any further).
907 1.1.1.8 christos */
908 1.1.1.8 christos if (NextExternal->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE)
909 1.1 jruoho {
910 1.1.1.8 christos return_ACPI_STATUS (AE_ALREADY_EXISTS);
911 1.1 jruoho }
912 1.1 jruoho
913 1.1 jruoho /* Allow upgrade of type from ANY */
914 1.1 jruoho
915 1.1.1.8 christos else if ((NextExternal->Type == ACPI_TYPE_ANY) &&
916 1.1.1.8 christos (Type != ACPI_TYPE_ANY))
917 1.1 jruoho {
918 1.1 jruoho NextExternal->Type = Type;
919 1.1.1.8 christos }
920 1.1.1.8 christos
921 1.1.1.8 christos /* Update the argument count as necessary */
922 1.1.1.8 christos
923 1.1.1.8 christos if (Value < NextExternal->Value)
924 1.1.1.8 christos {
925 1.1 jruoho NextExternal->Value = Value;
926 1.1 jruoho }
927 1.1 jruoho
928 1.1.1.8 christos /* Update flags. */
929 1.1.1.8 christos
930 1.1.1.8 christos NextExternal->Flags |= Flags;
931 1.1.1.8 christos NextExternal->Flags &= ~ACPI_EXT_INTERNAL_PATH_ALLOCATED;
932 1.1.1.8 christos
933 1.1.1.3 christos return_ACPI_STATUS (AE_ALREADY_EXISTS);
934 1.1 jruoho }
935 1.1 jruoho
936 1.1 jruoho NextExternal = NextExternal->Next;
937 1.1 jruoho }
938 1.1 jruoho
939 1.1 jruoho /* Allocate and init a new External() descriptor */
940 1.1 jruoho
941 1.1 jruoho NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
942 1.1 jruoho if (!NewExternal)
943 1.1 jruoho {
944 1.1.1.3 christos return_ACPI_STATUS (AE_NO_MEMORY);
945 1.1 jruoho }
946 1.1 jruoho
947 1.1.1.3 christos ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
948 1.1.1.3 christos "Adding external reference node (%s) type [%s]\n",
949 1.1.1.3 christos ExternalPath, AcpiUtGetTypeName (Type)));
950 1.1.1.3 christos
951 1.1.1.3 christos NewExternal->Flags = Flags;
952 1.1.1.3 christos NewExternal->Value = Value;
953 1.1 jruoho NewExternal->Path = ExternalPath;
954 1.1 jruoho NewExternal->Type = Type;
955 1.1.1.6 christos NewExternal->Length = (UINT16) strlen (ExternalPath);
956 1.1.1.3 christos NewExternal->InternalPath = InternalPath;
957 1.1 jruoho
958 1.1.1.3 christos /* Link the new descriptor into the global list, alphabetically ordered */
959 1.1 jruoho
960 1.1 jruoho NextExternal = AcpiGbl_ExternalList;
961 1.1 jruoho while (NextExternal)
962 1.1 jruoho {
963 1.1.1.3 christos if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
964 1.1 jruoho {
965 1.1 jruoho if (PrevExternal)
966 1.1 jruoho {
967 1.1 jruoho PrevExternal->Next = NewExternal;
968 1.1 jruoho }
969 1.1 jruoho else
970 1.1 jruoho {
971 1.1 jruoho AcpiGbl_ExternalList = NewExternal;
972 1.1 jruoho }
973 1.1 jruoho
974 1.1 jruoho NewExternal->Next = NextExternal;
975 1.1.1.3 christos return_ACPI_STATUS (AE_OK);
976 1.1 jruoho }
977 1.1 jruoho
978 1.1 jruoho PrevExternal = NextExternal;
979 1.1 jruoho NextExternal = NextExternal->Next;
980 1.1 jruoho }
981 1.1 jruoho
982 1.1 jruoho if (PrevExternal)
983 1.1 jruoho {
984 1.1 jruoho PrevExternal->Next = NewExternal;
985 1.1 jruoho }
986 1.1 jruoho else
987 1.1 jruoho {
988 1.1 jruoho AcpiGbl_ExternalList = NewExternal;
989 1.1 jruoho }
990 1.1.1.3 christos
991 1.1.1.3 christos return_ACPI_STATUS (AE_OK);
992 1.1 jruoho }
993 1.1 jruoho
994 1.1 jruoho
995 1.1 jruoho /*******************************************************************************
996 1.1 jruoho *
997 1.1.1.11 christos * FUNCTION: AcpiDmResolveExternal
998 1.1 jruoho *
999 1.1.1.11 christos * PARAMETERS: Path - Path of the external
1000 1.1.1.11 christos * Type - Type of the external
1001 1.1.1.11 christos * Node - Input node for AcpiNsLookup
1002 1.1.1.11 christos *
1003 1.1.1.11 christos * RETURN: Status
1004 1.1.1.11 christos *
1005 1.1.1.11 christos * DESCRIPTION: Resolve the external within the namespace by AcpiNsLookup.
1006 1.1.1.11 christos * If the returned node is an external and has the same type
1007 1.1.1.11 christos * we assume that it was either an existing external or a
1008 1.1.1.11 christos *
1009 1.1.1.11 christos ******************************************************************************/
1010 1.1.1.11 christos
1011 1.1.1.11 christos static ACPI_STATUS
1012 1.1.1.11 christos AcpiDmResolveExternal (
1013 1.1.1.11 christos char *Path,
1014 1.1.1.11 christos UINT8 Type,
1015 1.1.1.11 christos ACPI_NAMESPACE_NODE **Node)
1016 1.1.1.11 christos {
1017 1.1.1.11 christos ACPI_STATUS Status;
1018 1.1.1.11 christos
1019 1.1.1.11 christos
1020 1.1.1.11 christos Status = AcpiNsLookup (NULL, Path, Type,
1021 1.1.1.11 christos ACPI_IMODE_LOAD_PASS1,
1022 1.1.1.11 christos ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
1023 1.1.1.11 christos NULL, Node);
1024 1.1.1.11 christos
1025 1.1.1.11 christos if (!Node)
1026 1.1.1.11 christos {
1027 1.1.1.11 christos ACPI_EXCEPTION ((AE_INFO, Status,
1028 1.1.1.11 christos "while adding external to namespace [%s]", Path));
1029 1.1.1.11 christos }
1030 1.1.1.11 christos
1031 1.1.1.11 christos /* Note the asl code "external(a) external(a)" is acceptable ASL */
1032 1.1.1.11 christos
1033 1.1.1.11 christos else if ((*Node)->Type == Type &&
1034 1.1.1.11 christos (*Node)->Flags & ANOBJ_IS_EXTERNAL)
1035 1.1.1.11 christos {
1036 1.1.1.11 christos return (AE_OK);
1037 1.1.1.11 christos }
1038 1.1.1.11 christos else
1039 1.1.1.11 christos {
1040 1.1.1.11 christos ACPI_EXCEPTION ((AE_INFO, AE_ERROR,
1041 1.1.1.11 christos "[%s] has conflicting declarations", Path));
1042 1.1.1.11 christos }
1043 1.1.1.11 christos
1044 1.1.1.11 christos return (AE_ERROR);
1045 1.1.1.11 christos }
1046 1.1.1.11 christos
1047 1.1.1.11 christos
1048 1.1.1.11 christos /*******************************************************************************
1049 1.1.1.11 christos *
1050 1.1.1.11 christos * FUNCTION: AcpiDmCreateSubobjectForExternal
1051 1.1.1.11 christos *
1052 1.1.1.11 christos * PARAMETERS: Type - Type of the external
1053 1.1.1.11 christos * Node - Namespace node from AcpiNsLookup
1054 1.1.1.11 christos * ParamCount - Value to be used for Method
1055 1.1 jruoho *
1056 1.1 jruoho * RETURN: None
1057 1.1 jruoho *
1058 1.1.1.11 christos * DESCRIPTION: Add one external to the namespace. Allows external to be
1059 1.1 jruoho * "resolved".
1060 1.1 jruoho *
1061 1.1 jruoho ******************************************************************************/
1062 1.1 jruoho
1063 1.1 jruoho void
1064 1.1.1.11 christos AcpiDmCreateSubobjectForExternal (
1065 1.1.1.11 christos UINT8 Type,
1066 1.1.1.11 christos ACPI_NAMESPACE_NODE **Node,
1067 1.1.1.11 christos UINT32 ParamCount)
1068 1.1 jruoho {
1069 1.1.1.3 christos ACPI_OPERAND_OBJECT *ObjDesc;
1070 1.1 jruoho
1071 1.1 jruoho
1072 1.1.1.11 christos switch (Type)
1073 1.1 jruoho {
1074 1.1.1.11 christos case ACPI_TYPE_METHOD:
1075 1.1 jruoho
1076 1.1.1.11 christos /* For methods, we need to save the argument count */
1077 1.1 jruoho
1078 1.1.1.11 christos ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
1079 1.1.1.11 christos ObjDesc->Method.ParamCount = (UINT8) ParamCount;
1080 1.1.1.11 christos (*Node)->Object = ObjDesc;
1081 1.1.1.11 christos break;
1082 1.1.1.3 christos
1083 1.1.1.11 christos case ACPI_TYPE_REGION:
1084 1.1.1.3 christos
1085 1.1.1.11 christos /* Regions require a region sub-object */
1086 1.1 jruoho
1087 1.1.1.11 christos ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
1088 1.1.1.11 christos ObjDesc->Region.Node = *Node;
1089 1.1.1.11 christos (*Node)->Object = ObjDesc;
1090 1.1.1.11 christos break;
1091 1.1.1.3 christos
1092 1.1.1.11 christos default:
1093 1.1.1.3 christos
1094 1.1.1.11 christos break;
1095 1.1.1.11 christos }
1096 1.1.1.11 christos }
1097 1.1.1.3 christos
1098 1.1.1.3 christos
1099 1.1.1.11 christos /*******************************************************************************
1100 1.1.1.11 christos *
1101 1.1.1.11 christos * FUNCTION: AcpiDmAddOneExternalToNamespace
1102 1.1.1.11 christos *
1103 1.1.1.11 christos * PARAMETERS: Path - External parse object
1104 1.1.1.11 christos * Type - Type of parse object
1105 1.1.1.11 christos * ParamCount - External method parameter count
1106 1.1.1.11 christos *
1107 1.1.1.11 christos * RETURN: None
1108 1.1.1.11 christos *
1109 1.1.1.11 christos * DESCRIPTION: Add one external to the namespace by resolvign the external
1110 1.1.1.11 christos * (by performing a namespace lookup) and annotating the resulting
1111 1.1.1.15 christos * namespace node with the appropriate information if the type
1112 1.1.1.11 christos * is ACPI_TYPE_REGION or ACPI_TYPE_METHOD.
1113 1.1.1.11 christos *
1114 1.1.1.11 christos ******************************************************************************/
1115 1.1.1.11 christos
1116 1.1.1.11 christos void
1117 1.1.1.11 christos AcpiDmAddOneExternalToNamespace (
1118 1.1.1.11 christos char *Path,
1119 1.1.1.11 christos UINT8 Type,
1120 1.1.1.11 christos UINT32 ParamCount)
1121 1.1.1.11 christos {
1122 1.1.1.11 christos ACPI_STATUS Status;
1123 1.1.1.11 christos ACPI_NAMESPACE_NODE *Node;
1124 1.1.1.3 christos
1125 1.1 jruoho
1126 1.1.1.11 christos Status = AcpiDmResolveExternal (Path, Type, &Node);
1127 1.1.1.11 christos
1128 1.1.1.11 christos if (ACPI_FAILURE (Status))
1129 1.1.1.11 christos {
1130 1.1.1.11 christos return;
1131 1.1.1.11 christos }
1132 1.1.1.11 christos
1133 1.1.1.11 christos AcpiDmCreateSubobjectForExternal (Type, &Node, ParamCount);
1134 1.1.1.11 christos
1135 1.1.1.11 christos }
1136 1.1.1.11 christos
1137 1.1.1.11 christos
1138 1.1.1.11 christos /*******************************************************************************
1139 1.1.1.11 christos *
1140 1.1.1.11 christos * FUNCTION: AcpiDmAddExternalListToNamespace
1141 1.1.1.11 christos *
1142 1.1.1.11 christos * PARAMETERS: None
1143 1.1.1.11 christos *
1144 1.1.1.11 christos * RETURN: None
1145 1.1.1.11 christos *
1146 1.1.1.11 christos * DESCRIPTION: Add all externals within AcpiGbl_ExternalList to the namespace.
1147 1.1.1.11 christos * Allows externals to be "resolved".
1148 1.1.1.11 christos *
1149 1.1.1.11 christos ******************************************************************************/
1150 1.1.1.11 christos
1151 1.1.1.11 christos void
1152 1.1.1.11 christos AcpiDmAddExternalListToNamespace (
1153 1.1.1.11 christos void)
1154 1.1.1.11 christos {
1155 1.1.1.11 christos ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
1156 1.1.1.11 christos
1157 1.1.1.11 christos
1158 1.1.1.11 christos while (External)
1159 1.1.1.11 christos {
1160 1.1.1.11 christos AcpiDmAddOneExternalToNamespace (External->InternalPath,
1161 1.1.1.11 christos External->Type, External->Value);
1162 1.1 jruoho External = External->Next;
1163 1.1 jruoho }
1164 1.1 jruoho }
1165 1.1 jruoho
1166 1.1 jruoho
1167 1.1 jruoho /*******************************************************************************
1168 1.1 jruoho *
1169 1.1.1.11 christos * FUNCTION: AcpiDmGetUnresolvedExternalMethodCount
1170 1.1 jruoho *
1171 1.1 jruoho * PARAMETERS: None
1172 1.1 jruoho *
1173 1.1.1.11 christos * RETURN: The number of unresolved control method externals in the
1174 1.1.1.11 christos * external list
1175 1.1 jruoho *
1176 1.1.1.11 christos * DESCRIPTION: Return the number of unresolved external methods that have been
1177 1.1.1.11 christos * generated. If any unresolved control method externals have been
1178 1.1.1.11 christos * found, we must re-parse the entire definition block with the new
1179 1.1.1.11 christos * information (number of arguments for the methods.)
1180 1.1.1.11 christos * This is limitation of AML, we don't know the number of arguments
1181 1.1.1.11 christos * from the control method invocation itself.
1182 1.1.1.11 christos *
1183 1.1.1.11 christos * Note: resolved external control methods are external control
1184 1.1.1.11 christos * methods encoded with the AML_EXTERNAL_OP bytecode within the
1185 1.1.1.11 christos * AML being disassembled.
1186 1.1 jruoho *
1187 1.1 jruoho ******************************************************************************/
1188 1.1 jruoho
1189 1.1 jruoho UINT32
1190 1.1.1.11 christos AcpiDmGetUnresolvedExternalMethodCount (
1191 1.1 jruoho void)
1192 1.1 jruoho {
1193 1.1 jruoho ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
1194 1.1 jruoho UINT32 Count = 0;
1195 1.1 jruoho
1196 1.1 jruoho
1197 1.1 jruoho while (External)
1198 1.1 jruoho {
1199 1.1.1.11 christos if (External->Type == ACPI_TYPE_METHOD &&
1200 1.1.1.11 christos !(External->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE))
1201 1.1 jruoho {
1202 1.1 jruoho Count++;
1203 1.1 jruoho }
1204 1.1 jruoho
1205 1.1 jruoho External = External->Next;
1206 1.1 jruoho }
1207 1.1 jruoho
1208 1.1 jruoho return (Count);
1209 1.1 jruoho }
1210 1.1 jruoho
1211 1.1 jruoho
1212 1.1 jruoho /*******************************************************************************
1213 1.1 jruoho *
1214 1.1 jruoho * FUNCTION: AcpiDmClearExternalList
1215 1.1 jruoho *
1216 1.1 jruoho * PARAMETERS: None
1217 1.1 jruoho *
1218 1.1 jruoho * RETURN: None
1219 1.1 jruoho *
1220 1.1 jruoho * DESCRIPTION: Free the entire External info list
1221 1.1 jruoho *
1222 1.1 jruoho ******************************************************************************/
1223 1.1 jruoho
1224 1.1 jruoho void
1225 1.1 jruoho AcpiDmClearExternalList (
1226 1.1 jruoho void)
1227 1.1 jruoho {
1228 1.1 jruoho ACPI_EXTERNAL_LIST *NextExternal;
1229 1.1 jruoho
1230 1.1 jruoho
1231 1.1 jruoho while (AcpiGbl_ExternalList)
1232 1.1 jruoho {
1233 1.1 jruoho NextExternal = AcpiGbl_ExternalList->Next;
1234 1.1 jruoho ACPI_FREE (AcpiGbl_ExternalList->Path);
1235 1.1 jruoho ACPI_FREE (AcpiGbl_ExternalList);
1236 1.1 jruoho AcpiGbl_ExternalList = NextExternal;
1237 1.1 jruoho }
1238 1.1 jruoho }
1239 1.1 jruoho
1240 1.1 jruoho
1241 1.1 jruoho /*******************************************************************************
1242 1.1 jruoho *
1243 1.1 jruoho * FUNCTION: AcpiDmEmitExternals
1244 1.1 jruoho *
1245 1.1 jruoho * PARAMETERS: None
1246 1.1 jruoho *
1247 1.1 jruoho * RETURN: None
1248 1.1 jruoho *
1249 1.1 jruoho * DESCRIPTION: Emit an External() ASL statement for each of the externals in
1250 1.1 jruoho * the global external info list.
1251 1.1 jruoho *
1252 1.1 jruoho ******************************************************************************/
1253 1.1 jruoho
1254 1.1 jruoho void
1255 1.1 jruoho AcpiDmEmitExternals (
1256 1.1 jruoho void)
1257 1.1 jruoho {
1258 1.1 jruoho ACPI_EXTERNAL_LIST *NextExternal;
1259 1.1 jruoho
1260 1.1 jruoho
1261 1.1 jruoho if (!AcpiGbl_ExternalList)
1262 1.1 jruoho {
1263 1.1 jruoho return;
1264 1.1 jruoho }
1265 1.1 jruoho
1266 1.1 jruoho /*
1267 1.1.1.3 christos * Determine the number of control methods in the external list, and
1268 1.1.1.3 christos * also how many of those externals were resolved via the namespace.
1269 1.1 jruoho */
1270 1.1.1.3 christos NextExternal = AcpiGbl_ExternalList;
1271 1.1.1.3 christos while (NextExternal)
1272 1.1 jruoho {
1273 1.1.1.3 christos if (NextExternal->Type == ACPI_TYPE_METHOD)
1274 1.1.1.3 christos {
1275 1.1.1.3 christos AcpiGbl_NumExternalMethods++;
1276 1.1.1.3 christos if (NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE)
1277 1.1.1.3 christos {
1278 1.1.1.3 christos AcpiGbl_ResolvedExternalMethods++;
1279 1.1.1.3 christos }
1280 1.1.1.3 christos }
1281 1.1.1.3 christos
1282 1.1.1.3 christos NextExternal = NextExternal->Next;
1283 1.1.1.3 christos }
1284 1.1 jruoho
1285 1.1.1.3 christos /* Check if any control methods were unresolved */
1286 1.1.1.3 christos
1287 1.1.1.3 christos AcpiDmUnresolvedWarning (1);
1288 1.1.1.3 christos
1289 1.1.1.14 christos if (AslGbl_ExternalRefFilename)
1290 1.1.1.3 christos {
1291 1.1.1.3 christos AcpiOsPrintf (
1292 1.1.1.8 christos " /*\n * External declarations were imported from\n"
1293 1.1.1.8 christos " * a reference file -- %s\n */\n\n",
1294 1.1.1.14 christos AslGbl_ExternalRefFilename);
1295 1.1.1.3 christos }
1296 1.1.1.3 christos
1297 1.1.1.3 christos /*
1298 1.1.1.8 christos * Walk and emit the list of externals found during the AML parsing
1299 1.1.1.3 christos */
1300 1.1.1.3 christos while (AcpiGbl_ExternalList)
1301 1.1.1.3 christos {
1302 1.1.1.3 christos if (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_EXTERNAL_EMITTED))
1303 1.1.1.3 christos {
1304 1.1.1.8 christos AcpiOsPrintf (" External (%s%s)",
1305 1.1.1.3 christos AcpiGbl_ExternalList->Path,
1306 1.1.1.3 christos AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
1307 1.1.1.3 christos
1308 1.1.1.8 christos /* Check for "unresolved" method reference */
1309 1.1.1.3 christos
1310 1.1.1.8 christos if ((AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) &&
1311 1.1.1.8 christos (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_RESOLVED_REFERENCE)))
1312 1.1.1.3 christos {
1313 1.1.1.8 christos AcpiOsPrintf (" // Warning: Unknown method, "
1314 1.1.1.8 christos "guessing %u arguments",
1315 1.1.1.3 christos AcpiGbl_ExternalList->Value);
1316 1.1.1.3 christos }
1317 1.1.1.8 christos
1318 1.1.1.8 christos /* Check for external from a external references file */
1319 1.1.1.8 christos
1320 1.1.1.8 christos else if (AcpiGbl_ExternalList->Flags & ACPI_EXT_ORIGIN_FROM_FILE)
1321 1.1.1.8 christos {
1322 1.1.1.8 christos if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
1323 1.1.1.8 christos {
1324 1.1.1.8 christos AcpiOsPrintf (" // %u Arguments",
1325 1.1.1.8 christos AcpiGbl_ExternalList->Value);
1326 1.1.1.8 christos }
1327 1.1.1.8 christos
1328 1.1.1.8 christos AcpiOsPrintf (" // From external reference file");
1329 1.1.1.8 christos }
1330 1.1.1.8 christos
1331 1.1.1.8 christos /* This is the normal external case */
1332 1.1.1.8 christos
1333 1.1.1.3 christos else
1334 1.1.1.3 christos {
1335 1.1.1.8 christos /* For methods, add a comment with the number of arguments */
1336 1.1.1.8 christos
1337 1.1.1.8 christos if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
1338 1.1.1.8 christos {
1339 1.1.1.8 christos AcpiOsPrintf (" // %u Arguments",
1340 1.1.1.8 christos AcpiGbl_ExternalList->Value);
1341 1.1.1.8 christos }
1342 1.1.1.3 christos }
1343 1.1.1.8 christos
1344 1.1.1.11 christos if (AcpiGbl_ExternalList->Flags &= ACPI_EXT_CONFLICTING_DECLARATION)
1345 1.1.1.11 christos {
1346 1.1.1.11 christos AcpiOsPrintf ("%s", ExternalConflictMessage);
1347 1.1.1.11 christos AcpiDmConflictingDeclaration (AcpiGbl_ExternalList->Path);
1348 1.1.1.11 christos }
1349 1.1.1.8 christos AcpiOsPrintf ("\n");
1350 1.1 jruoho }
1351 1.1 jruoho
1352 1.1 jruoho /* Free this external info block and move on to next external */
1353 1.1 jruoho
1354 1.1 jruoho NextExternal = AcpiGbl_ExternalList->Next;
1355 1.1.1.3 christos if (AcpiGbl_ExternalList->Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
1356 1.1 jruoho {
1357 1.1 jruoho ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
1358 1.1 jruoho }
1359 1.1 jruoho
1360 1.1 jruoho ACPI_FREE (AcpiGbl_ExternalList->Path);
1361 1.1 jruoho ACPI_FREE (AcpiGbl_ExternalList);
1362 1.1 jruoho AcpiGbl_ExternalList = NextExternal;
1363 1.1 jruoho }
1364 1.1 jruoho
1365 1.1 jruoho AcpiOsPrintf ("\n");
1366 1.1 jruoho }
1367 1.1 jruoho
1368 1.1.1.3 christos
1369 1.1.1.3 christos /*******************************************************************************
1370 1.1.1.3 christos *
1371 1.1.1.11 christos * FUNCTION: AcpiDmMarkExternalConflict
1372 1.1.1.11 christos *
1373 1.1.1.11 christos * PARAMETERS: Path - Namepath to search
1374 1.1.1.11 christos *
1375 1.1.1.11 christos * RETURN: ExternalList
1376 1.1.1.11 christos *
1377 1.1.1.11 christos * DESCRIPTION: Search the AcpiGbl_ExternalList for a matching path
1378 1.1.1.11 christos *
1379 1.1.1.11 christos ******************************************************************************/
1380 1.1.1.11 christos
1381 1.1.1.11 christos void
1382 1.1.1.11 christos AcpiDmMarkExternalConflict (
1383 1.1.1.11 christos ACPI_NAMESPACE_NODE *Node)
1384 1.1.1.11 christos {
1385 1.1.1.11 christos ACPI_EXTERNAL_LIST *ExternalList = AcpiGbl_ExternalList;
1386 1.1.1.11 christos char *ExternalPath;
1387 1.1.1.11 christos char *InternalPath;
1388 1.1.1.11 christos char *Temp;
1389 1.1.1.11 christos ACPI_STATUS Status;
1390 1.1.1.11 christos
1391 1.1.1.11 christos
1392 1.1.1.11 christos ACPI_FUNCTION_TRACE (DmMarkExternalConflict);
1393 1.1.1.11 christos
1394 1.1.1.11 christos
1395 1.1.1.11 christos if (Node->Flags & ANOBJ_IS_EXTERNAL)
1396 1.1.1.11 christos {
1397 1.1.1.11 christos return_VOID;
1398 1.1.1.11 christos }
1399 1.1.1.11 christos
1400 1.1.1.11 christos /* Get the full external and internal pathnames to the node */
1401 1.1.1.11 christos
1402 1.1.1.11 christos Status = AcpiDmGetExternalAndInternalPath (Node,
1403 1.1.1.11 christos &ExternalPath, &InternalPath);
1404 1.1.1.11 christos if (ACPI_FAILURE (Status))
1405 1.1.1.11 christos {
1406 1.1.1.11 christos return_VOID;
1407 1.1.1.11 christos }
1408 1.1.1.11 christos
1409 1.1.1.11 christos /* Remove the root backslash */
1410 1.1.1.11 christos
1411 1.1.1.11 christos Status = AcpiDmRemoveRootPrefix (&InternalPath);
1412 1.1.1.11 christos if (ACPI_FAILURE (Status))
1413 1.1.1.11 christos {
1414 1.1.1.11 christos ACPI_FREE (InternalPath);
1415 1.1.1.11 christos ACPI_FREE (ExternalPath);
1416 1.1.1.11 christos return_VOID;
1417 1.1.1.11 christos }
1418 1.1.1.11 christos
1419 1.1.1.11 christos while (ExternalList)
1420 1.1.1.11 christos {
1421 1.1.1.11 christos Temp = ExternalList->InternalPath;
1422 1.1.1.11 christos if ((*ExternalList->InternalPath == AML_ROOT_PREFIX) &&
1423 1.1.1.11 christos (ExternalList->InternalPath[1]))
1424 1.1.1.11 christos {
1425 1.1.1.11 christos Temp++;
1426 1.1.1.11 christos }
1427 1.1.1.11 christos
1428 1.1.1.11 christos if (!strcmp (ExternalList->InternalPath, InternalPath))
1429 1.1.1.11 christos {
1430 1.1.1.11 christos ExternalList->Flags |= ACPI_EXT_CONFLICTING_DECLARATION;
1431 1.1.1.11 christos }
1432 1.1.1.11 christos ExternalList = ExternalList->Next;
1433 1.1.1.11 christos }
1434 1.1.1.11 christos
1435 1.1.1.11 christos ACPI_FREE (InternalPath);
1436 1.1.1.11 christos ACPI_FREE (ExternalPath);
1437 1.1.1.11 christos
1438 1.1.1.11 christos return_VOID;
1439 1.1.1.11 christos }
1440 1.1.1.11 christos
1441 1.1.1.11 christos
1442 1.1.1.11 christos /*******************************************************************************
1443 1.1.1.11 christos *
1444 1.1.1.11 christos * FUNCTION: AcpiDmConflictingDeclaration
1445 1.1.1.11 christos *
1446 1.1.1.11 christos * PARAMETERS: Path - Path with conflicting declaration
1447 1.1.1.11 christos *
1448 1.1.1.11 christos * RETURN: None
1449 1.1.1.11 christos *
1450 1.1.1.11 christos * DESCRIPTION: Emit a warning when printing conflicting ASL external
1451 1.1.1.11 christos * declarations.
1452 1.1.1.11 christos *
1453 1.1.1.11 christos ******************************************************************************/
1454 1.1.1.11 christos
1455 1.1.1.11 christos static void
1456 1.1.1.11 christos AcpiDmConflictingDeclaration (
1457 1.1.1.11 christos char *Path)
1458 1.1.1.11 christos {
1459 1.1.1.11 christos fprintf (stderr,
1460 1.1.1.11 christos " Warning - Emitting ASL code \"External (%s)\"\n"
1461 1.1.1.11 christos " This is a conflicting declaration with some "
1462 1.1.1.11 christos "other declaration within the ASL code.\n"
1463 1.1.1.11 christos " This external declaration may need to be "
1464 1.1.1.11 christos "deleted in order to recompile the dsl file.\n\n",
1465 1.1.1.11 christos Path);
1466 1.1.1.11 christos }
1467 1.1.1.11 christos
1468 1.1.1.11 christos
1469 1.1.1.11 christos /*******************************************************************************
1470 1.1.1.11 christos *
1471 1.1.1.10 christos * FUNCTION: AcpiDmEmitExternal
1472 1.1.1.10 christos *
1473 1.1.1.10 christos * PARAMETERS: Op External Parse Object
1474 1.1.1.10 christos *
1475 1.1.1.10 christos * RETURN: None
1476 1.1.1.10 christos *
1477 1.1.1.10 christos * DESCRIPTION: Emit an External() ASL statement for the current External
1478 1.1.1.11 christos * parse object. Note: External Ops are named types so the
1479 1.1.1.11 christos * namepath is contained within NameOp->Name.Path.
1480 1.1.1.10 christos *
1481 1.1.1.10 christos ******************************************************************************/
1482 1.1.1.10 christos
1483 1.1.1.10 christos void
1484 1.1.1.10 christos AcpiDmEmitExternal (
1485 1.1.1.10 christos ACPI_PARSE_OBJECT *NameOp,
1486 1.1.1.10 christos ACPI_PARSE_OBJECT *TypeOp)
1487 1.1.1.10 christos {
1488 1.1.1.10 christos AcpiOsPrintf ("External (");
1489 1.1.1.11 christos AcpiDmNamestring (NameOp->Named.Path);
1490 1.1.1.11 christos AcpiOsPrintf ("%s)",
1491 1.1.1.10 christos AcpiDmGetObjectTypeName ((ACPI_OBJECT_TYPE) TypeOp->Common.Value.Integer));
1492 1.1.1.11 christos AcpiDmCheckForExternalConflict (NameOp->Named.Path);
1493 1.1.1.11 christos AcpiOsPrintf ("\n");
1494 1.1.1.10 christos }
1495 1.1.1.10 christos
1496 1.1.1.10 christos
1497 1.1.1.10 christos /*******************************************************************************
1498 1.1.1.10 christos *
1499 1.1.1.11 christos * FUNCTION: AcpiDmCheckForExternalConflict
1500 1.1.1.11 christos *
1501 1.1.1.11 christos * PARAMETERS: Path - Path to check
1502 1.1.1.11 christos *
1503 1.1.1.11 christos * RETURN: None
1504 1.1.1.11 christos *
1505 1.1.1.11 christos * DESCRIPTION: Search the External List to see if the input Path has a
1506 1.1.1.11 christos * conflicting declaration.
1507 1.1.1.11 christos *
1508 1.1.1.11 christos ******************************************************************************/
1509 1.1.1.11 christos
1510 1.1.1.11 christos static void
1511 1.1.1.11 christos AcpiDmCheckForExternalConflict (
1512 1.1.1.11 christos char *Path)
1513 1.1.1.11 christos {
1514 1.1.1.11 christos ACPI_EXTERNAL_LIST *ExternalList = AcpiGbl_ExternalList;
1515 1.1.1.11 christos char *ListItemPath;
1516 1.1.1.11 christos char *InputPath;
1517 1.1.1.11 christos
1518 1.1.1.11 christos
1519 1.1.1.11 christos if (!Path)
1520 1.1.1.11 christos {
1521 1.1.1.11 christos return;
1522 1.1.1.11 christos }
1523 1.1.1.11 christos
1524 1.1.1.11 christos /* Move past the root prefix '\' */
1525 1.1.1.11 christos
1526 1.1.1.11 christos InputPath = Path;
1527 1.1.1.11 christos if ((*InputPath == AML_ROOT_PREFIX) && InputPath[1])
1528 1.1.1.11 christos {
1529 1.1.1.11 christos InputPath++;
1530 1.1.1.11 christos }
1531 1.1.1.11 christos
1532 1.1.1.11 christos while (ExternalList)
1533 1.1.1.11 christos {
1534 1.1.1.11 christos ListItemPath = ExternalList->Path;
1535 1.1.1.11 christos if (ListItemPath)
1536 1.1.1.11 christos {
1537 1.1.1.11 christos /* Move past the root prefix '\' */
1538 1.1.1.11 christos
1539 1.1.1.11 christos if ((*ListItemPath == AML_ROOT_PREFIX) &&
1540 1.1.1.11 christos ListItemPath[1])
1541 1.1.1.11 christos {
1542 1.1.1.11 christos ListItemPath++;
1543 1.1.1.11 christos }
1544 1.1.1.11 christos
1545 1.1.1.11 christos if (!strcmp (ListItemPath, InputPath) &&
1546 1.1.1.11 christos (ExternalList->Flags & ACPI_EXT_CONFLICTING_DECLARATION))
1547 1.1.1.11 christos {
1548 1.1.1.11 christos AcpiOsPrintf ("%s", ExternalConflictMessage);
1549 1.1.1.11 christos AcpiDmConflictingDeclaration (Path);
1550 1.1.1.11 christos
1551 1.1.1.11 christos return;
1552 1.1.1.11 christos }
1553 1.1.1.11 christos }
1554 1.1.1.11 christos ExternalList = ExternalList->Next;
1555 1.1.1.11 christos }
1556 1.1.1.11 christos }
1557 1.1.1.11 christos /*******************************************************************************
1558 1.1.1.11 christos *
1559 1.1.1.3 christos * FUNCTION: AcpiDmUnresolvedWarning
1560 1.1.1.3 christos *
1561 1.1.1.3 christos * PARAMETERS: Type - Where to output the warning.
1562 1.1.1.3 christos * 0 means write to stderr
1563 1.1.1.3 christos * 1 means write to AcpiOsPrintf
1564 1.1.1.3 christos *
1565 1.1.1.3 christos * RETURN: None
1566 1.1.1.3 christos *
1567 1.1.1.3 christos * DESCRIPTION: Issue warning message if there are unresolved external control
1568 1.1.1.3 christos * methods within the disassembly.
1569 1.1.1.3 christos *
1570 1.1.1.3 christos ******************************************************************************/
1571 1.1.1.3 christos
1572 1.1.1.11 christos /*
1573 1.1.1.3 christos Summary of the external control method problem:
1574 1.1.1.3 christos
1575 1.1.1.3 christos When the -e option is used with disassembly, the various SSDTs are simply
1576 1.1.1.3 christos loaded into a global namespace for the disassembler to use in order to
1577 1.1.1.3 christos resolve control method references (invocations).
1578 1.1.1.3 christos
1579 1.1.1.3 christos The disassembler tracks any such references, and will emit an External()
1580 1.1.1.3 christos statement for these types of methods, with the proper number of arguments .
1581 1.1.1.3 christos
1582 1.1.1.3 christos Without the SSDTs, the AML does not contain enough information to properly
1583 1.1.1.3 christos disassemble the control method invocation -- because the disassembler does
1584 1.1.1.3 christos not know how many arguments to parse.
1585 1.1.1.3 christos
1586 1.1.1.3 christos An example: Assume we have two control methods. ABCD has one argument, and
1587 1.1.1.3 christos EFGH has zero arguments. Further, we have two additional control methods
1588 1.1.1.3 christos that invoke ABCD and EFGH, named T1 and T2:
1589 1.1.1.3 christos
1590 1.1.1.3 christos Method (ABCD, 1)
1591 1.1.1.3 christos {
1592 1.1.1.3 christos }
1593 1.1.1.3 christos Method (EFGH, 0)
1594 1.1.1.3 christos {
1595 1.1.1.3 christos }
1596 1.1.1.3 christos Method (T1)
1597 1.1.1.3 christos {
1598 1.1.1.3 christos ABCD (Add (2, 7, Local0))
1599 1.1.1.3 christos }
1600 1.1.1.3 christos Method (T2)
1601 1.1.1.3 christos {
1602 1.1.1.3 christos EFGH ()
1603 1.1.1.3 christos Add (2, 7, Local0)
1604 1.1.1.3 christos }
1605 1.1.1.3 christos
1606 1.1.1.3 christos Here is the AML code that is generated for T1 and T2:
1607 1.1.1.3 christos
1608 1.1.1.3 christos 185: Method (T1)
1609 1.1.1.3 christos
1610 1.1.1.3 christos 0000034C: 14 10 54 31 5F 5F 00 ... "..T1__."
1611 1.1.1.3 christos
1612 1.1.1.3 christos 186: {
1613 1.1.1.3 christos 187: ABCD (Add (2, 7, Local0))
1614 1.1.1.3 christos
1615 1.1.1.3 christos 00000353: 41 42 43 44 ............ "ABCD"
1616 1.1.1.3 christos 00000357: 72 0A 02 0A 07 60 ...... "r....`"
1617 1.1.1.3 christos
1618 1.1.1.3 christos 188: }
1619 1.1.1.3 christos
1620 1.1.1.3 christos 190: Method (T2)
1621 1.1.1.3 christos
1622 1.1.1.3 christos 0000035D: 14 10 54 32 5F 5F 00 ... "..T2__."
1623 1.1.1.3 christos
1624 1.1.1.3 christos 191: {
1625 1.1.1.3 christos 192: EFGH ()
1626 1.1.1.3 christos
1627 1.1.1.3 christos 00000364: 45 46 47 48 ............ "EFGH"
1628 1.1.1.3 christos
1629 1.1.1.3 christos 193: Add (2, 7, Local0)
1630 1.1.1.3 christos
1631 1.1.1.3 christos 00000368: 72 0A 02 0A 07 60 ...... "r....`"
1632 1.1.1.3 christos 194: }
1633 1.1.1.3 christos
1634 1.1.1.3 christos Note that the AML code for T1 and T2 is essentially identical. When
1635 1.1.1.3 christos disassembling this code, the methods ABCD and EFGH must be known to the
1636 1.1.1.3 christos disassembler, otherwise it does not know how to handle the method invocations.
1637 1.1.1.3 christos
1638 1.1.1.3 christos In other words, if ABCD and EFGH are actually external control methods
1639 1.1.1.3 christos appearing in an SSDT, the disassembler does not know what to do unless
1640 1.1.1.3 christos the owning SSDT has been loaded via the -e option.
1641 1.1.1.11 christos */
1642 1.1.1.3 christos
1643 1.1.1.8 christos static char ExternalWarningPart1[600];
1644 1.1.1.8 christos static char ExternalWarningPart2[400];
1645 1.1.1.8 christos static char ExternalWarningPart3[400];
1646 1.1.1.8 christos static char ExternalWarningPart4[200];
1647 1.1.1.8 christos
1648 1.1.1.3 christos void
1649 1.1.1.3 christos AcpiDmUnresolvedWarning (
1650 1.1.1.3 christos UINT8 Type)
1651 1.1.1.3 christos {
1652 1.1.1.8 christos char *Format;
1653 1.1.1.8 christos char Pad[] = " *";
1654 1.1.1.8 christos char NoPad[] = "";
1655 1.1.1.8 christos
1656 1.1.1.3 christos
1657 1.1.1.3 christos if (!AcpiGbl_NumExternalMethods)
1658 1.1.1.3 christos {
1659 1.1.1.3 christos return;
1660 1.1.1.3 christos }
1661 1.1.1.3 christos
1662 1.1.1.8 christos if (AcpiGbl_NumExternalMethods == AcpiGbl_ResolvedExternalMethods)
1663 1.1.1.8 christos {
1664 1.1.1.8 christos return;
1665 1.1.1.8 christos }
1666 1.1.1.8 christos
1667 1.1.1.8 christos Format = Type ? Pad : NoPad;
1668 1.1.1.8 christos
1669 1.1.1.8 christos sprintf (ExternalWarningPart1,
1670 1.1.1.8 christos "%s iASL Warning: There %s %u external control method%s found during\n"
1671 1.1.1.8 christos "%s disassembly, but only %u %s resolved (%u unresolved). Additional\n"
1672 1.1.1.8 christos "%s ACPI tables may be required to properly disassemble the code. This\n"
1673 1.1.1.8 christos "%s resulting disassembler output file may not compile because the\n"
1674 1.1.1.8 christos "%s disassembler did not know how many arguments to assign to the\n"
1675 1.1.1.8 christos "%s unresolved methods. Note: SSDTs can be dynamically loaded at\n"
1676 1.1.1.8 christos "%s runtime and may or may not be available via the host OS.\n",
1677 1.1.1.8 christos Format, (AcpiGbl_NumExternalMethods != 1 ? "were" : "was"),
1678 1.1.1.8 christos AcpiGbl_NumExternalMethods, (AcpiGbl_NumExternalMethods != 1 ? "s" : ""),
1679 1.1.1.8 christos Format, AcpiGbl_ResolvedExternalMethods,
1680 1.1.1.8 christos (AcpiGbl_ResolvedExternalMethods != 1 ? "were" : "was"),
1681 1.1.1.8 christos (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods),
1682 1.1.1.8 christos Format, Format, Format, Format, Format);
1683 1.1.1.8 christos
1684 1.1.1.8 christos sprintf (ExternalWarningPart2,
1685 1.1.1.8 christos "%s To specify the tables needed to resolve external control method\n"
1686 1.1.1.8 christos "%s references, the -e option can be used to specify the filenames.\n"
1687 1.1.1.8 christos "%s Example iASL invocations:\n"
1688 1.1.1.8 christos "%s iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"
1689 1.1.1.8 christos "%s iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"
1690 1.1.1.8 christos "%s iasl -e ssdt*.aml -d dsdt.aml\n",
1691 1.1.1.8 christos Format, Format, Format, Format, Format, Format);
1692 1.1.1.8 christos
1693 1.1.1.8 christos sprintf (ExternalWarningPart3,
1694 1.1.1.8 christos "%s In addition, the -fe option can be used to specify a file containing\n"
1695 1.1.1.8 christos "%s control method external declarations with the associated method\n"
1696 1.1.1.8 christos "%s argument counts. Each line of the file must be of the form:\n"
1697 1.1.1.8 christos "%s External (<method pathname>, MethodObj, <argument count>)\n"
1698 1.1.1.8 christos "%s Invocation:\n"
1699 1.1.1.8 christos "%s iasl -fe refs.txt -d dsdt.aml\n",
1700 1.1.1.8 christos Format, Format, Format, Format, Format, Format);
1701 1.1.1.8 christos
1702 1.1.1.8 christos sprintf (ExternalWarningPart4,
1703 1.1.1.8 christos "%s The following methods were unresolved and many not compile properly\n"
1704 1.1.1.8 christos "%s because the disassembler had to guess at the number of arguments\n"
1705 1.1.1.8 christos "%s required for each:\n",
1706 1.1.1.8 christos Format, Format, Format);
1707 1.1.1.8 christos
1708 1.1.1.3 christos if (Type)
1709 1.1.1.3 christos {
1710 1.1.1.3 christos if (!AcpiGbl_ExternalFileList)
1711 1.1.1.3 christos {
1712 1.1.1.3 christos /* The -e option was not specified */
1713 1.1.1.3 christos
1714 1.1.1.8 christos AcpiOsPrintf (" /*\n%s *\n%s *\n%s *\n%s */\n",
1715 1.1.1.8 christos ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3,
1716 1.1.1.8 christos ExternalWarningPart4);
1717 1.1.1.3 christos }
1718 1.1.1.8 christos else
1719 1.1.1.3 christos {
1720 1.1.1.3 christos /* The -e option was specified, but there are still some unresolved externals */
1721 1.1.1.3 christos
1722 1.1.1.8 christos AcpiOsPrintf (" /*\n%s *\n%s *\n%s */\n",
1723 1.1.1.8 christos ExternalWarningPart1, ExternalWarningPart3, ExternalWarningPart4);
1724 1.1.1.3 christos }
1725 1.1.1.3 christos }
1726 1.1.1.3 christos else
1727 1.1.1.3 christos {
1728 1.1.1.3 christos if (!AcpiGbl_ExternalFileList)
1729 1.1.1.3 christos {
1730 1.1.1.3 christos /* The -e option was not specified */
1731 1.1.1.3 christos
1732 1.1.1.8 christos fprintf (stderr, "\n%s\n%s\n%s\n",
1733 1.1.1.8 christos ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3);
1734 1.1.1.3 christos }
1735 1.1.1.8 christos else
1736 1.1.1.3 christos {
1737 1.1.1.3 christos /* The -e option was specified, but there are still some unresolved externals */
1738 1.1.1.3 christos
1739 1.1.1.8 christos fprintf (stderr, "\n%s\n%s\n",
1740 1.1.1.8 christos ExternalWarningPart1, ExternalWarningPart3);
1741 1.1.1.3 christos }
1742 1.1.1.3 christos }
1743 1.1.1.3 christos }
1744