[ACPICA] Update to version 20171215. CORE-15222
[reactos.git] / drivers / bus / acpi / acpica / dispatcher / dsfield.c
1 /******************************************************************************
2 *
3 * Module Name: dsfield - Dispatcher field routines
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2017, 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.h"
45 #include "accommon.h"
46 #include "amlcode.h"
47 #include "acdispat.h"
48 #include "acinterp.h"
49 #include "acnamesp.h"
50 #include "acparser.h"
51
52
53 #define _COMPONENT ACPI_DISPATCHER
54 ACPI_MODULE_NAME ("dsfield")
55
56 /* Local prototypes */
57
58 #ifdef ACPI_ASL_COMPILER
59 #include "acdisasm.h"
60
61 static ACPI_STATUS
62 AcpiDsCreateExternalRegion (
63 ACPI_STATUS LookupStatus,
64 ACPI_PARSE_OBJECT *Op,
65 char *Path,
66 ACPI_WALK_STATE *WalkState,
67 ACPI_NAMESPACE_NODE **Node);
68 #endif
69
70 static ACPI_STATUS
71 AcpiDsGetFieldNames (
72 ACPI_CREATE_FIELD_INFO *Info,
73 ACPI_WALK_STATE *WalkState,
74 ACPI_PARSE_OBJECT *Arg);
75
76
77 #ifdef ACPI_ASL_COMPILER
78 /*******************************************************************************
79 *
80 * FUNCTION: AcpiDsCreateExternalRegion (iASL Disassembler only)
81 *
82 * PARAMETERS: LookupStatus - Status from NsLookup operation
83 * Op - Op containing the Field definition and args
84 * Path - Pathname of the region
85 * ` WalkState - Current method state
86 * Node - Where the new region node is returned
87 *
88 * RETURN: Status
89 *
90 * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
91 * region node/object.
92 *
93 ******************************************************************************/
94
95 static ACPI_STATUS
96 AcpiDsCreateExternalRegion (
97 ACPI_STATUS LookupStatus,
98 ACPI_PARSE_OBJECT *Op,
99 char *Path,
100 ACPI_WALK_STATE *WalkState,
101 ACPI_NAMESPACE_NODE **Node)
102 {
103 ACPI_STATUS Status;
104 ACPI_OPERAND_OBJECT *ObjDesc;
105
106
107 if (LookupStatus != AE_NOT_FOUND)
108 {
109 return (LookupStatus);
110 }
111
112 /*
113 * Table disassembly:
114 * OperationRegion not found. Generate an External for it, and
115 * insert the name into the namespace.
116 */
117 AcpiDmAddOpToExternalList (Op, Path, ACPI_TYPE_REGION, 0, 0);
118
119 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_REGION,
120 ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, WalkState, Node);
121 if (ACPI_FAILURE (Status))
122 {
123 return (Status);
124 }
125
126 /* Must create and install a region object for the new node */
127
128 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
129 if (!ObjDesc)
130 {
131 return (AE_NO_MEMORY);
132 }
133
134 ObjDesc->Region.Node = *Node;
135 Status = AcpiNsAttachObject (*Node, ObjDesc, ACPI_TYPE_REGION);
136 return (Status);
137 }
138 #endif
139
140
141 /*******************************************************************************
142 *
143 * FUNCTION: AcpiDsCreateBufferField
144 *
145 * PARAMETERS: Op - Current parse op (CreateXXField)
146 * WalkState - Current state
147 *
148 * RETURN: Status
149 *
150 * DESCRIPTION: Execute the CreateField operators:
151 * CreateBitFieldOp,
152 * CreateByteFieldOp,
153 * CreateWordFieldOp,
154 * CreateDwordFieldOp,
155 * CreateQwordFieldOp,
156 * CreateFieldOp (all of which define a field in a buffer)
157 *
158 ******************************************************************************/
159
160 ACPI_STATUS
161 AcpiDsCreateBufferField (
162 ACPI_PARSE_OBJECT *Op,
163 ACPI_WALK_STATE *WalkState)
164 {
165 ACPI_PARSE_OBJECT *Arg;
166 ACPI_NAMESPACE_NODE *Node;
167 ACPI_STATUS Status;
168 ACPI_OPERAND_OBJECT *ObjDesc;
169 ACPI_OPERAND_OBJECT *SecondDesc = NULL;
170 UINT32 Flags;
171
172
173 ACPI_FUNCTION_TRACE (DsCreateBufferField);
174
175
176 /*
177 * Get the NameString argument (name of the new BufferField)
178 */
179 if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
180 {
181 /* For CreateField, name is the 4th argument */
182
183 Arg = AcpiPsGetArg (Op, 3);
184 }
185 else
186 {
187 /* For all other CreateXXXField operators, name is the 3rd argument */
188
189 Arg = AcpiPsGetArg (Op, 2);
190 }
191
192 if (!Arg)
193 {
194 return_ACPI_STATUS (AE_AML_NO_OPERAND);
195 }
196
197 if (WalkState->DeferredNode)
198 {
199 Node = WalkState->DeferredNode;
200 Status = AE_OK;
201 }
202 else
203 {
204 /* Execute flag should always be set when this function is entered */
205
206 if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
207 {
208 ACPI_ERROR ((AE_INFO,
209 "Parse execute mode is not set"));
210 return_ACPI_STATUS (AE_AML_INTERNAL);
211 }
212
213 /* Creating new namespace node, should not already exist */
214
215 Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
216 ACPI_NS_ERROR_IF_FOUND;
217
218 /*
219 * Mark node temporary if we are executing a normal control
220 * method. (Don't mark if this is a module-level code method)
221 */
222 if (WalkState->MethodNode &&
223 !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
224 {
225 Flags |= ACPI_NS_TEMPORARY;
226 }
227
228 /* Enter the NameString into the namespace */
229
230 Status = AcpiNsLookup (WalkState->ScopeInfo,
231 Arg->Common.Value.String, ACPI_TYPE_ANY,
232 ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
233 if (ACPI_FAILURE (Status))
234 {
235 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
236 Arg->Common.Value.String, Status);
237 return_ACPI_STATUS (Status);
238 }
239 }
240
241 /*
242 * We could put the returned object (Node) on the object stack for later,
243 * but for now, we will put it in the "op" object that the parser uses,
244 * so we can get it again at the end of this scope.
245 */
246 Op->Common.Node = Node;
247
248 /*
249 * If there is no object attached to the node, this node was just created
250 * and we need to create the field object. Otherwise, this was a lookup
251 * of an existing node and we don't want to create the field object again.
252 */
253 ObjDesc = AcpiNsGetAttachedObject (Node);
254 if (ObjDesc)
255 {
256 return_ACPI_STATUS (AE_OK);
257 }
258
259 /*
260 * The Field definition is not fully parsed at this time.
261 * (We must save the address of the AML for the buffer and index operands)
262 */
263
264 /* Create the buffer field object */
265
266 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD);
267 if (!ObjDesc)
268 {
269 Status = AE_NO_MEMORY;
270 goto Cleanup;
271 }
272
273 /*
274 * Remember location in AML stream of the field unit opcode and operands
275 * -- since the buffer and index operands must be evaluated.
276 */
277 SecondDesc = ObjDesc->Common.NextObject;
278 SecondDesc->Extra.AmlStart = Op->Named.Data;
279 SecondDesc->Extra.AmlLength = Op->Named.Length;
280 ObjDesc->BufferField.Node = Node;
281
282 /* Attach constructed field descriptors to parent node */
283
284 Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD);
285 if (ACPI_FAILURE (Status))
286 {
287 goto Cleanup;
288 }
289
290
291 Cleanup:
292
293 /* Remove local reference to the object */
294
295 AcpiUtRemoveReference (ObjDesc);
296 return_ACPI_STATUS (Status);
297 }
298
299
300 /*******************************************************************************
301 *
302 * FUNCTION: AcpiDsGetFieldNames
303 *
304 * PARAMETERS: Info - CreateField info structure
305 * ` WalkState - Current method state
306 * Arg - First parser arg for the field name list
307 *
308 * RETURN: Status
309 *
310 * DESCRIPTION: Process all named fields in a field declaration. Names are
311 * entered into the namespace.
312 *
313 ******************************************************************************/
314
315 static ACPI_STATUS
316 AcpiDsGetFieldNames (
317 ACPI_CREATE_FIELD_INFO *Info,
318 ACPI_WALK_STATE *WalkState,
319 ACPI_PARSE_OBJECT *Arg)
320 {
321 ACPI_STATUS Status;
322 UINT64 Position;
323 ACPI_PARSE_OBJECT *Child;
324
325
326 ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info);
327
328
329 /* First field starts at bit zero */
330
331 Info->FieldBitPosition = 0;
332
333 /* Process all elements in the field list (of parse nodes) */
334
335 while (Arg)
336 {
337 /*
338 * Four types of field elements are handled:
339 * 1) Name - Enters a new named field into the namespace
340 * 2) Offset - specifies a bit offset
341 * 3) AccessAs - changes the access mode/attributes
342 * 4) Connection - Associate a resource template with the field
343 */
344 switch (Arg->Common.AmlOpcode)
345 {
346 case AML_INT_RESERVEDFIELD_OP:
347
348 Position = (UINT64) Info->FieldBitPosition +
349 (UINT64) Arg->Common.Value.Size;
350
351 if (Position > ACPI_UINT32_MAX)
352 {
353 ACPI_ERROR ((AE_INFO,
354 "Bit offset within field too large (> 0xFFFFFFFF)"));
355 return_ACPI_STATUS (AE_SUPPORT);
356 }
357
358 Info->FieldBitPosition = (UINT32) Position;
359 break;
360
361 case AML_INT_ACCESSFIELD_OP:
362 case AML_INT_EXTACCESSFIELD_OP:
363 /*
364 * Get new AccessType, AccessAttribute, and AccessLength fields
365 * -- to be used for all field units that follow, until the
366 * end-of-field or another AccessAs keyword is encountered.
367 * NOTE. These three bytes are encoded in the integer value
368 * of the parseop for convenience.
369 *
370 * In FieldFlags, preserve the flag bits other than the
371 * ACCESS_TYPE bits.
372 */
373
374 /* AccessType (ByteAcc, WordAcc, etc.) */
375
376 Info->FieldFlags = (UINT8)
377 ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
378 ((UINT8) ((UINT32) (Arg->Common.Value.Integer & 0x07))));
379
380 /* AccessAttribute (AttribQuick, AttribByte, etc.) */
381
382 Info->Attribute = (UINT8)
383 ((Arg->Common.Value.Integer >> 8) & 0xFF);
384
385 /* AccessLength (for serial/buffer protocols) */
386
387 Info->AccessLength = (UINT8)
388 ((Arg->Common.Value.Integer >> 16) & 0xFF);
389 break;
390
391 case AML_INT_CONNECTION_OP:
392 /*
393 * Clear any previous connection. New connection is used for all
394 * fields that follow, similar to AccessAs
395 */
396 Info->ResourceBuffer = NULL;
397 Info->ConnectionNode = NULL;
398 Info->PinNumberIndex = 0;
399
400 /*
401 * A Connection() is either an actual resource descriptor (buffer)
402 * or a named reference to a resource template
403 */
404 Child = Arg->Common.Value.Arg;
405 if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
406 {
407 Info->ResourceBuffer = Child->Named.Data;
408 Info->ResourceLength = (UINT16) Child->Named.Value.Integer;
409 }
410 else
411 {
412 /* Lookup the Connection() namepath, it should already exist */
413
414 Status = AcpiNsLookup (WalkState->ScopeInfo,
415 Child->Common.Value.Name, ACPI_TYPE_ANY,
416 ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
417 WalkState, &Info->ConnectionNode);
418 if (ACPI_FAILURE (Status))
419 {
420 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
421 Child->Common.Value.Name, Status);
422 return_ACPI_STATUS (Status);
423 }
424 }
425 break;
426
427 case AML_INT_NAMEDFIELD_OP:
428
429 /* Lookup the name, it should already exist */
430
431 Status = AcpiNsLookup (WalkState->ScopeInfo,
432 (char *) &Arg->Named.Name, Info->FieldType,
433 ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
434 WalkState, &Info->FieldNode);
435 if (ACPI_FAILURE (Status))
436 {
437 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
438 (char *) &Arg->Named.Name, Status);
439 return_ACPI_STATUS (Status);
440 }
441 else
442 {
443 Arg->Common.Node = Info->FieldNode;
444 Info->FieldBitLength = Arg->Common.Value.Size;
445
446 /*
447 * If there is no object attached to the node, this node was
448 * just created and we need to create the field object.
449 * Otherwise, this was a lookup of an existing node and we
450 * don't want to create the field object again.
451 */
452 if (!AcpiNsGetAttachedObject (Info->FieldNode))
453 {
454 Status = AcpiExPrepFieldValue (Info);
455 if (ACPI_FAILURE (Status))
456 {
457 return_ACPI_STATUS (Status);
458 }
459 }
460 }
461
462 /* Keep track of bit position for the next field */
463
464 Position = (UINT64) Info->FieldBitPosition +
465 (UINT64) Arg->Common.Value.Size;
466
467 if (Position > ACPI_UINT32_MAX)
468 {
469 ACPI_ERROR ((AE_INFO,
470 "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
471 ACPI_CAST_PTR (char, &Info->FieldNode->Name)));
472 return_ACPI_STATUS (AE_SUPPORT);
473 }
474
475 Info->FieldBitPosition += Info->FieldBitLength;
476 Info->PinNumberIndex++; /* Index relative to previous Connection() */
477 break;
478
479 default:
480
481 ACPI_ERROR ((AE_INFO,
482 "Invalid opcode in field list: 0x%X",
483 Arg->Common.AmlOpcode));
484 return_ACPI_STATUS (AE_AML_BAD_OPCODE);
485 }
486
487 Arg = Arg->Common.Next;
488 }
489
490 return_ACPI_STATUS (AE_OK);
491 }
492
493
494 /*******************************************************************************
495 *
496 * FUNCTION: AcpiDsCreateField
497 *
498 * PARAMETERS: Op - Op containing the Field definition and args
499 * RegionNode - Object for the containing Operation Region
500 * ` WalkState - Current method state
501 *
502 * RETURN: Status
503 *
504 * DESCRIPTION: Create a new field in the specified operation region
505 *
506 ******************************************************************************/
507
508 ACPI_STATUS
509 AcpiDsCreateField (
510 ACPI_PARSE_OBJECT *Op,
511 ACPI_NAMESPACE_NODE *RegionNode,
512 ACPI_WALK_STATE *WalkState)
513 {
514 ACPI_STATUS Status;
515 ACPI_PARSE_OBJECT *Arg;
516 ACPI_CREATE_FIELD_INFO Info;
517
518
519 ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op);
520
521
522 /* First arg is the name of the parent OpRegion (must already exist) */
523
524 Arg = Op->Common.Value.Arg;
525
526 if (!RegionNode)
527 {
528 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
529 ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
530 ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
531 #ifdef ACPI_ASL_COMPILER
532 Status = AcpiDsCreateExternalRegion (Status, Arg,
533 Arg->Common.Value.Name, WalkState, &RegionNode);
534 #endif
535 if (ACPI_FAILURE (Status))
536 {
537 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
538 Arg->Common.Value.Name, Status);
539 return_ACPI_STATUS (Status);
540 }
541 }
542
543 memset (&Info, 0, sizeof (ACPI_CREATE_FIELD_INFO));
544
545 /* Second arg is the field flags */
546
547 Arg = Arg->Common.Next;
548 Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
549 Info.Attribute = 0;
550
551 /* Each remaining arg is a Named Field */
552
553 Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD;
554 Info.RegionNode = RegionNode;
555
556 Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
557 return_ACPI_STATUS (Status);
558 }
559
560
561 /*******************************************************************************
562 *
563 * FUNCTION: AcpiDsInitFieldObjects
564 *
565 * PARAMETERS: Op - Op containing the Field definition and args
566 * ` WalkState - Current method state
567 *
568 * RETURN: Status
569 *
570 * DESCRIPTION: For each "Field Unit" name in the argument list that is
571 * part of the field declaration, enter the name into the
572 * namespace.
573 *
574 ******************************************************************************/
575
576 ACPI_STATUS
577 AcpiDsInitFieldObjects (
578 ACPI_PARSE_OBJECT *Op,
579 ACPI_WALK_STATE *WalkState)
580 {
581 ACPI_STATUS Status;
582 ACPI_PARSE_OBJECT *Arg = NULL;
583 ACPI_NAMESPACE_NODE *Node;
584 UINT8 Type = 0;
585 UINT32 Flags;
586
587
588 ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op);
589
590
591 /* Execute flag should always be set when this function is entered */
592
593 if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
594 {
595 if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP)
596 {
597 /* BankField Op is deferred, just return OK */
598
599 return_ACPI_STATUS (AE_OK);
600 }
601
602 ACPI_ERROR ((AE_INFO,
603 "Parse deferred mode is not set"));
604 return_ACPI_STATUS (AE_AML_INTERNAL);
605 }
606
607 /*
608 * Get the FieldList argument for this opcode. This is the start of the
609 * list of field elements.
610 */
611 switch (WalkState->Opcode)
612 {
613 case AML_FIELD_OP:
614
615 Arg = AcpiPsGetArg (Op, 2);
616 Type = ACPI_TYPE_LOCAL_REGION_FIELD;
617 break;
618
619 case AML_BANK_FIELD_OP:
620
621 Arg = AcpiPsGetArg (Op, 4);
622 Type = ACPI_TYPE_LOCAL_BANK_FIELD;
623 break;
624
625 case AML_INDEX_FIELD_OP:
626
627 Arg = AcpiPsGetArg (Op, 3);
628 Type = ACPI_TYPE_LOCAL_INDEX_FIELD;
629 break;
630
631 default:
632
633 return_ACPI_STATUS (AE_BAD_PARAMETER);
634 }
635
636 /* Creating new namespace node(s), should not already exist */
637
638 Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
639 ACPI_NS_ERROR_IF_FOUND;
640
641 /*
642 * Mark node(s) temporary if we are executing a normal control
643 * method. (Don't mark if this is a module-level code method)
644 */
645 if (WalkState->MethodNode &&
646 !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
647 {
648 Flags |= ACPI_NS_TEMPORARY;
649 }
650
651 /*
652 * Walk the list of entries in the FieldList
653 * Note: FieldList can be of zero length. In this case, Arg will be NULL.
654 */
655 while (Arg)
656 {
657 /*
658 * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
659 * in the field names in order to enter them into the namespace.
660 */
661 if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
662 {
663 Status = AcpiNsLookup (WalkState->ScopeInfo,
664 (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1,
665 Flags, WalkState, &Node);
666 if (ACPI_FAILURE (Status))
667 {
668 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
669 (char *) &Arg->Named.Name, Status);
670 if (Status != AE_ALREADY_EXISTS)
671 {
672 return_ACPI_STATUS (Status);
673 }
674
675 /* Name already exists, just ignore this error */
676
677 Status = AE_OK;
678 }
679
680 Arg->Common.Node = Node;
681 }
682
683 /* Get the next field element in the list */
684
685 Arg = Arg->Common.Next;
686 }
687
688 return_ACPI_STATUS (AE_OK);
689 }
690
691
692 /*******************************************************************************
693 *
694 * FUNCTION: AcpiDsCreateBankField
695 *
696 * PARAMETERS: Op - Op containing the Field definition and args
697 * RegionNode - Object for the containing Operation Region
698 * WalkState - Current method state
699 *
700 * RETURN: Status
701 *
702 * DESCRIPTION: Create a new bank field in the specified operation region
703 *
704 ******************************************************************************/
705
706 ACPI_STATUS
707 AcpiDsCreateBankField (
708 ACPI_PARSE_OBJECT *Op,
709 ACPI_NAMESPACE_NODE *RegionNode,
710 ACPI_WALK_STATE *WalkState)
711 {
712 ACPI_STATUS Status;
713 ACPI_PARSE_OBJECT *Arg;
714 ACPI_CREATE_FIELD_INFO Info;
715
716
717 ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op);
718
719
720 /* First arg is the name of the parent OpRegion (must already exist) */
721
722 Arg = Op->Common.Value.Arg;
723 if (!RegionNode)
724 {
725 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
726 ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
727 ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
728 #ifdef ACPI_ASL_COMPILER
729 Status = AcpiDsCreateExternalRegion (Status, Arg,
730 Arg->Common.Value.Name, WalkState, &RegionNode);
731 #endif
732 if (ACPI_FAILURE (Status))
733 {
734 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
735 Arg->Common.Value.Name, Status);
736 return_ACPI_STATUS (Status);
737 }
738 }
739
740 /* Second arg is the Bank Register (Field) (must already exist) */
741
742 Arg = Arg->Common.Next;
743 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
744 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
745 ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
746 if (ACPI_FAILURE (Status))
747 {
748 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
749 Arg->Common.Value.String, Status);
750 return_ACPI_STATUS (Status);
751 }
752
753 /*
754 * Third arg is the BankValue
755 * This arg is a TermArg, not a constant
756 * It will be evaluated later, by AcpiDsEvalBankFieldOperands
757 */
758 Arg = Arg->Common.Next;
759
760 /* Fourth arg is the field flags */
761
762 Arg = Arg->Common.Next;
763 Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
764
765 /* Each remaining arg is a Named Field */
766
767 Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD;
768 Info.RegionNode = RegionNode;
769
770 /*
771 * Use Info.DataRegisterNode to store BankField Op
772 * It's safe because DataRegisterNode will never be used when create
773 * bank field \we store AmlStart and AmlLength in the BankField Op for
774 * late evaluation. Used in AcpiExPrepFieldValue(Info)
775 *
776 * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like
777 * "void *ParentOp"?
778 */
779 Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op;
780
781 Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
782 return_ACPI_STATUS (Status);
783 }
784
785
786 /*******************************************************************************
787 *
788 * FUNCTION: AcpiDsCreateIndexField
789 *
790 * PARAMETERS: Op - Op containing the Field definition and args
791 * RegionNode - Object for the containing Operation Region
792 * ` WalkState - Current method state
793 *
794 * RETURN: Status
795 *
796 * DESCRIPTION: Create a new index field in the specified operation region
797 *
798 ******************************************************************************/
799
800 ACPI_STATUS
801 AcpiDsCreateIndexField (
802 ACPI_PARSE_OBJECT *Op,
803 ACPI_NAMESPACE_NODE *RegionNode,
804 ACPI_WALK_STATE *WalkState)
805 {
806 ACPI_STATUS Status;
807 ACPI_PARSE_OBJECT *Arg;
808 ACPI_CREATE_FIELD_INFO Info;
809
810
811 ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op);
812
813
814 /* First arg is the name of the Index register (must already exist) */
815
816 Arg = Op->Common.Value.Arg;
817 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
818 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
819 ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
820 if (ACPI_FAILURE (Status))
821 {
822 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
823 Arg->Common.Value.String, Status);
824 return_ACPI_STATUS (Status);
825 }
826
827 /* Second arg is the data register (must already exist) */
828
829 Arg = Arg->Common.Next;
830 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
831 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
832 ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode);
833 if (ACPI_FAILURE (Status))
834 {
835 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
836 Arg->Common.Value.String, Status);
837 return_ACPI_STATUS (Status);
838 }
839
840 /* Next arg is the field flags */
841
842 Arg = Arg->Common.Next;
843 Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
844
845 /* Each remaining arg is a Named Field */
846
847 Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD;
848 Info.RegionNode = RegionNode;
849
850 Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
851 return_ACPI_STATUS (Status);
852 }