Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/acpica/common/adwalk.c
48375 views
1
/******************************************************************************
2
*
3
* Module Name: adwalk - Application-level disassembler parse tree walk routines
4
*
5
*****************************************************************************/
6
7
/******************************************************************************
8
*
9
* 1. Copyright Notice
10
*
11
* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
12
* All rights reserved.
13
*
14
* 2. License
15
*
16
* 2.1. This is your license from Intel Corp. under its intellectual property
17
* rights. You may have additional license terms from the party that provided
18
* you this software, covering your right to use that party's intellectual
19
* property rights.
20
*
21
* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
* copy of the source code appearing in this file ("Covered Code") an
23
* irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
* base code distributed originally by Intel ("Original Intel Code") to copy,
25
* make derivatives, distribute, use and display any portion of the Covered
26
* Code in any form, with the right to sublicense such rights; and
27
*
28
* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
* license (with the right to sublicense), under only those claims of Intel
30
* patents that are infringed by the Original Intel Code, to make, use, sell,
31
* offer to sell, and import the Covered Code and derivative works thereof
32
* solely to the minimum extent necessary to exercise the above copyright
33
* license, and in no event shall the patent license extend to any additions
34
* to or modifications of the Original Intel Code. No other license or right
35
* is granted directly or by implication, estoppel or otherwise;
36
*
37
* The above copyright and patent license is granted only if the following
38
* conditions are met:
39
*
40
* 3. Conditions
41
*
42
* 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
* Redistribution of source code of any substantial portion of the Covered
44
* Code or modification with rights to further distribute source must include
45
* the above Copyright Notice, the above License, this list of Conditions,
46
* and the following Disclaimer and Export Compliance provision. In addition,
47
* Licensee must cause all Covered Code to which Licensee contributes to
48
* contain a file documenting the changes Licensee made to create that Covered
49
* Code and the date of any change. Licensee must include in that file the
50
* documentation of any changes made by any predecessor Licensee. Licensee
51
* must include a prominent statement that the modification is derived,
52
* directly or indirectly, from Original Intel Code.
53
*
54
* 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
* Redistribution of source code of any substantial portion of the Covered
56
* Code or modification without rights to further distribute source must
57
* include the following Disclaimer and Export Compliance provision in the
58
* documentation and/or other materials provided with distribution. In
59
* addition, Licensee may not authorize further sublicense of source of any
60
* portion of the Covered Code, and must include terms to the effect that the
61
* license from Licensee to its licensee is limited to the intellectual
62
* property embodied in the software Licensee provides to its licensee, and
63
* not to intellectual property embodied in modifications its licensee may
64
* make.
65
*
66
* 3.3. Redistribution of Executable. Redistribution in executable form of any
67
* substantial portion of the Covered Code or modification must reproduce the
68
* above Copyright Notice, and the following Disclaimer and Export Compliance
69
* provision in the documentation and/or other materials provided with the
70
* distribution.
71
*
72
* 3.4. Intel retains all right, title, and interest in and to the Original
73
* Intel Code.
74
*
75
* 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
* Intel shall be used in advertising or otherwise to promote the sale, use or
77
* other dealings in products derived from or relating to the Covered Code
78
* without prior written authorization from Intel.
79
*
80
* 4. Disclaimer and Export Compliance
81
*
82
* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85
* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86
* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87
* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
* PARTICULAR PURPOSE.
89
*
90
* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96
* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
* LIMITED REMEDY.
98
*
99
* 4.3. Licensee shall not export, either directly or indirectly, any of this
100
* software or system incorporating such software without first obtaining any
101
* required license or other approval from the U. S. Department of Commerce or
102
* any other agency or department of the United States Government. In the
103
* event Licensee exports any such software from the United States or
104
* re-exports any such software from a foreign destination, Licensee shall
105
* ensure that the distribution and export/re-export of the software is in
106
* compliance with all laws, regulations, orders, or other restrictions of the
107
* U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
* any of its subsidiaries will export/re-export any technical data, process,
109
* software, or service, directly or indirectly, to any country for which the
110
* United States government or any agency thereof requires an export license,
111
* other governmental approval, or letter of assurance, without first obtaining
112
* such license, approval or letter.
113
*
114
*****************************************************************************
115
*
116
* Alternatively, you may choose to be licensed under the terms of the
117
* following license:
118
*
119
* Redistribution and use in source and binary forms, with or without
120
* modification, are permitted provided that the following conditions
121
* are met:
122
* 1. Redistributions of source code must retain the above copyright
123
* notice, this list of conditions, and the following disclaimer,
124
* without modification.
125
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
126
* substantially similar to the "NO WARRANTY" disclaimer below
127
* ("Disclaimer") and any redistribution must be conditioned upon
128
* including a substantially similar Disclaimer requirement for further
129
* binary redistribution.
130
* 3. Neither the names of the above-listed copyright holders nor the names
131
* of any contributors may be used to endorse or promote products derived
132
* from this software without specific prior written permission.
133
*
134
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145
*
146
* Alternatively, you may choose to be licensed under the terms of the
147
* GNU General Public License ("GPL") version 2 as published by the Free
148
* Software Foundation.
149
*
150
*****************************************************************************/
151
152
#include <contrib/dev/acpica/include/acpi.h>
153
#include <contrib/dev/acpica/include/accommon.h>
154
#include <contrib/dev/acpica/include/acparser.h>
155
#include <contrib/dev/acpica/include/amlcode.h>
156
#include <contrib/dev/acpica/include/acdisasm.h>
157
#include <contrib/dev/acpica/include/acdispat.h>
158
#include <contrib/dev/acpica/include/acnamesp.h>
159
#include <contrib/dev/acpica/include/acapps.h>
160
161
162
#define _COMPONENT ACPI_TOOLS
163
ACPI_MODULE_NAME ("adwalk")
164
165
/*
166
* aslmap - opcode mappings and reserved method names
167
*/
168
ACPI_OBJECT_TYPE
169
AslMapNamedOpcodeToDataType (
170
UINT16 Opcode);
171
172
/* Local prototypes */
173
174
static ACPI_STATUS
175
AcpiDmFindOrphanDescending (
176
ACPI_PARSE_OBJECT *Op,
177
UINT32 Level,
178
void *Context);
179
180
static ACPI_STATUS
181
AcpiDmDumpDescending (
182
ACPI_PARSE_OBJECT *Op,
183
UINT32 Level,
184
void *Context);
185
186
static ACPI_STATUS
187
AcpiDmXrefDescendingOp (
188
ACPI_PARSE_OBJECT *Op,
189
UINT32 Level,
190
void *Context);
191
192
static ACPI_STATUS
193
AcpiDmCommonAscendingOp (
194
ACPI_PARSE_OBJECT *Op,
195
UINT32 Level,
196
void *Context);
197
198
static ACPI_STATUS
199
AcpiDmLoadDescendingOp (
200
ACPI_PARSE_OBJECT *Op,
201
UINT32 Level,
202
void *Context);
203
204
static UINT32
205
AcpiDmInspectPossibleArgs (
206
UINT32 CurrentOpArgCount,
207
UINT32 TargetCount,
208
ACPI_PARSE_OBJECT *Op);
209
210
static ACPI_STATUS
211
AcpiDmCommonDescendingOp (
212
ACPI_PARSE_OBJECT *Op,
213
UINT32 Level,
214
void *Context);
215
216
static ACPI_STATUS
217
AcpiDmProcessResourceDescriptors (
218
ACPI_PARSE_OBJECT *Op,
219
UINT32 Level,
220
void *Context);
221
222
/*******************************************************************************
223
*
224
* FUNCTION: AcpiDmDumpTree
225
*
226
* PARAMETERS: Origin - Starting object
227
*
228
* RETURN: None
229
*
230
* DESCRIPTION: Parse tree walk to format and output the nodes
231
*
232
******************************************************************************/
233
234
void
235
AcpiDmDumpTree (
236
ACPI_PARSE_OBJECT *Origin)
237
{
238
ACPI_OP_WALK_INFO Info;
239
240
241
if (!Origin)
242
{
243
return;
244
}
245
246
AcpiOsPrintf ("/*\nAML Parse Tree\n\n");
247
Info.Flags = 0;
248
Info.Count = 0;
249
Info.Level = 0;
250
Info.WalkState = NULL;
251
252
AcpiDmWalkParseTree (Origin, AcpiDmDumpDescending, NULL, &Info);
253
AcpiOsPrintf ("*/\n\n");
254
}
255
256
257
/*******************************************************************************
258
*
259
* FUNCTION: AcpiDmFindOrphanMethods
260
*
261
* PARAMETERS: Origin - Starting object
262
*
263
* RETURN: None
264
*
265
* DESCRIPTION: Parse tree walk to find "orphaned" method invocations -- methods
266
* that are not resolved in the namespace
267
*
268
******************************************************************************/
269
270
void
271
AcpiDmFindOrphanMethods (
272
ACPI_PARSE_OBJECT *Origin)
273
{
274
ACPI_OP_WALK_INFO Info;
275
276
277
if (!Origin)
278
{
279
return;
280
}
281
282
Info.Flags = 0;
283
Info.Level = 0;
284
Info.WalkState = NULL;
285
286
AcpiDmWalkParseTree (Origin, AcpiDmFindOrphanDescending, NULL, &Info);
287
}
288
289
290
/*******************************************************************************
291
*
292
* FUNCTION: AcpiDmFinishNamespaceLoad
293
*
294
* PARAMETERS: ParseTreeRoot - Root of the parse tree
295
* NamespaceRoot - Root of the internal namespace
296
* OwnerId - OwnerId of the table to be disassembled
297
*
298
* RETURN: None
299
*
300
* DESCRIPTION: Load all namespace items that are created within control
301
* methods. Used before namespace cross reference
302
*
303
******************************************************************************/
304
305
void
306
AcpiDmFinishNamespaceLoad (
307
ACPI_PARSE_OBJECT *ParseTreeRoot,
308
ACPI_NAMESPACE_NODE *NamespaceRoot,
309
ACPI_OWNER_ID OwnerId)
310
{
311
ACPI_STATUS Status;
312
ACPI_OP_WALK_INFO Info;
313
ACPI_WALK_STATE *WalkState;
314
315
316
if (!ParseTreeRoot)
317
{
318
return;
319
}
320
321
/* Create and initialize a new walk state */
322
323
WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
324
if (!WalkState)
325
{
326
return;
327
}
328
329
Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type,
330
WalkState);
331
if (ACPI_FAILURE (Status))
332
{
333
return;
334
}
335
336
Info.Flags = 0;
337
Info.Level = 0;
338
Info.WalkState = WalkState;
339
340
AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmLoadDescendingOp,
341
AcpiDmCommonAscendingOp, &Info);
342
ACPI_FREE (WalkState);
343
}
344
345
346
/*******************************************************************************
347
*
348
* FUNCTION: AcpiDmCrossReferenceNamespace
349
*
350
* PARAMETERS: ParseTreeRoot - Root of the parse tree
351
* NamespaceRoot - Root of the internal namespace
352
* OwnerId - OwnerId of the table to be disassembled
353
*
354
* RETURN: None
355
*
356
* DESCRIPTION: Cross reference the namespace to create externals
357
*
358
******************************************************************************/
359
360
void
361
AcpiDmCrossReferenceNamespace (
362
ACPI_PARSE_OBJECT *ParseTreeRoot,
363
ACPI_NAMESPACE_NODE *NamespaceRoot,
364
ACPI_OWNER_ID OwnerId)
365
{
366
ACPI_STATUS Status;
367
ACPI_OP_WALK_INFO Info;
368
ACPI_WALK_STATE *WalkState;
369
370
371
if (!ParseTreeRoot)
372
{
373
return;
374
}
375
376
/* Create and initialize a new walk state */
377
378
WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL);
379
if (!WalkState)
380
{
381
return;
382
}
383
384
Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type,
385
WalkState);
386
if (ACPI_FAILURE (Status))
387
{
388
return;
389
}
390
391
Info.Flags = 0;
392
Info.Level = 0;
393
Info.WalkState = WalkState;
394
395
AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmXrefDescendingOp,
396
AcpiDmCommonAscendingOp, &Info);
397
ACPI_FREE (WalkState);
398
}
399
400
401
/*******************************************************************************
402
*
403
* FUNCTION: AcpiDmConvertParseObjects
404
*
405
* PARAMETERS: ParseTreeRoot - Root of the parse tree
406
* NamespaceRoot - Root of the internal namespace
407
*
408
* RETURN: None
409
*
410
* DESCRIPTION: Begin parse tree walk to perform conversions needed for
411
* disassembly. These include resource descriptors and switch/case
412
* operations.
413
*
414
******************************************************************************/
415
416
void
417
AcpiDmConvertParseObjects (
418
ACPI_PARSE_OBJECT *ParseTreeRoot,
419
ACPI_NAMESPACE_NODE *NamespaceRoot)
420
{
421
ACPI_STATUS Status;
422
ACPI_OP_WALK_INFO Info;
423
ACPI_WALK_STATE *WalkState;
424
425
426
if (!ParseTreeRoot)
427
{
428
return;
429
}
430
431
/* Create and initialize a new walk state */
432
433
WalkState = AcpiDsCreateWalkState (0, ParseTreeRoot, NULL, NULL);
434
if (!WalkState)
435
{
436
return;
437
}
438
439
Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type,
440
WalkState);
441
if (ACPI_FAILURE (Status))
442
{
443
ACPI_FREE (WalkState);
444
return;
445
}
446
447
Info.Flags = 0;
448
Info.Level = 0;
449
Info.WalkState = WalkState;
450
451
AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmCommonDescendingOp,
452
AcpiDmCommonAscendingOp, &Info);
453
ACPI_FREE (WalkState);
454
455
if (AcpiGbl_TempListHead) {
456
AcpiDmClearTempList();
457
}
458
459
return;
460
}
461
462
463
/*******************************************************************************
464
*
465
* FUNCTION: AcpiDmDumpDescending
466
*
467
* PARAMETERS: ASL_WALK_CALLBACK
468
*
469
* RETURN: Status
470
*
471
* DESCRIPTION: Format and print contents of one parse Op.
472
*
473
******************************************************************************/
474
475
static ACPI_STATUS
476
AcpiDmDumpDescending (
477
ACPI_PARSE_OBJECT *Op,
478
UINT32 Level,
479
void *Context)
480
{
481
ACPI_OP_WALK_INFO *Info = Context;
482
char *Path;
483
ACPI_STATUS Status;
484
485
486
if (!Op)
487
{
488
return (AE_OK);
489
}
490
491
/* Most of the information (count, level, name) here */
492
493
Info->Count++;
494
AcpiOsPrintf ("% 5d [%2.2d] ", Info->Count, Level);
495
AcpiDmIndent (Level);
496
AcpiOsPrintf ("%-28s", AcpiPsGetOpcodeName (Op->Common.AmlOpcode));
497
498
/* Extra info is helpful */
499
500
switch (Op->Common.AmlOpcode)
501
{
502
case AML_BYTE_OP:
503
504
AcpiOsPrintf ("%2.2X", (UINT32) Op->Common.Value.Integer);
505
break;
506
507
case AML_WORD_OP:
508
509
AcpiOsPrintf ("%4.4X", (UINT32) Op->Common.Value.Integer);
510
break;
511
512
case AML_DWORD_OP:
513
514
AcpiOsPrintf ("%8.8X", (UINT32) Op->Common.Value.Integer);
515
break;
516
517
case AML_QWORD_OP:
518
519
AcpiOsPrintf ("%8.8X%8.8X", ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
520
break;
521
522
case AML_INT_NAMEPATH_OP:
523
524
if (Op->Common.Value.String)
525
{
526
Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Op->Common.Value.String,
527
NULL, &Path);
528
if (ACPI_SUCCESS (Status))
529
{
530
AcpiOsPrintf ("%s %p", Path, Op->Common.Node);
531
ACPI_FREE (Path);
532
}
533
else
534
{
535
AcpiOsPrintf ("Could not externalize pathname for node [%4.4s]",
536
Op->Common.Node->Name.Ascii);
537
}
538
}
539
else
540
{
541
AcpiOsPrintf ("[NULL]");
542
}
543
break;
544
545
case AML_NAME_OP:
546
case AML_METHOD_OP:
547
case AML_DEVICE_OP:
548
549
AcpiOsPrintf ("%4.4s",
550
ACPI_CAST_PTR (char, &Op->Named.Name));
551
break;
552
553
case AML_INT_NAMEDFIELD_OP:
554
555
AcpiOsPrintf ("%4.4s Length: (bits) %8.8X%8.8X (bytes) %8.8X%8.8X",
556
ACPI_CAST_PTR (char, &Op->Named.Name),
557
ACPI_FORMAT_UINT64 (Op->Common.Value.Integer),
558
ACPI_FORMAT_UINT64 (Op->Common.Value.Integer / 8));
559
break;
560
561
562
default:
563
564
break;
565
}
566
567
AcpiOsPrintf ("\n");
568
return (AE_OK);
569
}
570
571
572
/*******************************************************************************
573
*
574
* FUNCTION: AcpiDmFindOrphanDescending
575
*
576
* PARAMETERS: ASL_WALK_CALLBACK
577
*
578
* RETURN: Status
579
*
580
* DESCRIPTION: Check namepath Ops for orphaned method invocations
581
*
582
* Note: Parts of this are experimental, under possible further development.
583
*
584
******************************************************************************/
585
586
static ACPI_STATUS
587
AcpiDmFindOrphanDescending (
588
ACPI_PARSE_OBJECT *Op,
589
UINT32 Level,
590
void *Context)
591
{
592
const ACPI_OPCODE_INFO *OpInfo;
593
ACPI_PARSE_OBJECT *ChildOp;
594
ACPI_PARSE_OBJECT *NextOp;
595
ACPI_PARSE_OBJECT *ParentOp;
596
UINT32 ArgCount;
597
598
599
if (!Op)
600
{
601
return (AE_OK);
602
}
603
604
#ifdef ACPI_UNDER_DEVELOPMENT
605
OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
606
#endif
607
608
switch (Op->Common.AmlOpcode)
609
{
610
#ifdef ACPI_UNDER_DEVELOPMENT
611
case AML_ADD_OP:
612
613
ChildOp = Op->Common.Value.Arg;
614
if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
615
!ChildOp->Common.Node)
616
{
617
AcpiNsExternalizeName (ACPI_UINT32_MAX, ChildOp->Common.Value.String,
618
NULL, &Path);
619
AcpiOsPrintf ("/* %-16s A-NAMEPATH: %s */\n",
620
Op->Common.AmlOpName, Path);
621
ACPI_FREE (Path);
622
623
NextOp = Op->Common.Next;
624
if (!NextOp)
625
{
626
/* This NamePath has no args, assume it is an integer */
627
628
AcpiDmAddOpToExternalList (ChildOp,
629
ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
630
return (AE_OK);
631
}
632
633
ArgCount = AcpiDmInspectPossibleArgs (3, 1, NextOp);
634
AcpiOsPrintf ("/* A-CHILDREN: %u Actual %u */\n",
635
ArgCount, AcpiDmCountChildren (Op));
636
637
if (ArgCount < 1)
638
{
639
/* One Arg means this is just a Store(Name,Target) */
640
641
AcpiDmAddOpToExternalList (ChildOp,
642
ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
643
return (AE_OK);
644
}
645
646
AcpiDmAddOpToExternalList (ChildOp,
647
ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
648
}
649
break;
650
651
#endif
652
653
case AML_STORE_OP:
654
655
ChildOp = Op->Common.Value.Arg;
656
if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
657
!ChildOp->Common.Node)
658
{
659
NextOp = Op->Common.Next;
660
if (!NextOp)
661
{
662
/* This NamePath has no args, assume it is an integer */
663
664
AcpiDmAddOpToExternalList (ChildOp,
665
ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
666
return (AE_OK);
667
}
668
669
ArgCount = AcpiDmInspectPossibleArgs (2, 1, NextOp);
670
if (ArgCount <= 1)
671
{
672
/* One Arg means this is just a Store(Name,Target) */
673
674
AcpiDmAddOpToExternalList (ChildOp,
675
ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, ArgCount, 0);
676
return (AE_OK);
677
}
678
679
AcpiDmAddOpToExternalList (ChildOp,
680
ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
681
}
682
break;
683
684
case AML_INT_NAMEPATH_OP:
685
686
/* Must examine parent to see if this namepath is an argument */
687
688
ParentOp = Op->Common.Parent;
689
OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
690
691
if ((OpInfo->Class != AML_CLASS_EXECUTE) &&
692
(OpInfo->Class != AML_CLASS_CREATE) &&
693
(OpInfo->ObjectType != ACPI_TYPE_LOCAL_ALIAS) &&
694
(ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
695
!Op->Common.Node)
696
{
697
ArgCount = AcpiDmInspectPossibleArgs (0, 0, Op);
698
699
/*
700
* Check if namepath is a predicate for if/while or lone parameter to
701
* a return.
702
*/
703
if (ArgCount == 0)
704
{
705
if (((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
706
(ParentOp->Common.AmlOpcode == AML_WHILE_OP) ||
707
(ParentOp->Common.AmlOpcode == AML_RETURN_OP)) &&
708
709
/* And namepath is the first argument */
710
(ParentOp->Common.Value.Arg == Op))
711
{
712
AcpiDmAddOpToExternalList (Op,
713
Op->Common.Value.String, ACPI_TYPE_INTEGER, 0, 0);
714
break;
715
}
716
}
717
718
/*
719
* This is a standalone namestring (not a parameter to another
720
* operator) - it *must* be a method invocation, nothing else is
721
* grammatically possible.
722
*/
723
AcpiDmAddOpToExternalList (Op,
724
Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount, 0);
725
}
726
break;
727
728
default:
729
730
break;
731
}
732
733
return (AE_OK);
734
}
735
736
737
/*******************************************************************************
738
*
739
* FUNCTION: AcpiDmLoadDescendingOp
740
*
741
* PARAMETERS: ASL_WALK_CALLBACK
742
*
743
* RETURN: Status
744
*
745
* DESCRIPTION: Descending handler for namespace control method object load
746
*
747
******************************************************************************/
748
749
static ACPI_STATUS
750
AcpiDmLoadDescendingOp (
751
ACPI_PARSE_OBJECT *Op,
752
UINT32 Level,
753
void *Context)
754
{
755
ACPI_OP_WALK_INFO *Info = Context;
756
const ACPI_OPCODE_INFO *OpInfo;
757
ACPI_WALK_STATE *WalkState;
758
ACPI_OBJECT_TYPE ObjectType;
759
ACPI_STATUS Status;
760
char *Path = NULL;
761
ACPI_PARSE_OBJECT *NextOp;
762
ACPI_NAMESPACE_NODE *Node;
763
char FieldPath[5];
764
BOOLEAN PreDefined = FALSE;
765
UINT8 PreDefineIndex = 0;
766
767
768
WalkState = Info->WalkState;
769
OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
770
ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
771
772
/* Only interested in operators that create new names */
773
774
if (!(OpInfo->Flags & AML_NAMED) &&
775
!(OpInfo->Flags & AML_CREATE))
776
{
777
goto Exit;
778
}
779
780
/* Get the NamePath from the appropriate place */
781
782
if (OpInfo->Flags & AML_NAMED)
783
{
784
/* For all named operators, get the new name */
785
786
Path = Op->Named.Path;
787
788
if (!Path && Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
789
{
790
*ACPI_CAST_PTR (UINT32, &FieldPath[0]) = Op->Named.Name;
791
FieldPath[4] = 0;
792
Path = FieldPath;
793
}
794
}
795
else if (OpInfo->Flags & AML_CREATE)
796
{
797
/* New name is the last child */
798
799
NextOp = Op->Common.Value.Arg;
800
801
while (NextOp->Common.Next)
802
{
803
NextOp = NextOp->Common.Next;
804
}
805
806
Path = NextOp->Common.Value.String;
807
}
808
809
if (!Path)
810
{
811
goto Exit;
812
}
813
814
/* Insert the name into the namespace */
815
816
Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
817
ACPI_IMODE_LOAD_PASS2, ACPI_NS_DONT_OPEN_SCOPE,
818
WalkState, &Node);
819
820
Op->Common.Node = Node;
821
822
if (ACPI_SUCCESS (Status))
823
{
824
/* Check if it's a predefined node */
825
826
while (AcpiGbl_PreDefinedNames[PreDefineIndex].Name)
827
{
828
if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii,
829
AcpiGbl_PreDefinedNames[PreDefineIndex].Name))
830
{
831
PreDefined = TRUE;
832
break;
833
}
834
835
PreDefineIndex++;
836
}
837
838
/*
839
* Set node owner id if it satisfies all the following conditions:
840
* 1) Not a predefined node, _SB_ etc
841
* 2) Not the root node
842
* 3) Not a node created by Scope
843
*/
844
if (!PreDefined &&
845
(Node != AcpiGbl_RootNode) &&
846
(Op->Common.AmlOpcode != AML_SCOPE_OP))
847
{
848
Node->OwnerId = WalkState->OwnerId;
849
}
850
}
851
852
853
Exit:
854
855
if (AcpiNsOpensScope (ObjectType))
856
{
857
if (Op->Common.Node)
858
{
859
Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
860
WalkState);
861
if (ACPI_FAILURE (Status))
862
{
863
return (Status);
864
}
865
}
866
}
867
868
return (AE_OK);
869
}
870
871
872
/*******************************************************************************
873
*
874
* FUNCTION: AcpiDmXrefDescendingOp
875
*
876
* PARAMETERS: ASL_WALK_CALLBACK
877
*
878
* RETURN: Status
879
*
880
* DESCRIPTION: Descending handler for namespace cross reference
881
*
882
******************************************************************************/
883
884
static ACPI_STATUS
885
AcpiDmXrefDescendingOp (
886
ACPI_PARSE_OBJECT *Op,
887
UINT32 Level,
888
void *Context)
889
{
890
ACPI_OP_WALK_INFO *Info = Context;
891
const ACPI_OPCODE_INFO *OpInfo;
892
ACPI_WALK_STATE *WalkState;
893
ACPI_OBJECT_TYPE ObjectType;
894
ACPI_OBJECT_TYPE ObjectType2;
895
ACPI_STATUS Status;
896
char *Path = NULL;
897
ACPI_PARSE_OBJECT *NextOp;
898
ACPI_NAMESPACE_NODE *Node;
899
ACPI_OPERAND_OBJECT *Object;
900
UINT32 ParamCount = 0;
901
char *Pathname;
902
UINT16 Flags = 0;
903
904
905
WalkState = Info->WalkState;
906
OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
907
ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
908
909
if ((!(OpInfo->Flags & AML_NAMED)) &&
910
(!(OpInfo->Flags & AML_CREATE)) &&
911
(Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP) &&
912
(Op->Common.AmlOpcode != AML_NOTIFY_OP))
913
{
914
goto Exit;
915
}
916
917
/* Get the NamePath from the appropriate place */
918
919
if (OpInfo->Flags & AML_NAMED)
920
{
921
/*
922
* Only these two operators (Alias, Scope) refer to an existing
923
* name, it is the first argument
924
*/
925
if (Op->Common.AmlOpcode == AML_ALIAS_OP)
926
{
927
ObjectType = ACPI_TYPE_ANY;
928
929
NextOp = Op->Common.Value.Arg;
930
NextOp = NextOp->Common.Value.Arg;
931
if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
932
{
933
Path = NextOp->Common.Value.String;
934
}
935
}
936
else if (Op->Common.AmlOpcode == AML_SCOPE_OP ||
937
Op->Common.AmlOpcode == AML_EXTERNAL_OP)
938
{
939
Path = Op->Named.Path;
940
}
941
}
942
else if (OpInfo->Flags & AML_CREATE)
943
{
944
/* Referenced Buffer Name is the first child */
945
946
ObjectType = ACPI_TYPE_BUFFER; /* Change from TYPE_BUFFER_FIELD */
947
948
NextOp = Op->Common.Value.Arg;
949
if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
950
{
951
Path = NextOp->Common.Value.String;
952
}
953
}
954
else if (Op->Common.AmlOpcode == AML_NOTIFY_OP)
955
{
956
Path = Op->Common.Value.Arg->Asl.Value.String;
957
}
958
else
959
{
960
Path = Op->Common.Value.String;
961
}
962
963
if (!Path)
964
{
965
goto Exit;
966
}
967
968
/*
969
* Lookup the name in the namespace. Name must exist at this point, or it
970
* is an invalid reference.
971
*
972
* The namespace is also used as a lookup table for references to resource
973
* descriptors and the fields within them.
974
*/
975
Node = NULL;
976
Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
977
ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
978
WalkState, &Node);
979
980
if (ACPI_SUCCESS (Status) && (Node->Flags & ANOBJ_IS_EXTERNAL))
981
{
982
/* Node was created by an External() statement */
983
984
Status = AE_NOT_FOUND;
985
}
986
987
if (ACPI_FAILURE (Status))
988
{
989
if (Status == AE_NOT_FOUND)
990
{
991
/*
992
* Add this symbol as an external declaration, except if the
993
* parent is a CondRefOf operator. For this operator, we do not
994
* need an external, nor do we want one, since this can cause
995
* disassembly problems if the symbol is actually a control
996
* method.
997
*/
998
if (!(Op->Asl.Parent &&
999
(Op->Asl.Parent->Asl.AmlOpcode == AML_CONDITIONAL_REF_OF_OP)))
1000
{
1001
if (Node)
1002
{
1003
AcpiDmAddNodeToExternalList (Node,
1004
(UINT8) ObjectType, 7, Flags);
1005
}
1006
else
1007
{
1008
AcpiDmAddOpToExternalList (Op, Path,
1009
(UINT8) ObjectType, 7, Flags);
1010
}
1011
}
1012
}
1013
}
1014
1015
/*
1016
* Found the node, but check if it came from an external table.
1017
* Add it to external list. Note: Node->OwnerId == 0 indicates
1018
* one of the built-in ACPI Names (_OS_ etc.) which can safely
1019
* be ignored.
1020
*/
1021
else if (Node->OwnerId &&
1022
(WalkState->OwnerId != Node->OwnerId))
1023
{
1024
ObjectType2 = ObjectType;
1025
1026
Object = AcpiNsGetAttachedObject (Node);
1027
if (Object)
1028
{
1029
ObjectType2 = Object->Common.Type;
1030
if (ObjectType2 == ACPI_TYPE_METHOD)
1031
{
1032
ParamCount = Object->Method.ParamCount;
1033
}
1034
}
1035
1036
Pathname = AcpiNsGetExternalPathname (Node);
1037
if (!Pathname)
1038
{
1039
return (AE_NO_MEMORY);
1040
}
1041
1042
AcpiDmAddNodeToExternalList (Node, (UINT8) ObjectType2,
1043
ParamCount, ACPI_EXT_RESOLVED_REFERENCE);
1044
1045
ACPI_FREE (Pathname);
1046
Op->Common.Node = Node;
1047
}
1048
else
1049
{
1050
Op->Common.Node = Node;
1051
}
1052
1053
1054
Exit:
1055
/* Open new scope if necessary */
1056
1057
if (AcpiNsOpensScope (ObjectType))
1058
{
1059
if (Op->Common.Node)
1060
{
1061
Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
1062
WalkState);
1063
if (ACPI_FAILURE (Status))
1064
{
1065
return (Status);
1066
}
1067
}
1068
}
1069
1070
return (AE_OK);
1071
}
1072
1073
/*******************************************************************************
1074
*
1075
* FUNCTION: AcpiDmCommonDescendingOp
1076
*
1077
* PARAMETERS: ASL_WALK_CALLBACK
1078
*
1079
* RETURN: ACPI_STATUS
1080
*
1081
* DESCRIPTION: Perform parse tree preprocessing before main disassembly walk.
1082
*
1083
******************************************************************************/
1084
1085
static ACPI_STATUS
1086
AcpiDmCommonDescendingOp (
1087
ACPI_PARSE_OBJECT *Op,
1088
UINT32 Level,
1089
void *Context)
1090
{
1091
ACPI_STATUS Status;
1092
1093
1094
/* Resource descriptor conversion */
1095
1096
Status = AcpiDmProcessResourceDescriptors (Op, Level, Context);
1097
if (ACPI_FAILURE (Status))
1098
{
1099
return (Status);
1100
}
1101
1102
/* Switch/Case conversion */
1103
1104
Status = AcpiDmProcessSwitch (Op);
1105
return (Status);
1106
}
1107
1108
1109
/*******************************************************************************
1110
*
1111
* FUNCTION: AcpiDmProcessResourceDescriptors
1112
*
1113
* PARAMETERS: ASL_WALK_CALLBACK
1114
*
1115
* RETURN: ACPI_STATUS
1116
*
1117
* DESCRIPTION: Convert fixed-offset references to resource descriptors to
1118
* symbolic references. Should only be called after namespace has
1119
* been cross referenced.
1120
*
1121
******************************************************************************/
1122
1123
static ACPI_STATUS
1124
AcpiDmProcessResourceDescriptors (
1125
ACPI_PARSE_OBJECT *Op,
1126
UINT32 Level,
1127
void *Context)
1128
{
1129
ACPI_OP_WALK_INFO *Info = Context;
1130
const ACPI_OPCODE_INFO *OpInfo;
1131
ACPI_WALK_STATE *WalkState;
1132
ACPI_OBJECT_TYPE ObjectType;
1133
ACPI_STATUS Status;
1134
1135
1136
WalkState = Info->WalkState;
1137
OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1138
1139
/* Open new scope if necessary */
1140
1141
ObjectType = OpInfo->ObjectType;
1142
if (AcpiNsOpensScope (ObjectType))
1143
{
1144
if (Op->Common.Node)
1145
{
1146
1147
Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
1148
WalkState);
1149
if (ACPI_FAILURE (Status))
1150
{
1151
return (Status);
1152
}
1153
}
1154
}
1155
1156
/*
1157
* Check if this operator contains a reference to a resource descriptor.
1158
* If so, convert the reference into a symbolic reference.
1159
*/
1160
AcpiDmCheckResourceReference (Op, WalkState);
1161
return (AE_OK);
1162
}
1163
1164
/*******************************************************************************
1165
*
1166
* FUNCTION: AcpiDmCommonAscendingOp
1167
*
1168
* PARAMETERS: ASL_WALK_CALLBACK
1169
*
1170
* RETURN: None
1171
*
1172
* DESCRIPTION: Ascending handler for combined parse/namespace walks. Closes
1173
* scope if necessary.
1174
*
1175
******************************************************************************/
1176
1177
static ACPI_STATUS
1178
AcpiDmCommonAscendingOp (
1179
ACPI_PARSE_OBJECT *Op,
1180
UINT32 Level,
1181
void *Context)
1182
{
1183
ACPI_OP_WALK_INFO *Info = Context;
1184
ACPI_OBJECT_TYPE ObjectType;
1185
1186
1187
/* Close scope if necessary */
1188
1189
ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
1190
1191
if (AcpiNsOpensScope (ObjectType))
1192
{
1193
(void) AcpiDsScopeStackPop (Info->WalkState);
1194
}
1195
1196
return (AE_OK);
1197
}
1198
1199
/*******************************************************************************
1200
*
1201
* FUNCTION: AcpiDmInspectPossibleArgs
1202
*
1203
* PARAMETERS: CurrentOpArgCount - Which arg of the current op was the
1204
* possible method invocation found
1205
* TargetCount - Number of targets (0,1,2) for this op
1206
* Op - Parse op
1207
*
1208
* RETURN: Status
1209
*
1210
* DESCRIPTION: Examine following args and next ops for possible arguments
1211
* for an unrecognized method invocation.
1212
*
1213
******************************************************************************/
1214
1215
static UINT32
1216
AcpiDmInspectPossibleArgs (
1217
UINT32 CurrentOpArgCount,
1218
UINT32 TargetCount,
1219
ACPI_PARSE_OBJECT *Op)
1220
{
1221
const ACPI_OPCODE_INFO *OpInfo;
1222
UINT32 i;
1223
UINT32 ArgumentCount = 0;
1224
ACPI_PARSE_OBJECT *NextOp;
1225
ACPI_PARSE_OBJECT *ExecuteOp;
1226
1227
1228
if (!Op)
1229
{
1230
return (0);
1231
}
1232
1233
/* Lookahead for the maximum number of possible arguments */
1234
1235
NextOp = Op->Common.Next;
1236
1237
for (i = 0; (i < ACPI_METHOD_NUM_ARGS) && NextOp; i++)
1238
{
1239
OpInfo = AcpiPsGetOpcodeInfo (NextOp->Common.AmlOpcode);
1240
1241
/* Any one of these operators is "very probably" not a method arg */
1242
1243
if ((NextOp->Common.AmlOpcode == AML_STORE_OP) ||
1244
(NextOp->Common.AmlOpcode == AML_NOTIFY_OP) ||
1245
(OpInfo->Class == AML_CLASS_CONTROL) ||
1246
(OpInfo->Class == AML_CLASS_CREATE) ||
1247
(OpInfo->Class == AML_CLASS_NAMED_OBJECT))
1248
{
1249
break;
1250
}
1251
1252
if (OpInfo->Class == AML_CLASS_EXECUTE)
1253
{
1254
/* Probable that this is method arg if there is no target */
1255
1256
ExecuteOp = NextOp->Common.Value.Arg;
1257
while (ExecuteOp)
1258
{
1259
if ((ExecuteOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
1260
(ExecuteOp->Common.Value.Arg == NULL))
1261
{
1262
/* No target, could be a method arg */
1263
1264
break;
1265
}
1266
1267
if (NextOp->Common.AmlOpcode == AML_REF_OF_OP)
1268
{
1269
break;
1270
}
1271
1272
ExecuteOp = ExecuteOp->Common.Next;
1273
}
1274
1275
if (!ExecuteOp)
1276
{
1277
/* Has a target, not method arg */
1278
1279
return (ArgumentCount);
1280
}
1281
}
1282
1283
ArgumentCount++;
1284
NextOp = NextOp->Common.Next;
1285
}
1286
1287
return (ArgumentCount);
1288
}
1289
1290