Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c
48521 views
1
/******************************************************************************
2
*
3
* Module Name: dsopcode - Dispatcher support for regions and fields
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/acdispat.h>
157
#include <contrib/dev/acpica/include/acinterp.h>
158
#include <contrib/dev/acpica/include/acnamesp.h>
159
#include <contrib/dev/acpica/include/acevents.h>
160
#include <contrib/dev/acpica/include/actables.h>
161
162
#define _COMPONENT ACPI_DISPATCHER
163
ACPI_MODULE_NAME ("dsopcode")
164
165
/* Local prototypes */
166
167
static ACPI_STATUS
168
AcpiDsInitBufferField (
169
UINT16 AmlOpcode,
170
ACPI_OPERAND_OBJECT *ObjDesc,
171
ACPI_OPERAND_OBJECT *BufferDesc,
172
ACPI_OPERAND_OBJECT *OffsetDesc,
173
ACPI_OPERAND_OBJECT *LengthDesc,
174
ACPI_OPERAND_OBJECT *ResultDesc);
175
176
177
/*******************************************************************************
178
*
179
* FUNCTION: AcpiDsInitializeRegion
180
*
181
* PARAMETERS: ObjHandle - Region namespace node
182
*
183
* RETURN: Status
184
*
185
* DESCRIPTION: Front end to EvInitializeRegion
186
*
187
******************************************************************************/
188
189
ACPI_STATUS
190
AcpiDsInitializeRegion (
191
ACPI_HANDLE ObjHandle)
192
{
193
ACPI_OPERAND_OBJECT *ObjDesc;
194
ACPI_STATUS Status;
195
196
197
ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
198
199
/* Namespace is NOT locked */
200
201
Status = AcpiEvInitializeRegion (ObjDesc);
202
return (Status);
203
}
204
205
206
/*******************************************************************************
207
*
208
* FUNCTION: AcpiDsInitBufferField
209
*
210
* PARAMETERS: AmlOpcode - CreateXxxField
211
* ObjDesc - BufferField object
212
* BufferDesc - Host Buffer
213
* OffsetDesc - Offset into buffer
214
* LengthDesc - Length of field (CREATE_FIELD_OP only)
215
* ResultDesc - Where to store the result
216
*
217
* RETURN: Status
218
*
219
* DESCRIPTION: Perform actual initialization of a buffer field
220
*
221
******************************************************************************/
222
223
static ACPI_STATUS
224
AcpiDsInitBufferField (
225
UINT16 AmlOpcode,
226
ACPI_OPERAND_OBJECT *ObjDesc,
227
ACPI_OPERAND_OBJECT *BufferDesc,
228
ACPI_OPERAND_OBJECT *OffsetDesc,
229
ACPI_OPERAND_OBJECT *LengthDesc,
230
ACPI_OPERAND_OBJECT *ResultDesc)
231
{
232
UINT32 Offset;
233
UINT32 BitOffset;
234
UINT32 BitCount;
235
UINT8 FieldFlags;
236
ACPI_STATUS Status;
237
238
239
ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc);
240
241
242
/* Host object must be a Buffer */
243
244
if (BufferDesc->Common.Type != ACPI_TYPE_BUFFER)
245
{
246
ACPI_ERROR ((AE_INFO,
247
"Target of Create Field is not a Buffer object - %s",
248
AcpiUtGetObjectTypeName (BufferDesc)));
249
250
Status = AE_AML_OPERAND_TYPE;
251
goto Cleanup;
252
}
253
254
/*
255
* The last parameter to all of these opcodes (ResultDesc) started
256
* out as a NameString, and should therefore now be a NS node
257
* after resolution in AcpiExResolveOperands().
258
*/
259
if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
260
{
261
ACPI_ERROR ((AE_INFO,
262
"(%s) destination not a NS Node [%s]",
263
AcpiPsGetOpcodeName (AmlOpcode),
264
AcpiUtGetDescriptorName (ResultDesc)));
265
266
Status = AE_AML_OPERAND_TYPE;
267
goto Cleanup;
268
}
269
270
Offset = (UINT32) OffsetDesc->Integer.Value;
271
272
/*
273
* Setup the Bit offsets and counts, according to the opcode
274
*/
275
switch (AmlOpcode)
276
{
277
case AML_CREATE_FIELD_OP:
278
279
/* Offset is in bits, count is in bits */
280
281
FieldFlags = AML_FIELD_ACCESS_BYTE;
282
BitOffset = Offset;
283
BitCount = (UINT32) LengthDesc->Integer.Value;
284
285
/* Must have a valid (>0) bit count */
286
287
if (BitCount == 0)
288
{
289
ACPI_BIOS_ERROR ((AE_INFO,
290
"Attempt to CreateField of length zero"));
291
Status = AE_AML_OPERAND_VALUE;
292
goto Cleanup;
293
}
294
break;
295
296
case AML_CREATE_BIT_FIELD_OP:
297
298
/* Offset is in bits, Field is one bit */
299
300
BitOffset = Offset;
301
BitCount = 1;
302
FieldFlags = AML_FIELD_ACCESS_BYTE;
303
break;
304
305
case AML_CREATE_BYTE_FIELD_OP:
306
307
/* Offset is in bytes, field is one byte */
308
309
BitOffset = 8 * Offset;
310
BitCount = 8;
311
FieldFlags = AML_FIELD_ACCESS_BYTE;
312
break;
313
314
case AML_CREATE_WORD_FIELD_OP:
315
316
/* Offset is in bytes, field is one word */
317
318
BitOffset = 8 * Offset;
319
BitCount = 16;
320
FieldFlags = AML_FIELD_ACCESS_WORD;
321
break;
322
323
case AML_CREATE_DWORD_FIELD_OP:
324
325
/* Offset is in bytes, field is one dword */
326
327
BitOffset = 8 * Offset;
328
BitCount = 32;
329
FieldFlags = AML_FIELD_ACCESS_DWORD;
330
break;
331
332
case AML_CREATE_QWORD_FIELD_OP:
333
334
/* Offset is in bytes, field is one qword */
335
336
BitOffset = 8 * Offset;
337
BitCount = 64;
338
FieldFlags = AML_FIELD_ACCESS_QWORD;
339
break;
340
341
default:
342
343
ACPI_ERROR ((AE_INFO,
344
"Unknown field creation opcode 0x%02X",
345
AmlOpcode));
346
Status = AE_AML_BAD_OPCODE;
347
goto Cleanup;
348
}
349
350
/* Entire field must fit within the current length of the buffer */
351
352
if ((BitOffset + BitCount) >
353
(8 * (UINT32) BufferDesc->Buffer.Length))
354
{
355
Status = AE_AML_BUFFER_LIMIT;
356
ACPI_BIOS_EXCEPTION ((AE_INFO, Status,
357
"Field [%4.4s] at bit offset/length %u/%u "
358
"exceeds size of target Buffer (%u bits)",
359
AcpiUtGetNodeName (ResultDesc), BitOffset, BitCount,
360
8 * (UINT32) BufferDesc->Buffer.Length));
361
goto Cleanup;
362
}
363
364
/*
365
* Initialize areas of the field object that are common to all fields
366
* For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
367
* UPDATE_RULE = 0 (UPDATE_PRESERVE)
368
*/
369
Status = AcpiExPrepCommonFieldObject (
370
ObjDesc, FieldFlags, 0, BitOffset, BitCount);
371
if (ACPI_FAILURE (Status))
372
{
373
goto Cleanup;
374
}
375
376
ObjDesc->BufferField.BufferObj = BufferDesc;
377
ObjDesc->BufferField.IsCreateField = AmlOpcode == AML_CREATE_FIELD_OP;
378
379
/* Reference count for BufferDesc inherits ObjDesc count */
380
381
BufferDesc->Common.ReferenceCount = (UINT16)
382
(BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);
383
384
385
Cleanup:
386
387
/* Always delete the operands */
388
389
AcpiUtRemoveReference (OffsetDesc);
390
AcpiUtRemoveReference (BufferDesc);
391
392
if (AmlOpcode == AML_CREATE_FIELD_OP)
393
{
394
AcpiUtRemoveReference (LengthDesc);
395
}
396
397
/* On failure, delete the result descriptor */
398
399
if (ACPI_FAILURE (Status))
400
{
401
AcpiUtRemoveReference (ResultDesc); /* Result descriptor */
402
}
403
else
404
{
405
/* Now the address and length are valid for this BufferField */
406
407
ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
408
}
409
410
return_ACPI_STATUS (Status);
411
}
412
413
414
/*******************************************************************************
415
*
416
* FUNCTION: AcpiDsEvalBufferFieldOperands
417
*
418
* PARAMETERS: WalkState - Current walk
419
* Op - A valid BufferField Op object
420
*
421
* RETURN: Status
422
*
423
* DESCRIPTION: Get BufferField Buffer and Index
424
* Called from AcpiDsExecEndOp during BufferField parse tree walk
425
*
426
******************************************************************************/
427
428
ACPI_STATUS
429
AcpiDsEvalBufferFieldOperands (
430
ACPI_WALK_STATE *WalkState,
431
ACPI_PARSE_OBJECT *Op)
432
{
433
ACPI_STATUS Status;
434
ACPI_OPERAND_OBJECT *ObjDesc;
435
ACPI_NAMESPACE_NODE *Node;
436
ACPI_PARSE_OBJECT *NextOp;
437
438
439
ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op);
440
441
442
/*
443
* This is where we evaluate the address and length fields of the
444
* CreateXxxField declaration
445
*/
446
Node = Op->Common.Node;
447
448
/* NextOp points to the op that holds the Buffer */
449
450
NextOp = Op->Common.Value.Arg;
451
452
/* Evaluate/create the address and length operands */
453
454
Status = AcpiDsCreateOperands (WalkState, NextOp);
455
if (ACPI_FAILURE (Status))
456
{
457
return_ACPI_STATUS (Status);
458
}
459
460
ObjDesc = AcpiNsGetAttachedObject (Node);
461
if (!ObjDesc)
462
{
463
return_ACPI_STATUS (AE_NOT_EXIST);
464
}
465
466
/* Resolve the operands */
467
468
Status = AcpiExResolveOperands (
469
Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
470
if (ACPI_FAILURE (Status))
471
{
472
ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
473
AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
474
475
return_ACPI_STATUS (Status);
476
}
477
478
/* Initialize the Buffer Field */
479
480
if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
481
{
482
/* NOTE: Slightly different operands for this opcode */
483
484
Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
485
WalkState->Operands[0], WalkState->Operands[1],
486
WalkState->Operands[2], WalkState->Operands[3]);
487
}
488
else
489
{
490
/* All other, CreateXxxField opcodes */
491
492
Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
493
WalkState->Operands[0], WalkState->Operands[1],
494
NULL, WalkState->Operands[2]);
495
}
496
497
return_ACPI_STATUS (Status);
498
}
499
500
501
/*******************************************************************************
502
*
503
* FUNCTION: AcpiDsEvalRegionOperands
504
*
505
* PARAMETERS: WalkState - Current walk
506
* Op - A valid region Op object
507
*
508
* RETURN: Status
509
*
510
* DESCRIPTION: Get region address and length
511
* Called from AcpiDsExecEndOp during OpRegion parse tree walk
512
*
513
******************************************************************************/
514
515
ACPI_STATUS
516
AcpiDsEvalRegionOperands (
517
ACPI_WALK_STATE *WalkState,
518
ACPI_PARSE_OBJECT *Op)
519
{
520
ACPI_STATUS Status;
521
ACPI_OPERAND_OBJECT *ObjDesc;
522
ACPI_OPERAND_OBJECT *OperandDesc;
523
ACPI_NAMESPACE_NODE *Node;
524
ACPI_PARSE_OBJECT *NextOp;
525
ACPI_ADR_SPACE_TYPE SpaceId;
526
527
528
ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op);
529
530
531
/*
532
* This is where we evaluate the address and length fields of the
533
* OpRegion declaration
534
*/
535
Node = Op->Common.Node;
536
537
/* NextOp points to the op that holds the SpaceID */
538
539
NextOp = Op->Common.Value.Arg;
540
SpaceId = (ACPI_ADR_SPACE_TYPE) NextOp->Common.Value.Integer;
541
542
/* NextOp points to address op */
543
544
NextOp = NextOp->Common.Next;
545
546
/* Evaluate/create the address and length operands */
547
548
Status = AcpiDsCreateOperands (WalkState, NextOp);
549
if (ACPI_FAILURE (Status))
550
{
551
return_ACPI_STATUS (Status);
552
}
553
554
/* Resolve the length and address operands to numbers */
555
556
Status = AcpiExResolveOperands (
557
Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
558
if (ACPI_FAILURE (Status))
559
{
560
return_ACPI_STATUS (Status);
561
}
562
563
ObjDesc = AcpiNsGetAttachedObject (Node);
564
if (!ObjDesc)
565
{
566
return_ACPI_STATUS (AE_NOT_EXIST);
567
}
568
569
/*
570
* Get the length operand and save it
571
* (at Top of stack)
572
*/
573
OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
574
575
ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
576
AcpiUtRemoveReference (OperandDesc);
577
578
/* A zero-length operation region is unusable. Just warn */
579
580
if (!ObjDesc->Region.Length && (SpaceId < ACPI_NUM_PREDEFINED_REGIONS))
581
{
582
ACPI_WARNING ((AE_INFO,
583
"Operation Region [%4.4s] has zero length (SpaceId %X)",
584
Node->Name.Ascii, SpaceId));
585
}
586
587
/*
588
* Get the address and save it
589
* (at top of stack - 1)
590
*/
591
OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
592
593
ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS)
594
OperandDesc->Integer.Value;
595
AcpiUtRemoveReference (OperandDesc);
596
597
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
598
ObjDesc, ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
599
ObjDesc->Region.Length));
600
601
Status = AcpiUtAddAddressRange (ObjDesc->Region.SpaceId,
602
ObjDesc->Region.Address, ObjDesc->Region.Length, Node);
603
604
/* Now the address and length are valid for this opregion */
605
606
ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
607
return_ACPI_STATUS (Status);
608
}
609
610
611
/*******************************************************************************
612
*
613
* FUNCTION: AcpiDsEvalTableRegionOperands
614
*
615
* PARAMETERS: WalkState - Current walk
616
* Op - A valid region Op object
617
*
618
* RETURN: Status
619
*
620
* DESCRIPTION: Get region address and length.
621
* Called from AcpiDsExecEndOp during DataTableRegion parse
622
* tree walk.
623
*
624
******************************************************************************/
625
626
ACPI_STATUS
627
AcpiDsEvalTableRegionOperands (
628
ACPI_WALK_STATE *WalkState,
629
ACPI_PARSE_OBJECT *Op)
630
{
631
ACPI_STATUS Status;
632
ACPI_OPERAND_OBJECT *ObjDesc;
633
ACPI_OPERAND_OBJECT **Operand;
634
ACPI_NAMESPACE_NODE *Node;
635
ACPI_PARSE_OBJECT *NextOp;
636
ACPI_TABLE_HEADER *Table;
637
UINT32 TableIndex;
638
639
640
ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op);
641
642
643
/*
644
* This is where we evaluate the Signature string, OemId string,
645
* and OemTableId string of the Data Table Region declaration
646
*/
647
Node = Op->Common.Node;
648
649
/* NextOp points to Signature string op */
650
651
NextOp = Op->Common.Value.Arg;
652
653
/*
654
* Evaluate/create the Signature string, OemId string,
655
* and OemTableId string operands
656
*/
657
Status = AcpiDsCreateOperands (WalkState, NextOp);
658
if (ACPI_FAILURE (Status))
659
{
660
return_ACPI_STATUS (Status);
661
}
662
663
Operand = &WalkState->Operands[0];
664
665
/*
666
* Resolve the Signature string, OemId string,
667
* and OemTableId string operands
668
*/
669
Status = AcpiExResolveOperands (
670
Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState);
671
if (ACPI_FAILURE (Status))
672
{
673
goto Cleanup;
674
}
675
676
/* Find the ACPI table */
677
678
Status = AcpiTbFindTable (
679
Operand[0]->String.Pointer,
680
Operand[1]->String.Pointer,
681
Operand[2]->String.Pointer, &TableIndex);
682
if (ACPI_FAILURE (Status))
683
{
684
if (Status == AE_NOT_FOUND)
685
{
686
ACPI_ERROR ((AE_INFO,
687
"ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT",
688
Operand[0]->String.Pointer,
689
Operand[1]->String.Pointer,
690
Operand[2]->String.Pointer));
691
}
692
goto Cleanup;
693
}
694
695
Status = AcpiGetTableByIndex (TableIndex, &Table);
696
if (ACPI_FAILURE (Status))
697
{
698
goto Cleanup;
699
}
700
701
ObjDesc = AcpiNsGetAttachedObject (Node);
702
if (!ObjDesc)
703
{
704
Status = AE_NOT_EXIST;
705
goto Cleanup;
706
}
707
708
ObjDesc->Region.Address = ACPI_PTR_TO_PHYSADDR (Table);
709
ObjDesc->Region.Length = Table->Length;
710
ObjDesc->Region.Pointer = Table;
711
712
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
713
ObjDesc, ACPI_FORMAT_UINT64 (ObjDesc->Region.Address),
714
ObjDesc->Region.Length));
715
716
/* Now the address and length are valid for this opregion */
717
718
ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
719
720
Cleanup:
721
AcpiUtRemoveReference (Operand[0]);
722
AcpiUtRemoveReference (Operand[1]);
723
AcpiUtRemoveReference (Operand[2]);
724
725
return_ACPI_STATUS (Status);
726
}
727
728
729
/*******************************************************************************
730
*
731
* FUNCTION: AcpiDsEvalDataObjectOperands
732
*
733
* PARAMETERS: WalkState - Current walk
734
* Op - A valid DataObject Op object
735
* ObjDesc - DataObject
736
*
737
* RETURN: Status
738
*
739
* DESCRIPTION: Get the operands and complete the following data object types:
740
* Buffer, Package.
741
*
742
******************************************************************************/
743
744
ACPI_STATUS
745
AcpiDsEvalDataObjectOperands (
746
ACPI_WALK_STATE *WalkState,
747
ACPI_PARSE_OBJECT *Op,
748
ACPI_OPERAND_OBJECT *ObjDesc)
749
{
750
ACPI_STATUS Status;
751
ACPI_OPERAND_OBJECT *ArgDesc;
752
UINT32 Length;
753
754
755
ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands);
756
757
758
/* The first operand (for all of these data objects) is the length */
759
760
/*
761
* Set proper index into operand stack for AcpiDsObjStackPush
762
* invoked inside AcpiDsCreateOperand.
763
*/
764
WalkState->OperandIndex = WalkState->NumOperands;
765
766
/* Ignore if child is not valid */
767
768
if (!Op->Common.Value.Arg)
769
{
770
ACPI_ERROR ((AE_INFO,
771
"Missing child while evaluating opcode %4.4X, Op %p",
772
Op->Common.AmlOpcode, Op));
773
return_ACPI_STATUS (AE_OK);
774
}
775
776
Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
777
if (ACPI_FAILURE (Status))
778
{
779
return_ACPI_STATUS (Status);
780
}
781
782
Status = AcpiExResolveOperands (WalkState->Opcode,
783
&(WalkState->Operands [WalkState->NumOperands -1]),
784
WalkState);
785
if (ACPI_FAILURE (Status))
786
{
787
return_ACPI_STATUS (Status);
788
}
789
790
/* Extract length operand */
791
792
ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
793
Length = (UINT32) ArgDesc->Integer.Value;
794
795
/* Cleanup for length operand */
796
797
Status = AcpiDsObjStackPop (1, WalkState);
798
if (ACPI_FAILURE (Status))
799
{
800
return_ACPI_STATUS (Status);
801
}
802
803
AcpiUtRemoveReference (ArgDesc);
804
805
/*
806
* Create the actual data object
807
*/
808
switch (Op->Common.AmlOpcode)
809
{
810
case AML_BUFFER_OP:
811
812
Status = AcpiDsBuildInternalBufferObj (
813
WalkState, Op, Length, &ObjDesc);
814
break;
815
816
case AML_PACKAGE_OP:
817
case AML_VARIABLE_PACKAGE_OP:
818
819
Status = AcpiDsBuildInternalPackageObj (
820
WalkState, Op, Length, &ObjDesc);
821
break;
822
823
default:
824
825
return_ACPI_STATUS (AE_AML_BAD_OPCODE);
826
}
827
828
if (ACPI_SUCCESS (Status))
829
{
830
/*
831
* Return the object in the WalkState, unless the parent is a package -
832
* in this case, the return object will be stored in the parse tree
833
* for the package.
834
*/
835
if ((!Op->Common.Parent) ||
836
((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
837
(Op->Common.Parent->Common.AmlOpcode != AML_VARIABLE_PACKAGE_OP) &&
838
(Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
839
{
840
WalkState->ResultObj = ObjDesc;
841
}
842
}
843
844
return_ACPI_STATUS (Status);
845
}
846
847
848
/*******************************************************************************
849
*
850
* FUNCTION: AcpiDsEvalBankFieldOperands
851
*
852
* PARAMETERS: WalkState - Current walk
853
* Op - A valid BankField Op object
854
*
855
* RETURN: Status
856
*
857
* DESCRIPTION: Get BankField BankValue
858
* Called from AcpiDsExecEndOp during BankField parse tree walk
859
*
860
******************************************************************************/
861
862
ACPI_STATUS
863
AcpiDsEvalBankFieldOperands (
864
ACPI_WALK_STATE *WalkState,
865
ACPI_PARSE_OBJECT *Op)
866
{
867
ACPI_STATUS Status;
868
ACPI_OPERAND_OBJECT *ObjDesc;
869
ACPI_OPERAND_OBJECT *OperandDesc;
870
ACPI_NAMESPACE_NODE *Node;
871
ACPI_PARSE_OBJECT *NextOp;
872
ACPI_PARSE_OBJECT *Arg;
873
874
875
ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands, Op);
876
877
878
/*
879
* This is where we evaluate the BankValue field of the
880
* BankField declaration
881
*/
882
883
/* NextOp points to the op that holds the Region */
884
885
NextOp = Op->Common.Value.Arg;
886
887
/* NextOp points to the op that holds the Bank Register */
888
889
NextOp = NextOp->Common.Next;
890
891
/* NextOp points to the op that holds the Bank Value */
892
893
NextOp = NextOp->Common.Next;
894
895
/*
896
* Set proper index into operand stack for AcpiDsObjStackPush
897
* invoked inside AcpiDsCreateOperand.
898
*
899
* We use WalkState->Operands[0] to store the evaluated BankValue
900
*/
901
WalkState->OperandIndex = 0;
902
903
Status = AcpiDsCreateOperand (WalkState, NextOp, 0);
904
if (ACPI_FAILURE (Status))
905
{
906
return_ACPI_STATUS (Status);
907
}
908
909
Status = AcpiExResolveToValue (&WalkState->Operands[0], WalkState);
910
if (ACPI_FAILURE (Status))
911
{
912
return_ACPI_STATUS (Status);
913
}
914
915
ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS,
916
AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 1);
917
/*
918
* Get the BankValue operand and save it
919
* (at Top of stack)
920
*/
921
OperandDesc = WalkState->Operands[0];
922
923
/* Arg points to the start Bank Field */
924
925
Arg = AcpiPsGetArg (Op, 4);
926
while (Arg)
927
{
928
/* Ignore OFFSET and ACCESSAS terms here */
929
930
if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
931
{
932
Node = Arg->Common.Node;
933
934
ObjDesc = AcpiNsGetAttachedObject (Node);
935
if (!ObjDesc)
936
{
937
return_ACPI_STATUS (AE_NOT_EXIST);
938
}
939
940
ObjDesc->BankField.Value = (UINT32) OperandDesc->Integer.Value;
941
}
942
943
/* Move to next field in the list */
944
945
Arg = Arg->Common.Next;
946
}
947
948
AcpiUtRemoveReference (OperandDesc);
949
return_ACPI_STATUS (Status);
950
}
951
952