Deleted Added
full compact
asllookup.c (241973) asllookup.c (243347)
1/******************************************************************************
2 *
3 * Module Name: asllookup- Namespace lookup
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45#include <contrib/dev/acpica/compiler/aslcompiler.h>
46#include "aslcompiler.y.h"
47
48#include <contrib/dev/acpica/include/acparser.h>
49#include <contrib/dev/acpica/include/amlcode.h>
50#include <contrib/dev/acpica/include/acnamesp.h>
51#include <contrib/dev/acpica/include/acdispat.h>
52
53
54#define _COMPONENT ACPI_COMPILER
55 ACPI_MODULE_NAME ("asllookup")
56
57/* Local prototypes */
58
59static ACPI_STATUS
60LsCompareOneNamespaceObject (
61 ACPI_HANDLE ObjHandle,
62 UINT32 Level,
63 void *Context,
64 void **ReturnValue);
65
66static ACPI_STATUS
67LsDoOneNamespaceObject (
68 ACPI_HANDLE ObjHandle,
69 UINT32 Level,
70 void *Context,
71 void **ReturnValue);
72
73static BOOLEAN
74LkObjectExists (
75 char *Name);
76
77static void
78LkCheckFieldRange (
79 ACPI_PARSE_OBJECT *Op,
80 UINT32 RegionBitLength,
81 UINT32 FieldBitOffset,
82 UINT32 FieldBitLength,
83 UINT32 AccessBitWidth);
84
85static ACPI_STATUS
86LkNamespaceLocateBegin (
87 ACPI_PARSE_OBJECT *Op,
88 UINT32 Level,
89 void *Context);
90
91static ACPI_STATUS
92LkNamespaceLocateEnd (
93 ACPI_PARSE_OBJECT *Op,
94 UINT32 Level,
95 void *Context);
96
97static ACPI_STATUS
98LkIsObjectUsed (
99 ACPI_HANDLE ObjHandle,
100 UINT32 Level,
101 void *Context,
102 void **ReturnValue);
103
104static ACPI_STATUS
105LsDoOnePathname (
106 ACPI_HANDLE ObjHandle,
107 UINT32 Level,
108 void *Context,
109 void **ReturnValue);
110
111static ACPI_PARSE_OBJECT *
112LkGetNameOp (
113 ACPI_PARSE_OBJECT *Op);
114
115
116/*******************************************************************************
117 *
118 * FUNCTION: LsDoOneNamespaceObject
119 *
120 * PARAMETERS: ACPI_WALK_CALLBACK
121 *
122 * RETURN: Status
123 *
124 * DESCRIPTION: Dump a namespace object to the namespace output file.
125 * Called during the walk of the namespace to dump all objects.
126 *
127 ******************************************************************************/
128
129static ACPI_STATUS
130LsDoOneNamespaceObject (
131 ACPI_HANDLE ObjHandle,
132 UINT32 Level,
133 void *Context,
134 void **ReturnValue)
135{
136 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
137 ACPI_OPERAND_OBJECT *ObjDesc;
138 ACPI_PARSE_OBJECT *Op;
139
140
141 Gbl_NumNamespaceObjects++;
142
143 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5u [%u] %*s %4.4s - %s",
144 Gbl_NumNamespaceObjects, Level, (Level * 3), " ",
145 &Node->Name,
146 AcpiUtGetTypeName (Node->Type));
147
148 Op = Node->Op;
149 ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Node->Object);
150
151 if (!Op)
152 {
153 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
154 return (AE_OK);
155 }
156
157
158 if ((ObjDesc) &&
159 (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND))
160 {
161 switch (Node->Type)
162 {
163 case ACPI_TYPE_INTEGER:
164
165 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
166 " [Initial Value 0x%8.8X%8.8X]",
167 ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
168 break;
169
170
171 case ACPI_TYPE_STRING:
172
173 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
174 " [Initial Value \"%s\"]",
175 ObjDesc->String.Pointer);
176 break;
177
178 default:
179 /* Nothing to do for other types */
180 break;
181 }
182
183 }
184 else
185 {
186 switch (Node->Type)
187 {
188 case ACPI_TYPE_INTEGER:
189
190 if (Op->Asl.ParseOpcode == PARSEOP_NAME)
191 {
192 Op = Op->Asl.Child;
193 }
194 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
195 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
196 {
197 Op = Op->Asl.Next;
198 }
199 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
200 " [Initial Value 0x%8.8X%8.8X]",
201 ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
202 break;
203
204
205 case ACPI_TYPE_STRING:
206
207 if (Op->Asl.ParseOpcode == PARSEOP_NAME)
208 {
209 Op = Op->Asl.Child;
210 }
211 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
212 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
213 {
214 Op = Op->Asl.Next;
215 }
216 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
217 " [Initial Value \"%s\"]",
218 Op->Asl.Value.String);
219 break;
220
221
222 case ACPI_TYPE_LOCAL_REGION_FIELD:
223
224 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
225 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
226 {
227 Op = Op->Asl.Child;
228 }
229 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
230 " [Offset 0x%04X Length 0x%04X bits]",
231 Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer);
232 break;
233
234
235 case ACPI_TYPE_BUFFER_FIELD:
236
237 switch (Op->Asl.ParseOpcode)
238 {
239 case PARSEOP_CREATEBYTEFIELD:
240 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [BYTE ( 8 bit)]");
241 break;
242
243 case PARSEOP_CREATEDWORDFIELD:
244 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [DWORD (32 bit)]");
245 break;
246
247 case PARSEOP_CREATEQWORDFIELD:
248 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [QWORD (64 bit)]");
249 break;
250
251 case PARSEOP_CREATEWORDFIELD:
252 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [WORD (16 bit)]");
253 break;
254
255 case PARSEOP_CREATEBITFIELD:
256 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [BIT ( 1 bit)]");
257 break;
258
259 case PARSEOP_CREATEFIELD:
260 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [Arbitrary Bit Field]");
261 break;
262
263 default:
264 break;
265
266 }
267 break;
268
269
270 case ACPI_TYPE_PACKAGE:
271
272 if (Op->Asl.ParseOpcode == PARSEOP_NAME)
273 {
274 Op = Op->Asl.Child;
275 }
276 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
277 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
278 {
279 Op = Op->Asl.Next;
280 }
281 Op = Op->Asl.Child;
282
283 if ((Op->Asl.ParseOpcode == PARSEOP_BYTECONST) ||
284 (Op->Asl.ParseOpcode == PARSEOP_RAW_DATA))
285 {
286 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
287 " [Initial Length 0x%.2X elements]",
288 Op->Asl.Value.Integer);
289 }
290 break;
291
292
293 case ACPI_TYPE_BUFFER:
294
295 if (Op->Asl.ParseOpcode == PARSEOP_NAME)
296 {
297 Op = Op->Asl.Child;
298 }
299 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
300 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
301 {
302 Op = Op->Asl.Next;
303 }
304 Op = Op->Asl.Child;
305
306 if (Op && (Op->Asl.ParseOpcode == PARSEOP_INTEGER))
307 {
308 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
309 " [Initial Length 0x%.2X bytes]",
310 Op->Asl.Value.Integer);
311 }
312 break;
313
314
315 case ACPI_TYPE_METHOD:
316
317 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
318 " [Code Length 0x%.4X bytes]",
319 Op->Asl.AmlSubtreeLength);
320 break;
321
322
323 case ACPI_TYPE_LOCAL_RESOURCE:
324
325 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
326 " [Desc Offset 0x%.4X Bytes]", Node->Value);
327 break;
328
329
330 case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
331
1/******************************************************************************
2 *
3 * Module Name: asllookup- Namespace lookup
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45#include <contrib/dev/acpica/compiler/aslcompiler.h>
46#include "aslcompiler.y.h"
47
48#include <contrib/dev/acpica/include/acparser.h>
49#include <contrib/dev/acpica/include/amlcode.h>
50#include <contrib/dev/acpica/include/acnamesp.h>
51#include <contrib/dev/acpica/include/acdispat.h>
52
53
54#define _COMPONENT ACPI_COMPILER
55 ACPI_MODULE_NAME ("asllookup")
56
57/* Local prototypes */
58
59static ACPI_STATUS
60LsCompareOneNamespaceObject (
61 ACPI_HANDLE ObjHandle,
62 UINT32 Level,
63 void *Context,
64 void **ReturnValue);
65
66static ACPI_STATUS
67LsDoOneNamespaceObject (
68 ACPI_HANDLE ObjHandle,
69 UINT32 Level,
70 void *Context,
71 void **ReturnValue);
72
73static BOOLEAN
74LkObjectExists (
75 char *Name);
76
77static void
78LkCheckFieldRange (
79 ACPI_PARSE_OBJECT *Op,
80 UINT32 RegionBitLength,
81 UINT32 FieldBitOffset,
82 UINT32 FieldBitLength,
83 UINT32 AccessBitWidth);
84
85static ACPI_STATUS
86LkNamespaceLocateBegin (
87 ACPI_PARSE_OBJECT *Op,
88 UINT32 Level,
89 void *Context);
90
91static ACPI_STATUS
92LkNamespaceLocateEnd (
93 ACPI_PARSE_OBJECT *Op,
94 UINT32 Level,
95 void *Context);
96
97static ACPI_STATUS
98LkIsObjectUsed (
99 ACPI_HANDLE ObjHandle,
100 UINT32 Level,
101 void *Context,
102 void **ReturnValue);
103
104static ACPI_STATUS
105LsDoOnePathname (
106 ACPI_HANDLE ObjHandle,
107 UINT32 Level,
108 void *Context,
109 void **ReturnValue);
110
111static ACPI_PARSE_OBJECT *
112LkGetNameOp (
113 ACPI_PARSE_OBJECT *Op);
114
115
116/*******************************************************************************
117 *
118 * FUNCTION: LsDoOneNamespaceObject
119 *
120 * PARAMETERS: ACPI_WALK_CALLBACK
121 *
122 * RETURN: Status
123 *
124 * DESCRIPTION: Dump a namespace object to the namespace output file.
125 * Called during the walk of the namespace to dump all objects.
126 *
127 ******************************************************************************/
128
129static ACPI_STATUS
130LsDoOneNamespaceObject (
131 ACPI_HANDLE ObjHandle,
132 UINT32 Level,
133 void *Context,
134 void **ReturnValue)
135{
136 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
137 ACPI_OPERAND_OBJECT *ObjDesc;
138 ACPI_PARSE_OBJECT *Op;
139
140
141 Gbl_NumNamespaceObjects++;
142
143 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5u [%u] %*s %4.4s - %s",
144 Gbl_NumNamespaceObjects, Level, (Level * 3), " ",
145 &Node->Name,
146 AcpiUtGetTypeName (Node->Type));
147
148 Op = Node->Op;
149 ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Node->Object);
150
151 if (!Op)
152 {
153 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
154 return (AE_OK);
155 }
156
157
158 if ((ObjDesc) &&
159 (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND))
160 {
161 switch (Node->Type)
162 {
163 case ACPI_TYPE_INTEGER:
164
165 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
166 " [Initial Value 0x%8.8X%8.8X]",
167 ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
168 break;
169
170
171 case ACPI_TYPE_STRING:
172
173 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
174 " [Initial Value \"%s\"]",
175 ObjDesc->String.Pointer);
176 break;
177
178 default:
179 /* Nothing to do for other types */
180 break;
181 }
182
183 }
184 else
185 {
186 switch (Node->Type)
187 {
188 case ACPI_TYPE_INTEGER:
189
190 if (Op->Asl.ParseOpcode == PARSEOP_NAME)
191 {
192 Op = Op->Asl.Child;
193 }
194 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
195 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
196 {
197 Op = Op->Asl.Next;
198 }
199 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
200 " [Initial Value 0x%8.8X%8.8X]",
201 ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
202 break;
203
204
205 case ACPI_TYPE_STRING:
206
207 if (Op->Asl.ParseOpcode == PARSEOP_NAME)
208 {
209 Op = Op->Asl.Child;
210 }
211 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
212 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
213 {
214 Op = Op->Asl.Next;
215 }
216 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
217 " [Initial Value \"%s\"]",
218 Op->Asl.Value.String);
219 break;
220
221
222 case ACPI_TYPE_LOCAL_REGION_FIELD:
223
224 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
225 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
226 {
227 Op = Op->Asl.Child;
228 }
229 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
230 " [Offset 0x%04X Length 0x%04X bits]",
231 Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer);
232 break;
233
234
235 case ACPI_TYPE_BUFFER_FIELD:
236
237 switch (Op->Asl.ParseOpcode)
238 {
239 case PARSEOP_CREATEBYTEFIELD:
240 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [BYTE ( 8 bit)]");
241 break;
242
243 case PARSEOP_CREATEDWORDFIELD:
244 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [DWORD (32 bit)]");
245 break;
246
247 case PARSEOP_CREATEQWORDFIELD:
248 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [QWORD (64 bit)]");
249 break;
250
251 case PARSEOP_CREATEWORDFIELD:
252 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [WORD (16 bit)]");
253 break;
254
255 case PARSEOP_CREATEBITFIELD:
256 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [BIT ( 1 bit)]");
257 break;
258
259 case PARSEOP_CREATEFIELD:
260 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, " [Arbitrary Bit Field]");
261 break;
262
263 default:
264 break;
265
266 }
267 break;
268
269
270 case ACPI_TYPE_PACKAGE:
271
272 if (Op->Asl.ParseOpcode == PARSEOP_NAME)
273 {
274 Op = Op->Asl.Child;
275 }
276 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
277 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
278 {
279 Op = Op->Asl.Next;
280 }
281 Op = Op->Asl.Child;
282
283 if ((Op->Asl.ParseOpcode == PARSEOP_BYTECONST) ||
284 (Op->Asl.ParseOpcode == PARSEOP_RAW_DATA))
285 {
286 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
287 " [Initial Length 0x%.2X elements]",
288 Op->Asl.Value.Integer);
289 }
290 break;
291
292
293 case ACPI_TYPE_BUFFER:
294
295 if (Op->Asl.ParseOpcode == PARSEOP_NAME)
296 {
297 Op = Op->Asl.Child;
298 }
299 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
300 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
301 {
302 Op = Op->Asl.Next;
303 }
304 Op = Op->Asl.Child;
305
306 if (Op && (Op->Asl.ParseOpcode == PARSEOP_INTEGER))
307 {
308 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
309 " [Initial Length 0x%.2X bytes]",
310 Op->Asl.Value.Integer);
311 }
312 break;
313
314
315 case ACPI_TYPE_METHOD:
316
317 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
318 " [Code Length 0x%.4X bytes]",
319 Op->Asl.AmlSubtreeLength);
320 break;
321
322
323 case ACPI_TYPE_LOCAL_RESOURCE:
324
325 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
326 " [Desc Offset 0x%.4X Bytes]", Node->Value);
327 break;
328
329
330 case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
331
332 if (Node->Flags & 0x80)
332 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
333 " [Field Offset 0x%.4X Bits 0x%.4X Bytes] ",
334 Node->Value, Node->Value / 8);
335
336 if (Node->Flags & ANOBJ_IS_REFERENCED)
333 {
334 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
337 {
338 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
335 " [Field Offset 0x%.4X Bits 0x%.4X Bytes]",
336 Node->Value, Node->Value / 8);
339 "Referenced");
337 }
338 else
339 {
340 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
340 }
341 else
342 {
343 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
341 " [Field Offset 0x%.4X Bytes]", Node->Value);
344 "Name not referenced");
342 }
343 break;
344
345
346 default:
347 /* Nothing to do for other types */
348 break;
349 }
350 }
351
352 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
353 return (AE_OK);
354}
355
356
357/*******************************************************************************
358 *
359 * FUNCTION: LsSetupNsList
360 *
361 * PARAMETERS: Handle - local file handle
362 *
363 * RETURN: None
364 *
365 * DESCRIPTION: Set the namespace output file to the input handle
366 *
367 ******************************************************************************/
368
369void
370LsSetupNsList (
371 void *Handle)
372{
373
374 Gbl_NsOutputFlag = TRUE;
375 Gbl_Files[ASL_FILE_NAMESPACE_OUTPUT].Handle = Handle;
376}
377
378
379/*******************************************************************************
380 *
381 * FUNCTION: LsDoOnePathname
382 *
383 * PARAMETERS: ACPI_WALK_CALLBACK
384 *
385 * RETURN: Status
386 *
387 * DESCRIPTION: Print the full pathname for a namespace node.
388 *
389 ******************************************************************************/
390
391static ACPI_STATUS
392LsDoOnePathname (
393 ACPI_HANDLE ObjHandle,
394 UINT32 Level,
395 void *Context,
396 void **ReturnValue)
397{
398 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
399 ACPI_STATUS Status;
400 ACPI_BUFFER TargetPath;
401
402
403 TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
404 Status = AcpiNsHandleToPathname (Node, &TargetPath);
405 if (ACPI_FAILURE (Status))
406 {
407 return (Status);
408 }
409
410 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%s\n", TargetPath.Pointer);
411 ACPI_FREE (TargetPath.Pointer);
412
413 return (AE_OK);
414}
415
416
417/*******************************************************************************
418 *
419 * FUNCTION: LsDisplayNamespace
420 *
421 * PARAMETERS: None
422 *
423 * RETURN: Status
424 *
425 * DESCRIPTION: Walk the namespace an display information about each node
426 * in the tree. Information is written to the optional
427 * namespace output file.
428 *
429 ******************************************************************************/
430
431ACPI_STATUS
432LsDisplayNamespace (
433 void)
434{
435 ACPI_STATUS Status;
436
437
438 if (!Gbl_NsOutputFlag)
439 {
440 return (AE_OK);
441 }
442
443 Gbl_NumNamespaceObjects = 0;
444
445 /* File header */
446
447 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n");
448 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count Depth Name - Type\n\n");
449
450 /* Walk entire namespace from the root */
451
452 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
453 ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, NULL,
454 NULL, NULL);
455
456 /* Print the full pathname for each namespace node */
457
458 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\nNamespace pathnames\n\n");
459
460 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
461 ACPI_UINT32_MAX, FALSE, LsDoOnePathname, NULL,
462 NULL, NULL);
463
464 return (Status);
465}
466
467
468/*******************************************************************************
469 *
470 * FUNCTION: LsCompareOneNamespaceObject
471 *
472 * PARAMETERS: ACPI_WALK_CALLBACK
473 *
474 * RETURN: Status
475 *
476 * DESCRIPTION: Compare name of one object.
477 *
478 ******************************************************************************/
479
480static ACPI_STATUS
481LsCompareOneNamespaceObject (
482 ACPI_HANDLE ObjHandle,
483 UINT32 Level,
484 void *Context,
485 void **ReturnValue)
486{
487 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
488
489
490 /* Simply check the name */
491
492 if (*((UINT32 *) (Context)) == Node->Name.Integer)
493 {
494 /* Abort walk if we found one instance */
495
496 return (AE_CTRL_TRUE);
497 }
498
499 return (AE_OK);
500}
501
502
503/*******************************************************************************
504 *
505 * FUNCTION: LkObjectExists
506 *
507 * PARAMETERS: Name - 4 char ACPI name
508 *
509 * RETURN: TRUE if name exists in namespace
510 *
511 * DESCRIPTION: Walk the namespace to find an object
512 *
513 ******************************************************************************/
514
515static BOOLEAN
516LkObjectExists (
517 char *Name)
518{
519 ACPI_STATUS Status;
520
521
522 /* Walk entire namespace from the supplied root */
523
524 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
525 ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject, NULL,
526 Name, NULL);
527 if (Status == AE_CTRL_TRUE)
528 {
529 /* At least one instance of the name was found */
530
531 return (TRUE);
532 }
533
534 return (FALSE);
535}
536
537
538/*******************************************************************************
539 *
540 * FUNCTION: LkGetNameOp
541 *
542 * PARAMETERS: Op - Current Op
543 *
544 * RETURN: NameOp associated with the input op
545 *
546 * DESCRIPTION: Find the name declaration op associated with the operator
547 *
548 ******************************************************************************/
549
550static ACPI_PARSE_OBJECT *
551LkGetNameOp (
552 ACPI_PARSE_OBJECT *Op)
553{
554 const ACPI_OPCODE_INFO *OpInfo;
555 ACPI_PARSE_OBJECT *NameOp = Op;
556
557
558 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
559
560
561 /* Get the NamePath from the appropriate place */
562
563 if (OpInfo->Flags & AML_NAMED)
564 {
565 /* For nearly all NAMED operators, the name reference is the first child */
566
567 NameOp = Op->Asl.Child;
568 if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
569 {
570 /*
571 * ALIAS is the only oddball opcode, the name declaration
572 * (alias name) is the second operand
573 */
574 NameOp = Op->Asl.Child->Asl.Next;
575 }
576 }
577 else if (OpInfo->Flags & AML_CREATE)
578 {
579 /* Name must appear as the last parameter */
580
581 NameOp = Op->Asl.Child;
582 while (!(NameOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
583 {
584 NameOp = NameOp->Asl.Next;
585 }
586 }
587
588 return (NameOp);
589}
590
591
592/*******************************************************************************
593 *
594 * FUNCTION: LkIsObjectUsed
595 *
596 * PARAMETERS: ACPI_WALK_CALLBACK
597 *
598 * RETURN: Status
599 *
600 * DESCRIPTION: Check for an unreferenced namespace object and emit a warning.
601 * We have to be careful, because some types and names are
602 * typically or always unreferenced, we don't want to issue
603 * excessive warnings.
604 *
605 ******************************************************************************/
606
607static ACPI_STATUS
608LkIsObjectUsed (
609 ACPI_HANDLE ObjHandle,
610 UINT32 Level,
611 void *Context,
612 void **ReturnValue)
613{
614 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
615
616
617 /* Referenced flag is set during the namespace xref */
618
619 if (Node->Flags & ANOBJ_IS_REFERENCED)
620 {
621 return (AE_OK);
622 }
623
624 /*
625 * Ignore names that start with an underscore,
626 * these are the reserved ACPI names and are typically not referenced,
627 * they are called by the host OS.
628 */
629 if (Node->Name.Ascii[0] == '_')
630 {
631 return (AE_OK);
632 }
633
634 /* There are some types that are typically not referenced, ignore them */
635
636 switch (Node->Type)
637 {
638 case ACPI_TYPE_DEVICE:
639 case ACPI_TYPE_PROCESSOR:
640 case ACPI_TYPE_POWER:
641 case ACPI_TYPE_LOCAL_RESOURCE:
642 return (AE_OK);
643
644 default:
645 break;
646 }
647
648 /* All others are valid unreferenced namespace objects */
649
650 if (Node->Op)
651 {
652 AslError (ASL_WARNING2, ASL_MSG_NOT_REFERENCED, LkGetNameOp (Node->Op), NULL);
653 }
654 return (AE_OK);
655}
656
657
658/*******************************************************************************
659 *
660 * FUNCTION: LkFindUnreferencedObjects
661 *
662 * PARAMETERS: None
663 *
664 * RETURN: None
665 *
666 * DESCRIPTION: Namespace walk to find objects that are not referenced in any
667 * way. Must be called after the namespace has been cross
668 * referenced.
669 *
670 ******************************************************************************/
671
672void
673LkFindUnreferencedObjects (
674 void)
675{
676
677 /* Walk entire namespace from the supplied root */
678
679 (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
680 ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, NULL,
681 NULL, NULL);
682}
683
684
685/*******************************************************************************
686 *
687 * FUNCTION: LkCrossReferenceNamespace
688 *
689 * PARAMETERS: None
690 *
691 * RETURN: Status
692 *
693 * DESCRIPTION: Perform a cross reference check of the parse tree against the
694 * namespace. Every named referenced within the parse tree
695 * should be get resolved with a namespace lookup. If not, the
696 * original reference in the ASL code is invalid -- i.e., refers
697 * to a non-existent object.
698 *
699 * NOTE: The ASL "External" operator causes the name to be inserted into the
700 * namespace so that references to the external name will be resolved
701 * correctly here.
702 *
703 ******************************************************************************/
704
705ACPI_STATUS
706LkCrossReferenceNamespace (
707 void)
708{
709 ACPI_WALK_STATE *WalkState;
710
711
712 DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n");
713
714 /*
715 * Create a new walk state for use when looking up names
716 * within the namespace (Passed as context to the callbacks)
717 */
718 WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
719 if (!WalkState)
720 {
721 return (AE_NO_MEMORY);
722 }
723
724 /* Walk the entire parse tree */
725
726 TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, LkNamespaceLocateBegin,
727 LkNamespaceLocateEnd, WalkState);
728 return (AE_OK);
729}
730
731
732/*******************************************************************************
733 *
734 * FUNCTION: LkCheckFieldRange
735 *
736 * PARAMETERS: RegionBitLength - Length of entire parent region
737 * FieldBitOffset - Start of the field unit (within region)
738 * FieldBitLength - Entire length of field unit
739 * AccessBitWidth - Access width of the field unit
740 *
741 * RETURN: None
742 *
743 * DESCRIPTION: Check one field unit to make sure it fits in the parent
744 * op region.
745 *
746 * Note: AccessBitWidth must be either 8,16,32, or 64
747 *
748 ******************************************************************************/
749
750static void
751LkCheckFieldRange (
752 ACPI_PARSE_OBJECT *Op,
753 UINT32 RegionBitLength,
754 UINT32 FieldBitOffset,
755 UINT32 FieldBitLength,
756 UINT32 AccessBitWidth)
757{
758 UINT32 FieldEndBitOffset;
759
760
761 /*
762 * Check each field unit against the region size. The entire
763 * field unit (start offset plus length) must fit within the
764 * region.
765 */
766 FieldEndBitOffset = FieldBitOffset + FieldBitLength;
767
768 if (FieldEndBitOffset > RegionBitLength)
769 {
770 /* Field definition itself is beyond the end-of-region */
771
772 AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
773 return;
774 }
775
776 /*
777 * Now check that the field plus AccessWidth doesn't go beyond
778 * the end-of-region. Assumes AccessBitWidth is a power of 2
779 */
780 FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
781
782 if (FieldEndBitOffset > RegionBitLength)
783 {
784 /* Field definition combined with the access is beyond EOR */
785
786 AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
787 }
788}
789
790/*******************************************************************************
791 *
792 * FUNCTION: LkNamespaceLocateBegin
793 *
794 * PARAMETERS: ASL_WALK_CALLBACK
795 *
796 * RETURN: Status
797 *
798 * DESCRIPTION: Descending callback used during cross-reference. For named
799 * object references, attempt to locate the name in the
800 * namespace.
801 *
802 * NOTE: ASL references to named fields within resource descriptors are
803 * resolved to integer values here. Therefore, this step is an
804 * important part of the code generation. We don't know that the
805 * name refers to a resource descriptor until now.
806 *
807 ******************************************************************************/
808
809static ACPI_STATUS
810LkNamespaceLocateBegin (
811 ACPI_PARSE_OBJECT *Op,
812 UINT32 Level,
813 void *Context)
814{
815 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context;
816 ACPI_NAMESPACE_NODE *Node;
817 ACPI_STATUS Status;
818 ACPI_OBJECT_TYPE ObjectType;
819 char *Path;
820 UINT8 PassedArgs;
821 ACPI_PARSE_OBJECT *NextOp;
822 ACPI_PARSE_OBJECT *OwningOp;
823 ACPI_PARSE_OBJECT *SpaceIdOp;
824 UINT32 MinimumLength;
825 UINT32 Offset;
826 UINT32 FieldBitLength;
827 UINT32 TagBitLength;
828 UINT8 Message = 0;
829 const ACPI_OPCODE_INFO *OpInfo;
830 UINT32 Flags;
831
832
833 ACPI_FUNCTION_TRACE_PTR (LkNamespaceLocateBegin, Op);
834
835 /*
836 * If this node is the actual declaration of a name
837 * [such as the XXXX name in "Method (XXXX)"],
838 * we are not interested in it here. We only care about names that are
839 * references to other objects within the namespace and the parent objects
840 * of name declarations
841 */
842 if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
843 {
844 return (AE_OK);
845 }
846
847 /* We are only interested in opcodes that have an associated name */
848
849 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
850
851 if ((!(OpInfo->Flags & AML_NAMED)) &&
852 (!(OpInfo->Flags & AML_CREATE)) &&
853 (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
854 (Op->Asl.ParseOpcode != PARSEOP_NAMESEG) &&
855 (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
856 {
857 return (AE_OK);
858 }
859
860 /*
861 * One special case: CondRefOf operator - we don't care if the name exists
862 * or not at this point, just ignore it, the point of the operator is to
863 * determine if the name exists at runtime.
864 */
865 if ((Op->Asl.Parent) &&
866 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))
867 {
868 return (AE_OK);
869 }
870
871 /*
872 * We must enable the "search-to-root" for single NameSegs, but
873 * we have to be very careful about opening up scopes
874 */
875 Flags = ACPI_NS_SEARCH_PARENT;
876 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
877 (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
878 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
879 {
880 /*
881 * These are name references, do not push the scope stack
882 * for them.
883 */
884 Flags |= ACPI_NS_DONT_OPEN_SCOPE;
885 }
886
887 /* Get the NamePath from the appropriate place */
888
889 if (OpInfo->Flags & AML_NAMED)
890 {
891 /* For nearly all NAMED operators, the name reference is the first child */
892
893 Path = Op->Asl.Child->Asl.Value.String;
894 if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
895 {
896 /*
897 * ALIAS is the only oddball opcode, the name declaration
898 * (alias name) is the second operand
899 */
900 Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
901 }
902 }
903 else if (OpInfo->Flags & AML_CREATE)
904 {
905 /* Name must appear as the last parameter */
906
907 NextOp = Op->Asl.Child;
908 while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
909 {
910 NextOp = NextOp->Asl.Next;
911 }
912 Path = NextOp->Asl.Value.String;
913 }
914 else
915 {
916 Path = Op->Asl.Value.String;
917 }
918
919 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
920 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
921 "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
922
923 /*
924 * Lookup the name in the namespace. Name must exist at this point, or it
925 * is an invalid reference.
926 *
927 * The namespace is also used as a lookup table for references to resource
928 * descriptors and the fields within them.
929 */
930 Gbl_NsLookupCount++;
931
932 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
933 ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node));
934 if (ACPI_FAILURE (Status))
935 {
936 if (Status == AE_NOT_FOUND)
937 {
938 /*
939 * We didn't find the name reference by path -- we can qualify this
940 * a little better before we print an error message
941 */
942 if (strlen (Path) == ACPI_NAME_SIZE)
943 {
944 /* A simple, one-segment ACPI name */
945
946 if (LkObjectExists (Path))
947 {
948 /*
949 * There exists such a name, but we couldn't get to it
950 * from this scope
951 */
952 AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op,
953 Op->Asl.ExternalName);
954 }
955 else
956 {
957 /* The name doesn't exist, period */
958
959 AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,
960 Op, Op->Asl.ExternalName);
961 }
962 }
963 else
964 {
965 /* Check for a fully qualified path */
966
967 if (Path[0] == AML_ROOT_PREFIX)
968 {
969 /* Gave full path, the object does not exist */
970
971 AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,
972 Op->Asl.ExternalName);
973 }
974 else
975 {
976 /*
977 * We can't tell whether it doesn't exist or just
978 * can't be reached.
979 */
980 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
981 Op->Asl.ExternalName);
982 }
983 }
984
985 Status = AE_OK;
986 }
987 return (Status);
988 }
989
990 /* Check for a reference vs. name declaration */
991
992 if (!(OpInfo->Flags & AML_NAMED) &&
993 !(OpInfo->Flags & AML_CREATE))
994 {
995 /* This node has been referenced, mark it for reference check */
996
997 Node->Flags |= ANOBJ_IS_REFERENCED;
998 }
999
1000 /* Attempt to optimize the NamePath */
1001
1002 OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
1003
1004 /*
1005 * 1) Dereference an alias (A name reference that is an alias)
1006 * Aliases are not nested, the alias always points to the final object
1007 */
1008 if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) &&
1009 (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
1010 {
1011 /* This node points back to the original PARSEOP_ALIAS */
1012
1013 NextOp = Node->Op;
1014
1015 /* The first child is the alias target op */
1016
1017 NextOp = NextOp->Asl.Child;
1018
1019 /* That in turn points back to original target alias node */
1020
1021 if (NextOp->Asl.Node)
1022 {
1023 Node = NextOp->Asl.Node;
1024 }
1025
1026 /* Else - forward reference to alias, will be resolved later */
1027 }
1028
1029 /* 2) Check for a reference to a resource descriptor */
1030
1031 if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
1032 (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
1033 {
1034 /*
1035 * This was a reference to a field within a resource descriptor.
1036 * Extract the associated field offset (either a bit or byte
1037 * offset depending on the field type) and change the named
1038 * reference into an integer for AML code generation
1039 */
1040 Offset = Node->Value;
1041 TagBitLength = Node->Length;
1042
1043 /*
1044 * If a field is being created, generate the length (in bits) of
1045 * the field. Note: Opcodes other than CreateXxxField and Index
1046 * can come through here. For other opcodes, we just need to
1047 * convert the resource tag reference to an integer offset.
1048 */
1049 switch (Op->Asl.Parent->Asl.AmlOpcode)
1050 {
1051 case AML_CREATE_FIELD_OP: /* Variable "Length" field, in bits */
1052 /*
1053 * We know the length operand is an integer constant because
1054 * we know that it contains a reference to a resource
1055 * descriptor tag.
1056 */
1057 FieldBitLength = (UINT32) Op->Asl.Next->Asl.Value.Integer;
1058 break;
1059
1060 case AML_CREATE_BIT_FIELD_OP:
1061 FieldBitLength = 1;
1062 break;
1063
1064 case AML_CREATE_BYTE_FIELD_OP:
1065 case AML_INDEX_OP:
1066 FieldBitLength = 8;
1067 break;
1068
1069 case AML_CREATE_WORD_FIELD_OP:
1070 FieldBitLength = 16;
1071 break;
1072
1073 case AML_CREATE_DWORD_FIELD_OP:
1074 FieldBitLength = 32;
1075 break;
1076
1077 case AML_CREATE_QWORD_FIELD_OP:
1078 FieldBitLength = 64;
1079 break;
1080
1081 default:
1082 FieldBitLength = 0;
1083 break;
1084 }
1085
1086 /* Check the field length against the length of the resource tag */
1087
1088 if (FieldBitLength)
1089 {
1090 if (TagBitLength < FieldBitLength)
1091 {
1092 Message = ASL_MSG_TAG_SMALLER;
1093 }
1094 else if (TagBitLength > FieldBitLength)
1095 {
1096 Message = ASL_MSG_TAG_LARGER;
1097 }
1098
1099 if (Message)
1100 {
1101 sprintf (MsgBuffer, "Size mismatch, Tag: %u bit%s, Field: %u bit%s",
1102 TagBitLength, (TagBitLength > 1) ? "s" : "",
1103 FieldBitLength, (FieldBitLength > 1) ? "s" : "");
1104
1105 AslError (ASL_WARNING, Message, Op, MsgBuffer);
1106 }
1107 }
1108
1109 /* Convert the BitOffset to a ByteOffset for certain opcodes */
1110
1111 switch (Op->Asl.Parent->Asl.AmlOpcode)
1112 {
1113 case AML_CREATE_BYTE_FIELD_OP:
1114 case AML_CREATE_WORD_FIELD_OP:
1115 case AML_CREATE_DWORD_FIELD_OP:
1116 case AML_CREATE_QWORD_FIELD_OP:
1117 case AML_INDEX_OP:
1118
1119 Offset = ACPI_DIV_8 (Offset);
1120 break;
1121
1122 default:
1123 break;
1124 }
1125
1126 /* Now convert this node to an integer whose value is the field offset */
1127
1128 Op->Asl.AmlLength = 0;
1129 Op->Asl.ParseOpcode = PARSEOP_INTEGER;
1130 Op->Asl.Value.Integer = (UINT64) Offset;
1131 Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD;
1132
1133 OpcGenerateAmlOpcode (Op);
1134 }
1135
1136 /* 3) Check for a method invocation */
1137
1138 else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
1139 (Node->Type == ACPI_TYPE_METHOD) &&
1140 (Op->Asl.Parent) &&
1141 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD)) ||
1142
1143 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
1144 {
1145
1146 /*
1147 * A reference to a method within one of these opcodes is not an
1148 * invocation of the method, it is simply a reference to the method.
1149 */
1150 if ((Op->Asl.Parent) &&
1151 ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF) ||
1152 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEREFOF) ||
1153 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE)))
1154 {
1155 return (AE_OK);
1156 }
1157 /*
1158 * There are two types of method invocation:
1159 * 1) Invocation with arguments -- the parser recognizes this
1160 * as a METHODCALL.
1161 * 2) Invocation with no arguments --the parser cannot determine that
1162 * this is a method invocation, therefore we have to figure it out
1163 * here.
1164 */
1165 if (Node->Type != ACPI_TYPE_METHOD)
1166 {
1167 sprintf (MsgBuffer, "%s is a %s",
1168 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
1169
1170 AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer);
1171 return (AE_OK);
1172 }
1173
1174 /* Save the method node in the caller's op */
1175
1176 Op->Asl.Node = Node;
1177 if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
1178 {
1179 return (AE_OK);
1180 }
1181
1182 /*
1183 * This is a method invocation, with or without arguments.
1184 * Count the number of arguments, each appears as a child
1185 * under the parent node
1186 */
1187 Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
1188 UtSetParseOpName (Op);
1189
1190 PassedArgs = 0;
1191 NextOp = Op->Asl.Child;
1192
1193 while (NextOp)
1194 {
1195 PassedArgs++;
1196 NextOp = NextOp->Asl.Next;
1197 }
1198
1199 if (Node->Value != ASL_EXTERNAL_METHOD)
1200 {
1201 /*
1202 * Check the parsed arguments with the number expected by the
1203 * method declaration itself
1204 */
1205 if (PassedArgs != Node->Value)
1206 {
1207 sprintf (MsgBuffer, "%s requires %u", Op->Asl.ExternalName,
1208 Node->Value);
1209
1210 if (PassedArgs < Node->Value)
1211 {
1212 AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer);
1213 }
1214 else
1215 {
1216 AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer);
1217 }
1218 }
1219 }
1220 }
1221
1222 /* 4) Check for an ASL Field definition */
1223
1224 else if ((Op->Asl.Parent) &&
1225 ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD) ||
1226 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
1227 {
1228 /*
1229 * Offset checking for fields. If the parent operation region has a
1230 * constant length (known at compile time), we can check fields
1231 * defined in that region against the region length. This will catch
1232 * fields and field units that cannot possibly fit within the region.
1233 *
1234 * Note: Index fields do not directly reference an operation region,
1235 * thus they are not included in this check.
1236 */
1237 if (Op == Op->Asl.Parent->Asl.Child)
1238 {
1239 /*
1240 * This is the first child of the field node, which is
1241 * the name of the region. Get the parse node for the
1242 * region -- which contains the length of the region.
1243 */
1244 OwningOp = Node->Op;
1245 Op->Asl.Parent->Asl.ExtraValue =
1246 ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
1247
1248 /* Examine the field access width */
1249
1250 switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
1251 {
1252 case AML_FIELD_ACCESS_ANY:
1253 case AML_FIELD_ACCESS_BYTE:
1254 case AML_FIELD_ACCESS_BUFFER:
1255 default:
1256 MinimumLength = 1;
1257 break;
1258
1259 case AML_FIELD_ACCESS_WORD:
1260 MinimumLength = 2;
1261 break;
1262
1263 case AML_FIELD_ACCESS_DWORD:
1264 MinimumLength = 4;
1265 break;
1266
1267 case AML_FIELD_ACCESS_QWORD:
1268 MinimumLength = 8;
1269 break;
1270 }
1271
1272 /*
1273 * Is the region at least as big as the access width?
1274 * Note: DataTableRegions have 0 length
1275 */
1276 if (((UINT32) OwningOp->Asl.Value.Integer) &&
1277 ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
1278 {
1279 AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
1280 }
1281
1282 /*
1283 * Check EC/CMOS/SMBUS fields to make sure that the correct
1284 * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
1285 */
1286 SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
1287 switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
1288 {
1289 case ACPI_ADR_SPACE_EC:
1290 case ACPI_ADR_SPACE_CMOS:
1291 case ACPI_ADR_SPACE_GPIO:
1292
1293 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE)
1294 {
1295 AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
1296 }
1297 break;
1298
1299 case ACPI_ADR_SPACE_SMBUS:
1300 case ACPI_ADR_SPACE_IPMI:
1301 case ACPI_ADR_SPACE_GSBUS:
1302
1303 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER)
1304 {
1305 AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
1306 }
1307 break;
1308
1309 default:
1310
1311 /* Nothing to do for other address spaces */
1312 break;
1313 }
1314 }
1315 else
1316 {
1317 /*
1318 * This is one element of the field list. Check to make sure
1319 * that it does not go beyond the end of the parent operation region.
1320 *
1321 * In the code below:
1322 * Op->Asl.Parent->Asl.ExtraValue - Region Length (bits)
1323 * Op->Asl.ExtraValue - Field start offset (bits)
1324 * Op->Asl.Child->Asl.Value.Integer32 - Field length (bits)
1325 * Op->Asl.Child->Asl.ExtraValue - Field access width (bits)
1326 */
1327 if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
1328 {
1329 LkCheckFieldRange (Op,
1330 Op->Asl.Parent->Asl.ExtraValue,
1331 Op->Asl.ExtraValue,
1332 (UINT32) Op->Asl.Child->Asl.Value.Integer,
1333 Op->Asl.Child->Asl.ExtraValue);
1334 }
1335 }
1336 }
1337
1338 Op->Asl.Node = Node;
1339 return (Status);
1340}
1341
1342
1343/*******************************************************************************
1344 *
1345 * FUNCTION: LkNamespaceLocateEnd
1346 *
1347 * PARAMETERS: ASL_WALK_CALLBACK
1348 *
1349 * RETURN: Status
1350 *
1351 * DESCRIPTION: Ascending callback used during cross reference. We only
1352 * need to worry about scope management here.
1353 *
1354 ******************************************************************************/
1355
1356static ACPI_STATUS
1357LkNamespaceLocateEnd (
1358 ACPI_PARSE_OBJECT *Op,
1359 UINT32 Level,
1360 void *Context)
1361{
1362 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context;
1363 const ACPI_OPCODE_INFO *OpInfo;
1364
1365
1366 ACPI_FUNCTION_TRACE (LkNamespaceLocateEnd);
1367
1368
1369 /* We are only interested in opcodes that have an associated name */
1370
1371 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
1372 if (!(OpInfo->Flags & AML_NAMED))
1373 {
1374 return (AE_OK);
1375 }
1376
1377 /* Not interested in name references, we did not open a scope for them */
1378
1379 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
1380 (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
1381 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
1382 {
1383 return (AE_OK);
1384 }
1385
1386 /* Pop the scope stack if necessary */
1387
1388 if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
1389 {
1390
1391 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1392 "%s: Popping scope for Op %p\n",
1393 AcpiUtGetTypeName (OpInfo->ObjectType), Op));
1394
1395 (void) AcpiDsScopeStackPop (WalkState);
1396 }
1397
1398 return (AE_OK);
1399}
345 }
346 break;
347
348
349 default:
350 /* Nothing to do for other types */
351 break;
352 }
353 }
354
355 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
356 return (AE_OK);
357}
358
359
360/*******************************************************************************
361 *
362 * FUNCTION: LsSetupNsList
363 *
364 * PARAMETERS: Handle - local file handle
365 *
366 * RETURN: None
367 *
368 * DESCRIPTION: Set the namespace output file to the input handle
369 *
370 ******************************************************************************/
371
372void
373LsSetupNsList (
374 void *Handle)
375{
376
377 Gbl_NsOutputFlag = TRUE;
378 Gbl_Files[ASL_FILE_NAMESPACE_OUTPUT].Handle = Handle;
379}
380
381
382/*******************************************************************************
383 *
384 * FUNCTION: LsDoOnePathname
385 *
386 * PARAMETERS: ACPI_WALK_CALLBACK
387 *
388 * RETURN: Status
389 *
390 * DESCRIPTION: Print the full pathname for a namespace node.
391 *
392 ******************************************************************************/
393
394static ACPI_STATUS
395LsDoOnePathname (
396 ACPI_HANDLE ObjHandle,
397 UINT32 Level,
398 void *Context,
399 void **ReturnValue)
400{
401 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
402 ACPI_STATUS Status;
403 ACPI_BUFFER TargetPath;
404
405
406 TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
407 Status = AcpiNsHandleToPathname (Node, &TargetPath);
408 if (ACPI_FAILURE (Status))
409 {
410 return (Status);
411 }
412
413 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%s\n", TargetPath.Pointer);
414 ACPI_FREE (TargetPath.Pointer);
415
416 return (AE_OK);
417}
418
419
420/*******************************************************************************
421 *
422 * FUNCTION: LsDisplayNamespace
423 *
424 * PARAMETERS: None
425 *
426 * RETURN: Status
427 *
428 * DESCRIPTION: Walk the namespace an display information about each node
429 * in the tree. Information is written to the optional
430 * namespace output file.
431 *
432 ******************************************************************************/
433
434ACPI_STATUS
435LsDisplayNamespace (
436 void)
437{
438 ACPI_STATUS Status;
439
440
441 if (!Gbl_NsOutputFlag)
442 {
443 return (AE_OK);
444 }
445
446 Gbl_NumNamespaceObjects = 0;
447
448 /* File header */
449
450 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n");
451 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count Depth Name - Type\n\n");
452
453 /* Walk entire namespace from the root */
454
455 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
456 ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, NULL,
457 NULL, NULL);
458
459 /* Print the full pathname for each namespace node */
460
461 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\nNamespace pathnames\n\n");
462
463 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
464 ACPI_UINT32_MAX, FALSE, LsDoOnePathname, NULL,
465 NULL, NULL);
466
467 return (Status);
468}
469
470
471/*******************************************************************************
472 *
473 * FUNCTION: LsCompareOneNamespaceObject
474 *
475 * PARAMETERS: ACPI_WALK_CALLBACK
476 *
477 * RETURN: Status
478 *
479 * DESCRIPTION: Compare name of one object.
480 *
481 ******************************************************************************/
482
483static ACPI_STATUS
484LsCompareOneNamespaceObject (
485 ACPI_HANDLE ObjHandle,
486 UINT32 Level,
487 void *Context,
488 void **ReturnValue)
489{
490 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
491
492
493 /* Simply check the name */
494
495 if (*((UINT32 *) (Context)) == Node->Name.Integer)
496 {
497 /* Abort walk if we found one instance */
498
499 return (AE_CTRL_TRUE);
500 }
501
502 return (AE_OK);
503}
504
505
506/*******************************************************************************
507 *
508 * FUNCTION: LkObjectExists
509 *
510 * PARAMETERS: Name - 4 char ACPI name
511 *
512 * RETURN: TRUE if name exists in namespace
513 *
514 * DESCRIPTION: Walk the namespace to find an object
515 *
516 ******************************************************************************/
517
518static BOOLEAN
519LkObjectExists (
520 char *Name)
521{
522 ACPI_STATUS Status;
523
524
525 /* Walk entire namespace from the supplied root */
526
527 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
528 ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject, NULL,
529 Name, NULL);
530 if (Status == AE_CTRL_TRUE)
531 {
532 /* At least one instance of the name was found */
533
534 return (TRUE);
535 }
536
537 return (FALSE);
538}
539
540
541/*******************************************************************************
542 *
543 * FUNCTION: LkGetNameOp
544 *
545 * PARAMETERS: Op - Current Op
546 *
547 * RETURN: NameOp associated with the input op
548 *
549 * DESCRIPTION: Find the name declaration op associated with the operator
550 *
551 ******************************************************************************/
552
553static ACPI_PARSE_OBJECT *
554LkGetNameOp (
555 ACPI_PARSE_OBJECT *Op)
556{
557 const ACPI_OPCODE_INFO *OpInfo;
558 ACPI_PARSE_OBJECT *NameOp = Op;
559
560
561 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
562
563
564 /* Get the NamePath from the appropriate place */
565
566 if (OpInfo->Flags & AML_NAMED)
567 {
568 /* For nearly all NAMED operators, the name reference is the first child */
569
570 NameOp = Op->Asl.Child;
571 if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
572 {
573 /*
574 * ALIAS is the only oddball opcode, the name declaration
575 * (alias name) is the second operand
576 */
577 NameOp = Op->Asl.Child->Asl.Next;
578 }
579 }
580 else if (OpInfo->Flags & AML_CREATE)
581 {
582 /* Name must appear as the last parameter */
583
584 NameOp = Op->Asl.Child;
585 while (!(NameOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
586 {
587 NameOp = NameOp->Asl.Next;
588 }
589 }
590
591 return (NameOp);
592}
593
594
595/*******************************************************************************
596 *
597 * FUNCTION: LkIsObjectUsed
598 *
599 * PARAMETERS: ACPI_WALK_CALLBACK
600 *
601 * RETURN: Status
602 *
603 * DESCRIPTION: Check for an unreferenced namespace object and emit a warning.
604 * We have to be careful, because some types and names are
605 * typically or always unreferenced, we don't want to issue
606 * excessive warnings.
607 *
608 ******************************************************************************/
609
610static ACPI_STATUS
611LkIsObjectUsed (
612 ACPI_HANDLE ObjHandle,
613 UINT32 Level,
614 void *Context,
615 void **ReturnValue)
616{
617 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
618
619
620 /* Referenced flag is set during the namespace xref */
621
622 if (Node->Flags & ANOBJ_IS_REFERENCED)
623 {
624 return (AE_OK);
625 }
626
627 /*
628 * Ignore names that start with an underscore,
629 * these are the reserved ACPI names and are typically not referenced,
630 * they are called by the host OS.
631 */
632 if (Node->Name.Ascii[0] == '_')
633 {
634 return (AE_OK);
635 }
636
637 /* There are some types that are typically not referenced, ignore them */
638
639 switch (Node->Type)
640 {
641 case ACPI_TYPE_DEVICE:
642 case ACPI_TYPE_PROCESSOR:
643 case ACPI_TYPE_POWER:
644 case ACPI_TYPE_LOCAL_RESOURCE:
645 return (AE_OK);
646
647 default:
648 break;
649 }
650
651 /* All others are valid unreferenced namespace objects */
652
653 if (Node->Op)
654 {
655 AslError (ASL_WARNING2, ASL_MSG_NOT_REFERENCED, LkGetNameOp (Node->Op), NULL);
656 }
657 return (AE_OK);
658}
659
660
661/*******************************************************************************
662 *
663 * FUNCTION: LkFindUnreferencedObjects
664 *
665 * PARAMETERS: None
666 *
667 * RETURN: None
668 *
669 * DESCRIPTION: Namespace walk to find objects that are not referenced in any
670 * way. Must be called after the namespace has been cross
671 * referenced.
672 *
673 ******************************************************************************/
674
675void
676LkFindUnreferencedObjects (
677 void)
678{
679
680 /* Walk entire namespace from the supplied root */
681
682 (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
683 ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, NULL,
684 NULL, NULL);
685}
686
687
688/*******************************************************************************
689 *
690 * FUNCTION: LkCrossReferenceNamespace
691 *
692 * PARAMETERS: None
693 *
694 * RETURN: Status
695 *
696 * DESCRIPTION: Perform a cross reference check of the parse tree against the
697 * namespace. Every named referenced within the parse tree
698 * should be get resolved with a namespace lookup. If not, the
699 * original reference in the ASL code is invalid -- i.e., refers
700 * to a non-existent object.
701 *
702 * NOTE: The ASL "External" operator causes the name to be inserted into the
703 * namespace so that references to the external name will be resolved
704 * correctly here.
705 *
706 ******************************************************************************/
707
708ACPI_STATUS
709LkCrossReferenceNamespace (
710 void)
711{
712 ACPI_WALK_STATE *WalkState;
713
714
715 DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n");
716
717 /*
718 * Create a new walk state for use when looking up names
719 * within the namespace (Passed as context to the callbacks)
720 */
721 WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
722 if (!WalkState)
723 {
724 return (AE_NO_MEMORY);
725 }
726
727 /* Walk the entire parse tree */
728
729 TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, LkNamespaceLocateBegin,
730 LkNamespaceLocateEnd, WalkState);
731 return (AE_OK);
732}
733
734
735/*******************************************************************************
736 *
737 * FUNCTION: LkCheckFieldRange
738 *
739 * PARAMETERS: RegionBitLength - Length of entire parent region
740 * FieldBitOffset - Start of the field unit (within region)
741 * FieldBitLength - Entire length of field unit
742 * AccessBitWidth - Access width of the field unit
743 *
744 * RETURN: None
745 *
746 * DESCRIPTION: Check one field unit to make sure it fits in the parent
747 * op region.
748 *
749 * Note: AccessBitWidth must be either 8,16,32, or 64
750 *
751 ******************************************************************************/
752
753static void
754LkCheckFieldRange (
755 ACPI_PARSE_OBJECT *Op,
756 UINT32 RegionBitLength,
757 UINT32 FieldBitOffset,
758 UINT32 FieldBitLength,
759 UINT32 AccessBitWidth)
760{
761 UINT32 FieldEndBitOffset;
762
763
764 /*
765 * Check each field unit against the region size. The entire
766 * field unit (start offset plus length) must fit within the
767 * region.
768 */
769 FieldEndBitOffset = FieldBitOffset + FieldBitLength;
770
771 if (FieldEndBitOffset > RegionBitLength)
772 {
773 /* Field definition itself is beyond the end-of-region */
774
775 AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
776 return;
777 }
778
779 /*
780 * Now check that the field plus AccessWidth doesn't go beyond
781 * the end-of-region. Assumes AccessBitWidth is a power of 2
782 */
783 FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
784
785 if (FieldEndBitOffset > RegionBitLength)
786 {
787 /* Field definition combined with the access is beyond EOR */
788
789 AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
790 }
791}
792
793/*******************************************************************************
794 *
795 * FUNCTION: LkNamespaceLocateBegin
796 *
797 * PARAMETERS: ASL_WALK_CALLBACK
798 *
799 * RETURN: Status
800 *
801 * DESCRIPTION: Descending callback used during cross-reference. For named
802 * object references, attempt to locate the name in the
803 * namespace.
804 *
805 * NOTE: ASL references to named fields within resource descriptors are
806 * resolved to integer values here. Therefore, this step is an
807 * important part of the code generation. We don't know that the
808 * name refers to a resource descriptor until now.
809 *
810 ******************************************************************************/
811
812static ACPI_STATUS
813LkNamespaceLocateBegin (
814 ACPI_PARSE_OBJECT *Op,
815 UINT32 Level,
816 void *Context)
817{
818 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context;
819 ACPI_NAMESPACE_NODE *Node;
820 ACPI_STATUS Status;
821 ACPI_OBJECT_TYPE ObjectType;
822 char *Path;
823 UINT8 PassedArgs;
824 ACPI_PARSE_OBJECT *NextOp;
825 ACPI_PARSE_OBJECT *OwningOp;
826 ACPI_PARSE_OBJECT *SpaceIdOp;
827 UINT32 MinimumLength;
828 UINT32 Offset;
829 UINT32 FieldBitLength;
830 UINT32 TagBitLength;
831 UINT8 Message = 0;
832 const ACPI_OPCODE_INFO *OpInfo;
833 UINT32 Flags;
834
835
836 ACPI_FUNCTION_TRACE_PTR (LkNamespaceLocateBegin, Op);
837
838 /*
839 * If this node is the actual declaration of a name
840 * [such as the XXXX name in "Method (XXXX)"],
841 * we are not interested in it here. We only care about names that are
842 * references to other objects within the namespace and the parent objects
843 * of name declarations
844 */
845 if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
846 {
847 return (AE_OK);
848 }
849
850 /* We are only interested in opcodes that have an associated name */
851
852 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
853
854 if ((!(OpInfo->Flags & AML_NAMED)) &&
855 (!(OpInfo->Flags & AML_CREATE)) &&
856 (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
857 (Op->Asl.ParseOpcode != PARSEOP_NAMESEG) &&
858 (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
859 {
860 return (AE_OK);
861 }
862
863 /*
864 * One special case: CondRefOf operator - we don't care if the name exists
865 * or not at this point, just ignore it, the point of the operator is to
866 * determine if the name exists at runtime.
867 */
868 if ((Op->Asl.Parent) &&
869 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))
870 {
871 return (AE_OK);
872 }
873
874 /*
875 * We must enable the "search-to-root" for single NameSegs, but
876 * we have to be very careful about opening up scopes
877 */
878 Flags = ACPI_NS_SEARCH_PARENT;
879 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
880 (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
881 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
882 {
883 /*
884 * These are name references, do not push the scope stack
885 * for them.
886 */
887 Flags |= ACPI_NS_DONT_OPEN_SCOPE;
888 }
889
890 /* Get the NamePath from the appropriate place */
891
892 if (OpInfo->Flags & AML_NAMED)
893 {
894 /* For nearly all NAMED operators, the name reference is the first child */
895
896 Path = Op->Asl.Child->Asl.Value.String;
897 if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
898 {
899 /*
900 * ALIAS is the only oddball opcode, the name declaration
901 * (alias name) is the second operand
902 */
903 Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
904 }
905 }
906 else if (OpInfo->Flags & AML_CREATE)
907 {
908 /* Name must appear as the last parameter */
909
910 NextOp = Op->Asl.Child;
911 while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
912 {
913 NextOp = NextOp->Asl.Next;
914 }
915 Path = NextOp->Asl.Value.String;
916 }
917 else
918 {
919 Path = Op->Asl.Value.String;
920 }
921
922 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
923 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
924 "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
925
926 /*
927 * Lookup the name in the namespace. Name must exist at this point, or it
928 * is an invalid reference.
929 *
930 * The namespace is also used as a lookup table for references to resource
931 * descriptors and the fields within them.
932 */
933 Gbl_NsLookupCount++;
934
935 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
936 ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node));
937 if (ACPI_FAILURE (Status))
938 {
939 if (Status == AE_NOT_FOUND)
940 {
941 /*
942 * We didn't find the name reference by path -- we can qualify this
943 * a little better before we print an error message
944 */
945 if (strlen (Path) == ACPI_NAME_SIZE)
946 {
947 /* A simple, one-segment ACPI name */
948
949 if (LkObjectExists (Path))
950 {
951 /*
952 * There exists such a name, but we couldn't get to it
953 * from this scope
954 */
955 AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op,
956 Op->Asl.ExternalName);
957 }
958 else
959 {
960 /* The name doesn't exist, period */
961
962 AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,
963 Op, Op->Asl.ExternalName);
964 }
965 }
966 else
967 {
968 /* Check for a fully qualified path */
969
970 if (Path[0] == AML_ROOT_PREFIX)
971 {
972 /* Gave full path, the object does not exist */
973
974 AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,
975 Op->Asl.ExternalName);
976 }
977 else
978 {
979 /*
980 * We can't tell whether it doesn't exist or just
981 * can't be reached.
982 */
983 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
984 Op->Asl.ExternalName);
985 }
986 }
987
988 Status = AE_OK;
989 }
990 return (Status);
991 }
992
993 /* Check for a reference vs. name declaration */
994
995 if (!(OpInfo->Flags & AML_NAMED) &&
996 !(OpInfo->Flags & AML_CREATE))
997 {
998 /* This node has been referenced, mark it for reference check */
999
1000 Node->Flags |= ANOBJ_IS_REFERENCED;
1001 }
1002
1003 /* Attempt to optimize the NamePath */
1004
1005 OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
1006
1007 /*
1008 * 1) Dereference an alias (A name reference that is an alias)
1009 * Aliases are not nested, the alias always points to the final object
1010 */
1011 if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) &&
1012 (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
1013 {
1014 /* This node points back to the original PARSEOP_ALIAS */
1015
1016 NextOp = Node->Op;
1017
1018 /* The first child is the alias target op */
1019
1020 NextOp = NextOp->Asl.Child;
1021
1022 /* That in turn points back to original target alias node */
1023
1024 if (NextOp->Asl.Node)
1025 {
1026 Node = NextOp->Asl.Node;
1027 }
1028
1029 /* Else - forward reference to alias, will be resolved later */
1030 }
1031
1032 /* 2) Check for a reference to a resource descriptor */
1033
1034 if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
1035 (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
1036 {
1037 /*
1038 * This was a reference to a field within a resource descriptor.
1039 * Extract the associated field offset (either a bit or byte
1040 * offset depending on the field type) and change the named
1041 * reference into an integer for AML code generation
1042 */
1043 Offset = Node->Value;
1044 TagBitLength = Node->Length;
1045
1046 /*
1047 * If a field is being created, generate the length (in bits) of
1048 * the field. Note: Opcodes other than CreateXxxField and Index
1049 * can come through here. For other opcodes, we just need to
1050 * convert the resource tag reference to an integer offset.
1051 */
1052 switch (Op->Asl.Parent->Asl.AmlOpcode)
1053 {
1054 case AML_CREATE_FIELD_OP: /* Variable "Length" field, in bits */
1055 /*
1056 * We know the length operand is an integer constant because
1057 * we know that it contains a reference to a resource
1058 * descriptor tag.
1059 */
1060 FieldBitLength = (UINT32) Op->Asl.Next->Asl.Value.Integer;
1061 break;
1062
1063 case AML_CREATE_BIT_FIELD_OP:
1064 FieldBitLength = 1;
1065 break;
1066
1067 case AML_CREATE_BYTE_FIELD_OP:
1068 case AML_INDEX_OP:
1069 FieldBitLength = 8;
1070 break;
1071
1072 case AML_CREATE_WORD_FIELD_OP:
1073 FieldBitLength = 16;
1074 break;
1075
1076 case AML_CREATE_DWORD_FIELD_OP:
1077 FieldBitLength = 32;
1078 break;
1079
1080 case AML_CREATE_QWORD_FIELD_OP:
1081 FieldBitLength = 64;
1082 break;
1083
1084 default:
1085 FieldBitLength = 0;
1086 break;
1087 }
1088
1089 /* Check the field length against the length of the resource tag */
1090
1091 if (FieldBitLength)
1092 {
1093 if (TagBitLength < FieldBitLength)
1094 {
1095 Message = ASL_MSG_TAG_SMALLER;
1096 }
1097 else if (TagBitLength > FieldBitLength)
1098 {
1099 Message = ASL_MSG_TAG_LARGER;
1100 }
1101
1102 if (Message)
1103 {
1104 sprintf (MsgBuffer, "Size mismatch, Tag: %u bit%s, Field: %u bit%s",
1105 TagBitLength, (TagBitLength > 1) ? "s" : "",
1106 FieldBitLength, (FieldBitLength > 1) ? "s" : "");
1107
1108 AslError (ASL_WARNING, Message, Op, MsgBuffer);
1109 }
1110 }
1111
1112 /* Convert the BitOffset to a ByteOffset for certain opcodes */
1113
1114 switch (Op->Asl.Parent->Asl.AmlOpcode)
1115 {
1116 case AML_CREATE_BYTE_FIELD_OP:
1117 case AML_CREATE_WORD_FIELD_OP:
1118 case AML_CREATE_DWORD_FIELD_OP:
1119 case AML_CREATE_QWORD_FIELD_OP:
1120 case AML_INDEX_OP:
1121
1122 Offset = ACPI_DIV_8 (Offset);
1123 break;
1124
1125 default:
1126 break;
1127 }
1128
1129 /* Now convert this node to an integer whose value is the field offset */
1130
1131 Op->Asl.AmlLength = 0;
1132 Op->Asl.ParseOpcode = PARSEOP_INTEGER;
1133 Op->Asl.Value.Integer = (UINT64) Offset;
1134 Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD;
1135
1136 OpcGenerateAmlOpcode (Op);
1137 }
1138
1139 /* 3) Check for a method invocation */
1140
1141 else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
1142 (Node->Type == ACPI_TYPE_METHOD) &&
1143 (Op->Asl.Parent) &&
1144 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD)) ||
1145
1146 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
1147 {
1148
1149 /*
1150 * A reference to a method within one of these opcodes is not an
1151 * invocation of the method, it is simply a reference to the method.
1152 */
1153 if ((Op->Asl.Parent) &&
1154 ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF) ||
1155 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEREFOF) ||
1156 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE)))
1157 {
1158 return (AE_OK);
1159 }
1160 /*
1161 * There are two types of method invocation:
1162 * 1) Invocation with arguments -- the parser recognizes this
1163 * as a METHODCALL.
1164 * 2) Invocation with no arguments --the parser cannot determine that
1165 * this is a method invocation, therefore we have to figure it out
1166 * here.
1167 */
1168 if (Node->Type != ACPI_TYPE_METHOD)
1169 {
1170 sprintf (MsgBuffer, "%s is a %s",
1171 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
1172
1173 AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer);
1174 return (AE_OK);
1175 }
1176
1177 /* Save the method node in the caller's op */
1178
1179 Op->Asl.Node = Node;
1180 if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
1181 {
1182 return (AE_OK);
1183 }
1184
1185 /*
1186 * This is a method invocation, with or without arguments.
1187 * Count the number of arguments, each appears as a child
1188 * under the parent node
1189 */
1190 Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
1191 UtSetParseOpName (Op);
1192
1193 PassedArgs = 0;
1194 NextOp = Op->Asl.Child;
1195
1196 while (NextOp)
1197 {
1198 PassedArgs++;
1199 NextOp = NextOp->Asl.Next;
1200 }
1201
1202 if (Node->Value != ASL_EXTERNAL_METHOD)
1203 {
1204 /*
1205 * Check the parsed arguments with the number expected by the
1206 * method declaration itself
1207 */
1208 if (PassedArgs != Node->Value)
1209 {
1210 sprintf (MsgBuffer, "%s requires %u", Op->Asl.ExternalName,
1211 Node->Value);
1212
1213 if (PassedArgs < Node->Value)
1214 {
1215 AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer);
1216 }
1217 else
1218 {
1219 AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer);
1220 }
1221 }
1222 }
1223 }
1224
1225 /* 4) Check for an ASL Field definition */
1226
1227 else if ((Op->Asl.Parent) &&
1228 ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD) ||
1229 (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
1230 {
1231 /*
1232 * Offset checking for fields. If the parent operation region has a
1233 * constant length (known at compile time), we can check fields
1234 * defined in that region against the region length. This will catch
1235 * fields and field units that cannot possibly fit within the region.
1236 *
1237 * Note: Index fields do not directly reference an operation region,
1238 * thus they are not included in this check.
1239 */
1240 if (Op == Op->Asl.Parent->Asl.Child)
1241 {
1242 /*
1243 * This is the first child of the field node, which is
1244 * the name of the region. Get the parse node for the
1245 * region -- which contains the length of the region.
1246 */
1247 OwningOp = Node->Op;
1248 Op->Asl.Parent->Asl.ExtraValue =
1249 ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
1250
1251 /* Examine the field access width */
1252
1253 switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
1254 {
1255 case AML_FIELD_ACCESS_ANY:
1256 case AML_FIELD_ACCESS_BYTE:
1257 case AML_FIELD_ACCESS_BUFFER:
1258 default:
1259 MinimumLength = 1;
1260 break;
1261
1262 case AML_FIELD_ACCESS_WORD:
1263 MinimumLength = 2;
1264 break;
1265
1266 case AML_FIELD_ACCESS_DWORD:
1267 MinimumLength = 4;
1268 break;
1269
1270 case AML_FIELD_ACCESS_QWORD:
1271 MinimumLength = 8;
1272 break;
1273 }
1274
1275 /*
1276 * Is the region at least as big as the access width?
1277 * Note: DataTableRegions have 0 length
1278 */
1279 if (((UINT32) OwningOp->Asl.Value.Integer) &&
1280 ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
1281 {
1282 AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
1283 }
1284
1285 /*
1286 * Check EC/CMOS/SMBUS fields to make sure that the correct
1287 * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
1288 */
1289 SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
1290 switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
1291 {
1292 case ACPI_ADR_SPACE_EC:
1293 case ACPI_ADR_SPACE_CMOS:
1294 case ACPI_ADR_SPACE_GPIO:
1295
1296 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE)
1297 {
1298 AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
1299 }
1300 break;
1301
1302 case ACPI_ADR_SPACE_SMBUS:
1303 case ACPI_ADR_SPACE_IPMI:
1304 case ACPI_ADR_SPACE_GSBUS:
1305
1306 if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER)
1307 {
1308 AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
1309 }
1310 break;
1311
1312 default:
1313
1314 /* Nothing to do for other address spaces */
1315 break;
1316 }
1317 }
1318 else
1319 {
1320 /*
1321 * This is one element of the field list. Check to make sure
1322 * that it does not go beyond the end of the parent operation region.
1323 *
1324 * In the code below:
1325 * Op->Asl.Parent->Asl.ExtraValue - Region Length (bits)
1326 * Op->Asl.ExtraValue - Field start offset (bits)
1327 * Op->Asl.Child->Asl.Value.Integer32 - Field length (bits)
1328 * Op->Asl.Child->Asl.ExtraValue - Field access width (bits)
1329 */
1330 if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
1331 {
1332 LkCheckFieldRange (Op,
1333 Op->Asl.Parent->Asl.ExtraValue,
1334 Op->Asl.ExtraValue,
1335 (UINT32) Op->Asl.Child->Asl.Value.Integer,
1336 Op->Asl.Child->Asl.ExtraValue);
1337 }
1338 }
1339 }
1340
1341 Op->Asl.Node = Node;
1342 return (Status);
1343}
1344
1345
1346/*******************************************************************************
1347 *
1348 * FUNCTION: LkNamespaceLocateEnd
1349 *
1350 * PARAMETERS: ASL_WALK_CALLBACK
1351 *
1352 * RETURN: Status
1353 *
1354 * DESCRIPTION: Ascending callback used during cross reference. We only
1355 * need to worry about scope management here.
1356 *
1357 ******************************************************************************/
1358
1359static ACPI_STATUS
1360LkNamespaceLocateEnd (
1361 ACPI_PARSE_OBJECT *Op,
1362 UINT32 Level,
1363 void *Context)
1364{
1365 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context;
1366 const ACPI_OPCODE_INFO *OpInfo;
1367
1368
1369 ACPI_FUNCTION_TRACE (LkNamespaceLocateEnd);
1370
1371
1372 /* We are only interested in opcodes that have an associated name */
1373
1374 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
1375 if (!(OpInfo->Flags & AML_NAMED))
1376 {
1377 return (AE_OK);
1378 }
1379
1380 /* Not interested in name references, we did not open a scope for them */
1381
1382 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
1383 (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||
1384 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
1385 {
1386 return (AE_OK);
1387 }
1388
1389 /* Pop the scope stack if necessary */
1390
1391 if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
1392 {
1393
1394 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1395 "%s: Popping scope for Op %p\n",
1396 AcpiUtGetTypeName (OpInfo->ObjectType), Op));
1397
1398 (void) AcpiDsScopeStackPop (WalkState);
1399 }
1400
1401 return (AE_OK);
1402}