Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/acpi/acpica/dsopcode.c
15109 views
1
/******************************************************************************
2
*
3
* Module Name: dsopcode - Dispatcher suport for regions and fields
4
*
5
*****************************************************************************/
6
7
/*
8
* Copyright (C) 2000 - 2011, 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
#include <acpi/acpi.h>
45
#include "accommon.h"
46
#include "acparser.h"
47
#include "amlcode.h"
48
#include "acdispat.h"
49
#include "acinterp.h"
50
#include "acnamesp.h"
51
#include "acevents.h"
52
#include "actables.h"
53
54
#define _COMPONENT ACPI_DISPATCHER
55
ACPI_MODULE_NAME("dsopcode")
56
57
/* Local prototypes */
58
static acpi_status
59
acpi_ds_init_buffer_field(u16 aml_opcode,
60
union acpi_operand_object *obj_desc,
61
union acpi_operand_object *buffer_desc,
62
union acpi_operand_object *offset_desc,
63
union acpi_operand_object *length_desc,
64
union acpi_operand_object *result_desc);
65
66
/*******************************************************************************
67
*
68
* FUNCTION: acpi_ds_initialize_region
69
*
70
* PARAMETERS: obj_handle - Region namespace node
71
*
72
* RETURN: Status
73
*
74
* DESCRIPTION: Front end to ev_initialize_region
75
*
76
******************************************************************************/
77
78
acpi_status acpi_ds_initialize_region(acpi_handle obj_handle)
79
{
80
union acpi_operand_object *obj_desc;
81
acpi_status status;
82
83
obj_desc = acpi_ns_get_attached_object(obj_handle);
84
85
/* Namespace is NOT locked */
86
87
status = acpi_ev_initialize_region(obj_desc, FALSE);
88
return (status);
89
}
90
91
/*******************************************************************************
92
*
93
* FUNCTION: acpi_ds_init_buffer_field
94
*
95
* PARAMETERS: aml_opcode - create_xxx_field
96
* obj_desc - buffer_field object
97
* buffer_desc - Host Buffer
98
* offset_desc - Offset into buffer
99
* length_desc - Length of field (CREATE_FIELD_OP only)
100
* result_desc - Where to store the result
101
*
102
* RETURN: Status
103
*
104
* DESCRIPTION: Perform actual initialization of a buffer field
105
*
106
******************************************************************************/
107
108
static acpi_status
109
acpi_ds_init_buffer_field(u16 aml_opcode,
110
union acpi_operand_object *obj_desc,
111
union acpi_operand_object *buffer_desc,
112
union acpi_operand_object *offset_desc,
113
union acpi_operand_object *length_desc,
114
union acpi_operand_object *result_desc)
115
{
116
u32 offset;
117
u32 bit_offset;
118
u32 bit_count;
119
u8 field_flags;
120
acpi_status status;
121
122
ACPI_FUNCTION_TRACE_PTR(ds_init_buffer_field, obj_desc);
123
124
/* Host object must be a Buffer */
125
126
if (buffer_desc->common.type != ACPI_TYPE_BUFFER) {
127
ACPI_ERROR((AE_INFO,
128
"Target of Create Field is not a Buffer object - %s",
129
acpi_ut_get_object_type_name(buffer_desc)));
130
131
status = AE_AML_OPERAND_TYPE;
132
goto cleanup;
133
}
134
135
/*
136
* The last parameter to all of these opcodes (result_desc) started
137
* out as a name_string, and should therefore now be a NS node
138
* after resolution in acpi_ex_resolve_operands().
139
*/
140
if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) {
141
ACPI_ERROR((AE_INFO,
142
"(%s) destination not a NS Node [%s]",
143
acpi_ps_get_opcode_name(aml_opcode),
144
acpi_ut_get_descriptor_name(result_desc)));
145
146
status = AE_AML_OPERAND_TYPE;
147
goto cleanup;
148
}
149
150
offset = (u32) offset_desc->integer.value;
151
152
/*
153
* Setup the Bit offsets and counts, according to the opcode
154
*/
155
switch (aml_opcode) {
156
case AML_CREATE_FIELD_OP:
157
158
/* Offset is in bits, count is in bits */
159
160
field_flags = AML_FIELD_ACCESS_BYTE;
161
bit_offset = offset;
162
bit_count = (u32) length_desc->integer.value;
163
164
/* Must have a valid (>0) bit count */
165
166
if (bit_count == 0) {
167
ACPI_ERROR((AE_INFO,
168
"Attempt to CreateField of length zero"));
169
status = AE_AML_OPERAND_VALUE;
170
goto cleanup;
171
}
172
break;
173
174
case AML_CREATE_BIT_FIELD_OP:
175
176
/* Offset is in bits, Field is one bit */
177
178
bit_offset = offset;
179
bit_count = 1;
180
field_flags = AML_FIELD_ACCESS_BYTE;
181
break;
182
183
case AML_CREATE_BYTE_FIELD_OP:
184
185
/* Offset is in bytes, field is one byte */
186
187
bit_offset = 8 * offset;
188
bit_count = 8;
189
field_flags = AML_FIELD_ACCESS_BYTE;
190
break;
191
192
case AML_CREATE_WORD_FIELD_OP:
193
194
/* Offset is in bytes, field is one word */
195
196
bit_offset = 8 * offset;
197
bit_count = 16;
198
field_flags = AML_FIELD_ACCESS_WORD;
199
break;
200
201
case AML_CREATE_DWORD_FIELD_OP:
202
203
/* Offset is in bytes, field is one dword */
204
205
bit_offset = 8 * offset;
206
bit_count = 32;
207
field_flags = AML_FIELD_ACCESS_DWORD;
208
break;
209
210
case AML_CREATE_QWORD_FIELD_OP:
211
212
/* Offset is in bytes, field is one qword */
213
214
bit_offset = 8 * offset;
215
bit_count = 64;
216
field_flags = AML_FIELD_ACCESS_QWORD;
217
break;
218
219
default:
220
221
ACPI_ERROR((AE_INFO,
222
"Unknown field creation opcode 0x%02X",
223
aml_opcode));
224
status = AE_AML_BAD_OPCODE;
225
goto cleanup;
226
}
227
228
/* Entire field must fit within the current length of the buffer */
229
230
if ((bit_offset + bit_count) > (8 * (u32) buffer_desc->buffer.length)) {
231
ACPI_ERROR((AE_INFO,
232
"Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
233
acpi_ut_get_node_name(result_desc),
234
bit_offset + bit_count,
235
acpi_ut_get_node_name(buffer_desc->buffer.node),
236
8 * (u32) buffer_desc->buffer.length));
237
status = AE_AML_BUFFER_LIMIT;
238
goto cleanup;
239
}
240
241
/*
242
* Initialize areas of the field object that are common to all fields
243
* For field_flags, use LOCK_RULE = 0 (NO_LOCK),
244
* UPDATE_RULE = 0 (UPDATE_PRESERVE)
245
*/
246
status = acpi_ex_prep_common_field_object(obj_desc, field_flags, 0,
247
bit_offset, bit_count);
248
if (ACPI_FAILURE(status)) {
249
goto cleanup;
250
}
251
252
obj_desc->buffer_field.buffer_obj = buffer_desc;
253
254
/* Reference count for buffer_desc inherits obj_desc count */
255
256
buffer_desc->common.reference_count = (u16)
257
(buffer_desc->common.reference_count +
258
obj_desc->common.reference_count);
259
260
cleanup:
261
262
/* Always delete the operands */
263
264
acpi_ut_remove_reference(offset_desc);
265
acpi_ut_remove_reference(buffer_desc);
266
267
if (aml_opcode == AML_CREATE_FIELD_OP) {
268
acpi_ut_remove_reference(length_desc);
269
}
270
271
/* On failure, delete the result descriptor */
272
273
if (ACPI_FAILURE(status)) {
274
acpi_ut_remove_reference(result_desc); /* Result descriptor */
275
} else {
276
/* Now the address and length are valid for this buffer_field */
277
278
obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID;
279
}
280
281
return_ACPI_STATUS(status);
282
}
283
284
/*******************************************************************************
285
*
286
* FUNCTION: acpi_ds_eval_buffer_field_operands
287
*
288
* PARAMETERS: walk_state - Current walk
289
* Op - A valid buffer_field Op object
290
*
291
* RETURN: Status
292
*
293
* DESCRIPTION: Get buffer_field Buffer and Index
294
* Called from acpi_ds_exec_end_op during buffer_field parse tree walk
295
*
296
******************************************************************************/
297
298
acpi_status
299
acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state,
300
union acpi_parse_object *op)
301
{
302
acpi_status status;
303
union acpi_operand_object *obj_desc;
304
struct acpi_namespace_node *node;
305
union acpi_parse_object *next_op;
306
307
ACPI_FUNCTION_TRACE_PTR(ds_eval_buffer_field_operands, op);
308
309
/*
310
* This is where we evaluate the address and length fields of the
311
* create_xxx_field declaration
312
*/
313
node = op->common.node;
314
315
/* next_op points to the op that holds the Buffer */
316
317
next_op = op->common.value.arg;
318
319
/* Evaluate/create the address and length operands */
320
321
status = acpi_ds_create_operands(walk_state, next_op);
322
if (ACPI_FAILURE(status)) {
323
return_ACPI_STATUS(status);
324
}
325
326
obj_desc = acpi_ns_get_attached_object(node);
327
if (!obj_desc) {
328
return_ACPI_STATUS(AE_NOT_EXIST);
329
}
330
331
/* Resolve the operands */
332
333
status = acpi_ex_resolve_operands(op->common.aml_opcode,
334
ACPI_WALK_OPERANDS, walk_state);
335
if (ACPI_FAILURE(status)) {
336
ACPI_ERROR((AE_INFO, "(%s) bad operand(s), status 0x%X",
337
acpi_ps_get_opcode_name(op->common.aml_opcode),
338
status));
339
340
return_ACPI_STATUS(status);
341
}
342
343
/* Initialize the Buffer Field */
344
345
if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
346
347
/* NOTE: Slightly different operands for this opcode */
348
349
status =
350
acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc,
351
walk_state->operands[0],
352
walk_state->operands[1],
353
walk_state->operands[2],
354
walk_state->operands[3]);
355
} else {
356
/* All other, create_xxx_field opcodes */
357
358
status =
359
acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc,
360
walk_state->operands[0],
361
walk_state->operands[1], NULL,
362
walk_state->operands[2]);
363
}
364
365
return_ACPI_STATUS(status);
366
}
367
368
/*******************************************************************************
369
*
370
* FUNCTION: acpi_ds_eval_region_operands
371
*
372
* PARAMETERS: walk_state - Current walk
373
* Op - A valid region Op object
374
*
375
* RETURN: Status
376
*
377
* DESCRIPTION: Get region address and length
378
* Called from acpi_ds_exec_end_op during op_region parse tree walk
379
*
380
******************************************************************************/
381
382
acpi_status
383
acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
384
union acpi_parse_object *op)
385
{
386
acpi_status status;
387
union acpi_operand_object *obj_desc;
388
union acpi_operand_object *operand_desc;
389
struct acpi_namespace_node *node;
390
union acpi_parse_object *next_op;
391
392
ACPI_FUNCTION_TRACE_PTR(ds_eval_region_operands, op);
393
394
/*
395
* This is where we evaluate the address and length fields of the
396
* op_region declaration
397
*/
398
node = op->common.node;
399
400
/* next_op points to the op that holds the space_iD */
401
402
next_op = op->common.value.arg;
403
404
/* next_op points to address op */
405
406
next_op = next_op->common.next;
407
408
/* Evaluate/create the address and length operands */
409
410
status = acpi_ds_create_operands(walk_state, next_op);
411
if (ACPI_FAILURE(status)) {
412
return_ACPI_STATUS(status);
413
}
414
415
/* Resolve the length and address operands to numbers */
416
417
status = acpi_ex_resolve_operands(op->common.aml_opcode,
418
ACPI_WALK_OPERANDS, walk_state);
419
if (ACPI_FAILURE(status)) {
420
return_ACPI_STATUS(status);
421
}
422
423
obj_desc = acpi_ns_get_attached_object(node);
424
if (!obj_desc) {
425
return_ACPI_STATUS(AE_NOT_EXIST);
426
}
427
428
/*
429
* Get the length operand and save it
430
* (at Top of stack)
431
*/
432
operand_desc = walk_state->operands[walk_state->num_operands - 1];
433
434
obj_desc->region.length = (u32) operand_desc->integer.value;
435
acpi_ut_remove_reference(operand_desc);
436
437
/*
438
* Get the address and save it
439
* (at top of stack - 1)
440
*/
441
operand_desc = walk_state->operands[walk_state->num_operands - 2];
442
443
obj_desc->region.address = (acpi_physical_address)
444
operand_desc->integer.value;
445
acpi_ut_remove_reference(operand_desc);
446
447
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
448
obj_desc,
449
ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address),
450
obj_desc->region.length));
451
452
/* Now the address and length are valid for this opregion */
453
454
obj_desc->region.flags |= AOPOBJ_DATA_VALID;
455
456
return_ACPI_STATUS(status);
457
}
458
459
/*******************************************************************************
460
*
461
* FUNCTION: acpi_ds_eval_table_region_operands
462
*
463
* PARAMETERS: walk_state - Current walk
464
* Op - A valid region Op object
465
*
466
* RETURN: Status
467
*
468
* DESCRIPTION: Get region address and length.
469
* Called from acpi_ds_exec_end_op during data_table_region parse
470
* tree walk.
471
*
472
******************************************************************************/
473
474
acpi_status
475
acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
476
union acpi_parse_object *op)
477
{
478
acpi_status status;
479
union acpi_operand_object *obj_desc;
480
union acpi_operand_object **operand;
481
struct acpi_namespace_node *node;
482
union acpi_parse_object *next_op;
483
u32 table_index;
484
struct acpi_table_header *table;
485
486
ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op);
487
488
/*
489
* This is where we evaluate the signature_string and oem_iDString
490
* and oem_table_iDString of the data_table_region declaration
491
*/
492
node = op->common.node;
493
494
/* next_op points to signature_string op */
495
496
next_op = op->common.value.arg;
497
498
/*
499
* Evaluate/create the signature_string and oem_iDString
500
* and oem_table_iDString operands
501
*/
502
status = acpi_ds_create_operands(walk_state, next_op);
503
if (ACPI_FAILURE(status)) {
504
return_ACPI_STATUS(status);
505
}
506
507
/*
508
* Resolve the signature_string and oem_iDString
509
* and oem_table_iDString operands
510
*/
511
status = acpi_ex_resolve_operands(op->common.aml_opcode,
512
ACPI_WALK_OPERANDS, walk_state);
513
if (ACPI_FAILURE(status)) {
514
return_ACPI_STATUS(status);
515
}
516
517
operand = &walk_state->operands[0];
518
519
/* Find the ACPI table */
520
521
status = acpi_tb_find_table(operand[0]->string.pointer,
522
operand[1]->string.pointer,
523
operand[2]->string.pointer, &table_index);
524
if (ACPI_FAILURE(status)) {
525
return_ACPI_STATUS(status);
526
}
527
528
acpi_ut_remove_reference(operand[0]);
529
acpi_ut_remove_reference(operand[1]);
530
acpi_ut_remove_reference(operand[2]);
531
532
status = acpi_get_table_by_index(table_index, &table);
533
if (ACPI_FAILURE(status)) {
534
return_ACPI_STATUS(status);
535
}
536
537
obj_desc = acpi_ns_get_attached_object(node);
538
if (!obj_desc) {
539
return_ACPI_STATUS(AE_NOT_EXIST);
540
}
541
542
obj_desc->region.address =
543
(acpi_physical_address) ACPI_TO_INTEGER(table);
544
obj_desc->region.length = table->length;
545
546
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
547
obj_desc,
548
ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address),
549
obj_desc->region.length));
550
551
/* Now the address and length are valid for this opregion */
552
553
obj_desc->region.flags |= AOPOBJ_DATA_VALID;
554
555
return_ACPI_STATUS(status);
556
}
557
558
/*******************************************************************************
559
*
560
* FUNCTION: acpi_ds_eval_data_object_operands
561
*
562
* PARAMETERS: walk_state - Current walk
563
* Op - A valid data_object Op object
564
* obj_desc - data_object
565
*
566
* RETURN: Status
567
*
568
* DESCRIPTION: Get the operands and complete the following data object types:
569
* Buffer, Package.
570
*
571
******************************************************************************/
572
573
acpi_status
574
acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
575
union acpi_parse_object *op,
576
union acpi_operand_object *obj_desc)
577
{
578
acpi_status status;
579
union acpi_operand_object *arg_desc;
580
u32 length;
581
582
ACPI_FUNCTION_TRACE(ds_eval_data_object_operands);
583
584
/* The first operand (for all of these data objects) is the length */
585
586
/*
587
* Set proper index into operand stack for acpi_ds_obj_stack_push
588
* invoked inside acpi_ds_create_operand.
589
*/
590
walk_state->operand_index = walk_state->num_operands;
591
592
status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1);
593
if (ACPI_FAILURE(status)) {
594
return_ACPI_STATUS(status);
595
}
596
597
status = acpi_ex_resolve_operands(walk_state->opcode,
598
&(walk_state->
599
operands[walk_state->num_operands -
600
1]), walk_state);
601
if (ACPI_FAILURE(status)) {
602
return_ACPI_STATUS(status);
603
}
604
605
/* Extract length operand */
606
607
arg_desc = walk_state->operands[walk_state->num_operands - 1];
608
length = (u32) arg_desc->integer.value;
609
610
/* Cleanup for length operand */
611
612
status = acpi_ds_obj_stack_pop(1, walk_state);
613
if (ACPI_FAILURE(status)) {
614
return_ACPI_STATUS(status);
615
}
616
617
acpi_ut_remove_reference(arg_desc);
618
619
/*
620
* Create the actual data object
621
*/
622
switch (op->common.aml_opcode) {
623
case AML_BUFFER_OP:
624
625
status =
626
acpi_ds_build_internal_buffer_obj(walk_state, op, length,
627
&obj_desc);
628
break;
629
630
case AML_PACKAGE_OP:
631
case AML_VAR_PACKAGE_OP:
632
633
status =
634
acpi_ds_build_internal_package_obj(walk_state, op, length,
635
&obj_desc);
636
break;
637
638
default:
639
return_ACPI_STATUS(AE_AML_BAD_OPCODE);
640
}
641
642
if (ACPI_SUCCESS(status)) {
643
/*
644
* Return the object in the walk_state, unless the parent is a package -
645
* in this case, the return object will be stored in the parse tree
646
* for the package.
647
*/
648
if ((!op->common.parent) ||
649
((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) &&
650
(op->common.parent->common.aml_opcode !=
651
AML_VAR_PACKAGE_OP)
652
&& (op->common.parent->common.aml_opcode != AML_NAME_OP))) {
653
walk_state->result_obj = obj_desc;
654
}
655
}
656
657
return_ACPI_STATUS(status);
658
}
659
660
/*******************************************************************************
661
*
662
* FUNCTION: acpi_ds_eval_bank_field_operands
663
*
664
* PARAMETERS: walk_state - Current walk
665
* Op - A valid bank_field Op object
666
*
667
* RETURN: Status
668
*
669
* DESCRIPTION: Get bank_field bank_value
670
* Called from acpi_ds_exec_end_op during bank_field parse tree walk
671
*
672
******************************************************************************/
673
674
acpi_status
675
acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state,
676
union acpi_parse_object *op)
677
{
678
acpi_status status;
679
union acpi_operand_object *obj_desc;
680
union acpi_operand_object *operand_desc;
681
struct acpi_namespace_node *node;
682
union acpi_parse_object *next_op;
683
union acpi_parse_object *arg;
684
685
ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op);
686
687
/*
688
* This is where we evaluate the bank_value field of the
689
* bank_field declaration
690
*/
691
692
/* next_op points to the op that holds the Region */
693
694
next_op = op->common.value.arg;
695
696
/* next_op points to the op that holds the Bank Register */
697
698
next_op = next_op->common.next;
699
700
/* next_op points to the op that holds the Bank Value */
701
702
next_op = next_op->common.next;
703
704
/*
705
* Set proper index into operand stack for acpi_ds_obj_stack_push
706
* invoked inside acpi_ds_create_operand.
707
*
708
* We use walk_state->Operands[0] to store the evaluated bank_value
709
*/
710
walk_state->operand_index = 0;
711
712
status = acpi_ds_create_operand(walk_state, next_op, 0);
713
if (ACPI_FAILURE(status)) {
714
return_ACPI_STATUS(status);
715
}
716
717
status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state);
718
if (ACPI_FAILURE(status)) {
719
return_ACPI_STATUS(status);
720
}
721
722
ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS,
723
acpi_ps_get_opcode_name(op->common.aml_opcode), 1);
724
/*
725
* Get the bank_value operand and save it
726
* (at Top of stack)
727
*/
728
operand_desc = walk_state->operands[0];
729
730
/* Arg points to the start Bank Field */
731
732
arg = acpi_ps_get_arg(op, 4);
733
while (arg) {
734
735
/* Ignore OFFSET and ACCESSAS terms here */
736
737
if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
738
node = arg->common.node;
739
740
obj_desc = acpi_ns_get_attached_object(node);
741
if (!obj_desc) {
742
return_ACPI_STATUS(AE_NOT_EXIST);
743
}
744
745
obj_desc->bank_field.value =
746
(u32) operand_desc->integer.value;
747
}
748
749
/* Move to next field in the list */
750
751
arg = arg->common.next;
752
}
753
754
acpi_ut_remove_reference(operand_desc);
755
return_ACPI_STATUS(status);
756
}
757
758