dsfield.c revision 193341
1224135Sdim/****************************************************************************** 2224135Sdim * 3224135Sdim * Module Name: dsfield - Dispatcher field routines 4224135Sdim * 5224135Sdim *****************************************************************************/ 6224135Sdim 7224135Sdim/****************************************************************************** 8224135Sdim * 9224135Sdim * 1. Copyright Notice 10224135Sdim * 11224135Sdim * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 12224135Sdim * All rights reserved. 13224135Sdim * 14263508Sdim * 2. License 15224135Sdim * 16224135Sdim * 2.1. This is your license from Intel Corp. under its intellectual property 17224135Sdim * rights. You may have additional license terms from the party that provided 18224135Sdim * you this software, covering your right to use that party's intellectual 19224135Sdim * property rights. 20224135Sdim * 21249423Sdim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22249423Sdim * copy of the source code appearing in this file ("Covered Code") an 23249423Sdim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24224135Sdim * base code distributed originally by Intel ("Original Intel Code") to copy, 25224135Sdim * make derivatives, distribute, use and display any portion of the Covered 26224135Sdim * Code in any form, with the right to sublicense such rights; and 27224135Sdim * 28249423Sdim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29249423Sdim * license (with the right to sublicense), under only those claims of Intel 30249423Sdim * patents that are infringed by the Original Intel Code, to make, use, sell, 31249423Sdim * offer to sell, and import the Covered Code and derivative works thereof 32249423Sdim * solely to the minimum extent necessary to exercise the above copyright 33249423Sdim * license, and in no event shall the patent license extend to any additions 34224135Sdim * to or modifications of the Original Intel Code. No other license or right 35224135Sdim * is granted directly or by implication, estoppel or otherwise; 36249423Sdim * 37249423Sdim * The above copyright and patent license is granted only if the following 38249423Sdim * conditions are met: 39249423Sdim * 40249423Sdim * 3. Conditions 41224135Sdim * 42224135Sdim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43224135Sdim * Redistribution of source code of any substantial portion of the Covered 44224135Sdim * Code or modification with rights to further distribute source must include 45224135Sdim * the above Copyright Notice, the above License, this list of Conditions, 46224135Sdim * and the following Disclaimer and Export Compliance provision. In addition, 47224135Sdim * Licensee must cause all Covered Code to which Licensee contributes to 48224135Sdim * contain a file documenting the changes Licensee made to create that Covered 49224135Sdim * Code and the date of any change. Licensee must include in that file the 50234353Sdim * documentation of any changes made by any predecessor Licensee. Licensee 51224135Sdim * must include a prominent statement that the modification is derived, 52224135Sdim * directly or indirectly, from Original Intel Code. 53224135Sdim * 54224135Sdim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55224135Sdim * Redistribution of source code of any substantial portion of the Covered 56224135Sdim * Code or modification without rights to further distribute source must 57224135Sdim * include the following Disclaimer and Export Compliance provision in the 58224135Sdim * documentation and/or other materials provided with distribution. In 59224135Sdim * addition, Licensee may not authorize further sublicense of source of any 60224135Sdim * portion of the Covered Code, and must include terms to the effect that the 61224135Sdim * license from Licensee to its licensee is limited to the intellectual 62224135Sdim * property embodied in the software Licensee provides to its licensee, and 63224135Sdim * not to intellectual property embodied in modifications its licensee may 64251662Sdim * make. 65251662Sdim * 66251662Sdim * 3.3. Redistribution of Executable. Redistribution in executable form of any 67224135Sdim * substantial portion of the Covered Code or modification must reproduce the 68224135Sdim * above Copyright Notice, and the following Disclaimer and Export Compliance 69224135Sdim * provision in the documentation and/or other materials provided with the 70224135Sdim * distribution. 71234353Sdim * 72234353Sdim * 3.4. Intel retains all right, title, and interest in and to the Original 73234353Sdim * Intel Code. 74234353Sdim * 75234353Sdim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76224135Sdim * Intel shall be used in advertising or otherwise to promote the sale, use or 77224135Sdim * other dealings in products derived from or relating to the Covered Code 78224135Sdim * without prior written authorization from Intel. 79224135Sdim * 80224135Sdim * 4. Disclaimer and Export Compliance 81224135Sdim * 82224135Sdim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83224135Sdim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84224135Sdim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85224135Sdim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86224135Sdim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87224135Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88234353Sdim * PARTICULAR PURPOSE. 89224135Sdim * 90224135Sdim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91224135Sdim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92224135Sdim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93224135Sdim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94224135Sdim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95224135Sdim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96224135Sdim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97224135Sdim * LIMITED REMEDY. 98234982Sdim * 99234982Sdim * 4.3. Licensee shall not export, either directly or indirectly, any of this 100224135Sdim * software or system incorporating such software without first obtaining any 101224135Sdim * required license or other approval from the U. S. Department of Commerce or 102224135Sdim * any other agency or department of the United States Government. In the 103224135Sdim * event Licensee exports any such software from the United States or 104224135Sdim * re-exports any such software from a foreign destination, Licensee shall 105224135Sdim * ensure that the distribution and export/re-export of the software is in 106234353Sdim * compliance with all laws, regulations, orders, or other restrictions of the 107249423Sdim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108224135Sdim * any of its subsidiaries will export/re-export any technical data, process, 109224135Sdim * software, or service, directly or indirectly, to any country for which the 110224135Sdim * United States government or any agency thereof requires an export license, 111224135Sdim * other governmental approval, or letter of assurance, without first obtaining 112251662Sdim * such license, approval or letter. 113251662Sdim * 114234353Sdim *****************************************************************************/ 115224135Sdim 116224135Sdim#define __DSFIELD_C__ 117224135Sdim 118224135Sdim#include <contrib/dev/acpica/include/acpi.h> 119224135Sdim#include <contrib/dev/acpica/include/accommon.h> 120224135Sdim#include <contrib/dev/acpica/include/amlcode.h> 121224135Sdim#include <contrib/dev/acpica/include/acdispat.h> 122224135Sdim#include <contrib/dev/acpica/include/acinterp.h> 123224135Sdim#include <contrib/dev/acpica/include/acnamesp.h> 124224135Sdim#include <contrib/dev/acpica/include/acparser.h> 125224135Sdim 126224135Sdim 127251662Sdim#define _COMPONENT ACPI_DISPATCHER 128251662Sdim ACPI_MODULE_NAME ("dsfield") 129251662Sdim 130251662Sdim/* Local prototypes */ 131251662Sdim 132251662Sdimstatic ACPI_STATUS 133251662SdimAcpiDsGetFieldNames ( 134251662Sdim ACPI_CREATE_FIELD_INFO *Info, 135251662Sdim ACPI_WALK_STATE *WalkState, 136251662Sdim ACPI_PARSE_OBJECT *Arg); 137251662Sdim 138251662Sdim 139251662Sdim/******************************************************************************* 140251662Sdim * 141251662Sdim * FUNCTION: AcpiDsCreateBufferField 142251662Sdim * 143251662Sdim * PARAMETERS: Op - Current parse op (CreateXXField) 144224135Sdim * WalkState - Current state 145251662Sdim * 146251662Sdim * RETURN: Status 147251662Sdim * 148251662Sdim * DESCRIPTION: Execute the CreateField operators: 149251662Sdim * CreateBitFieldOp, 150251662Sdim * CreateByteFieldOp, 151251662Sdim * CreateWordFieldOp, 152251662Sdim * CreateDWordFieldOp, 153234353Sdim * CreateQWordFieldOp, 154234353Sdim * CreateFieldOp (all of which define a field in a buffer) 155224135Sdim * 156224135Sdim ******************************************************************************/ 157224135Sdim 158224135SdimACPI_STATUS 159234353SdimAcpiDsCreateBufferField ( 160234353Sdim ACPI_PARSE_OBJECT *Op, 161251662Sdim ACPI_WALK_STATE *WalkState) 162251662Sdim{ 163224135Sdim ACPI_PARSE_OBJECT *Arg; 164224135Sdim ACPI_NAMESPACE_NODE *Node; 165224135Sdim ACPI_STATUS Status; 166224135Sdim ACPI_OPERAND_OBJECT *ObjDesc; 167224135Sdim ACPI_OPERAND_OBJECT *SecondDesc = NULL; 168224135Sdim UINT32 Flags; 169224135Sdim 170224135Sdim 171224135Sdim ACPI_FUNCTION_TRACE (DsCreateBufferField); 172224135Sdim 173224135Sdim 174224135Sdim /* 175224135Sdim * Get the NameString argument (name of the new BufferField) 176224135Sdim */ 177224135Sdim if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP) 178234353Sdim { 179249423Sdim /* For CreateField, name is the 4th argument */ 180249423Sdim 181249423Sdim Arg = AcpiPsGetArg (Op, 3); 182249423Sdim } 183249423Sdim else 184249423Sdim { 185249423Sdim /* For all other CreateXXXField operators, name is the 3rd argument */ 186224135Sdim 187224135Sdim Arg = AcpiPsGetArg (Op, 2); 188224135Sdim } 189224135Sdim 190249423Sdim if (!Arg) 191234353Sdim { 192251662Sdim return_ACPI_STATUS (AE_AML_NO_OPERAND); 193251662Sdim } 194224135Sdim 195224135Sdim if (WalkState->DeferredNode) 196224135Sdim { 197224135Sdim Node = WalkState->DeferredNode; 198224135Sdim Status = AE_OK; 199234353Sdim } 200224135Sdim else 201234353Sdim { 202224135Sdim /* Execute flag should always be set when this function is entered */ 203224135Sdim 204224135Sdim if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE)) 205224135Sdim { 206234353Sdim return_ACPI_STATUS (AE_AML_INTERNAL); 207234353Sdim } 208234353Sdim 209234353Sdim /* Creating new namespace node, should not already exist */ 210234353Sdim 211234353Sdim Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 212234353Sdim ACPI_NS_ERROR_IF_FOUND; 213234353Sdim 214234353Sdim /* Mark node temporary if we are executing a method */ 215234353Sdim 216234353Sdim if (WalkState->MethodNode) 217234353Sdim { 218224135Sdim Flags |= ACPI_NS_TEMPORARY; 219234353Sdim } 220234353Sdim 221234353Sdim /* Enter the NameString into the namespace */ 222234353Sdim 223234353Sdim Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 224234353Sdim ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1, 225234353Sdim Flags, WalkState, &Node); 226224135Sdim if (ACPI_FAILURE (Status)) 227234353Sdim { 228234353Sdim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 229234353Sdim return_ACPI_STATUS (Status); 230234353Sdim } 231224135Sdim } 232224135Sdim 233224135Sdim /* 234224135Sdim * We could put the returned object (Node) on the object stack for later, 235224135Sdim * but for now, we will put it in the "op" object that the parser uses, 236234353Sdim * so we can get it again at the end of this scope. 237224135Sdim */ 238224135Sdim Op->Common.Node = Node; 239224135Sdim 240224135Sdim /* 241234353Sdim * If there is no object attached to the node, this node was just created 242224135Sdim * and we need to create the field object. Otherwise, this was a lookup 243224135Sdim * of an existing node and we don't want to create the field object again. 244224135Sdim */ 245224135Sdim ObjDesc = AcpiNsGetAttachedObject (Node); 246234353Sdim if (ObjDesc) 247224135Sdim { 248234353Sdim return_ACPI_STATUS (AE_OK); 249234353Sdim } 250234353Sdim 251234353Sdim /* 252224135Sdim * The Field definition is not fully parsed at this time. 253251662Sdim * (We must save the address of the AML for the buffer and index operands) 254224135Sdim */ 255224135Sdim 256234353Sdim /* Create the buffer field object */ 257234353Sdim 258224135Sdim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD); 259224135Sdim if (!ObjDesc) 260224135Sdim { 261224135Sdim Status = AE_NO_MEMORY; 262234353Sdim goto Cleanup; 263224135Sdim } 264224135Sdim 265224135Sdim /* 266224135Sdim * Remember location in AML stream of the field unit opcode and operands -- 267224135Sdim * since the buffer and index operands must be evaluated. 268224135Sdim */ 269224135Sdim SecondDesc = ObjDesc->Common.NextObject; 270224135Sdim SecondDesc->Extra.AmlStart = Op->Named.Data; 271224135Sdim SecondDesc->Extra.AmlLength = Op->Named.Length; 272224135Sdim ObjDesc->BufferField.Node = Node; 273224135Sdim 274224135Sdim /* Attach constructed field descriptors to parent node */ 275224135Sdim 276224135Sdim Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD); 277224135Sdim if (ACPI_FAILURE (Status)) 278224135Sdim { 279224135Sdim goto Cleanup; 280224135Sdim } 281224135Sdim 282224135Sdim 283224135SdimCleanup: 284224135Sdim 285224135Sdim /* Remove local reference to the object */ 286224135Sdim 287224135Sdim AcpiUtRemoveReference (ObjDesc); 288224135Sdim return_ACPI_STATUS (Status); 289224135Sdim} 290224135Sdim 291224135Sdim 292224135Sdim/******************************************************************************* 293224135Sdim * 294224135Sdim * FUNCTION: AcpiDsGetFieldNames 295224135Sdim * 296224135Sdim * PARAMETERS: Info - CreateField info structure 297224135Sdim * ` WalkState - Current method state 298224135Sdim * Arg - First parser arg for the field name list 299224135Sdim * 300224135Sdim * RETURN: Status 301224135Sdim * 302224135Sdim * DESCRIPTION: Process all named fields in a field declaration. Names are 303224135Sdim * entered into the namespace. 304224135Sdim * 305224135Sdim ******************************************************************************/ 306224135Sdim 307224135Sdimstatic ACPI_STATUS 308224135SdimAcpiDsGetFieldNames ( 309224135Sdim ACPI_CREATE_FIELD_INFO *Info, 310224135Sdim ACPI_WALK_STATE *WalkState, 311224135Sdim ACPI_PARSE_OBJECT *Arg) 312224135Sdim{ 313224135Sdim ACPI_STATUS Status; 314224135Sdim ACPI_INTEGER Position; 315224135Sdim 316224135Sdim 317224135Sdim ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info); 318224135Sdim 319224135Sdim 320224135Sdim /* First field starts at bit zero */ 321224135Sdim 322224135Sdim Info->FieldBitPosition = 0; 323224135Sdim 324224135Sdim /* Process all elements in the field list (of parse nodes) */ 325224135Sdim 326224135Sdim while (Arg) 327226633Sdim { 328224135Sdim /* 329224135Sdim * Three types of field elements are handled: 330224135Sdim * 1) Offset - specifies a bit offset 331224135Sdim * 2) AccessAs - changes the access mode 332224135Sdim * 3) Name - Enters a new named field into the namespace 333224135Sdim */ 334224135Sdim switch (Arg->Common.AmlOpcode) 335224135Sdim { 336224135Sdim case AML_INT_RESERVEDFIELD_OP: 337224135Sdim 338224135Sdim Position = (ACPI_INTEGER) Info->FieldBitPosition 339224135Sdim + (ACPI_INTEGER) Arg->Common.Value.Size; 340224135Sdim 341224135Sdim if (Position > ACPI_UINT32_MAX) 342224135Sdim { 343224135Sdim ACPI_ERROR ((AE_INFO, 344224135Sdim "Bit offset within field too large (> 0xFFFFFFFF)")); 345224135Sdim return_ACPI_STATUS (AE_SUPPORT); 346224135Sdim } 347224135Sdim 348224135Sdim Info->FieldBitPosition = (UINT32) Position; 349224135Sdim break; 350224135Sdim 351224135Sdim 352224135Sdim case AML_INT_ACCESSFIELD_OP: 353224135Sdim 354224135Sdim /* 355224135Sdim * Get a new AccessType and AccessAttribute -- to be used for all 356224135Sdim * field units that follow, until field end or another AccessAs 357224135Sdim * keyword. 358224135Sdim * 359224135Sdim * In FieldFlags, preserve the flag bits other than the 360224135Sdim * ACCESS_TYPE bits 361224135Sdim */ 362224135Sdim Info->FieldFlags = (UINT8) 363224135Sdim ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) | 364224135Sdim ((UINT8) ((UINT32) Arg->Common.Value.Integer >> 8))); 365224135Sdim 366226633Sdim Info->Attribute = (UINT8) (Arg->Common.Value.Integer); 367243830Sdim break; 368226633Sdim 369226633Sdim 370226633Sdim case AML_INT_NAMEDFIELD_OP: 371226633Sdim 372224135Sdim /* Lookup the name, it should already exist */ 373226633Sdim 374224135Sdim Status = AcpiNsLookup (WalkState->ScopeInfo, 375224135Sdim (char *) &Arg->Named.Name, Info->FieldType, 376224135Sdim ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE, 377224135Sdim WalkState, &Info->FieldNode); 378224135Sdim if (ACPI_FAILURE (Status)) 379224135Sdim { 380224135Sdim ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status); 381224135Sdim return_ACPI_STATUS (Status); 382224135Sdim } 383224135Sdim else 384224135Sdim { 385224135Sdim Arg->Common.Node = Info->FieldNode; 386224135Sdim Info->FieldBitLength = Arg->Common.Value.Size; 387224135Sdim 388224135Sdim /* 389224135Sdim * If there is no object attached to the node, this node was 390224135Sdim * just created and we need to create the field object. 391224135Sdim * Otherwise, this was a lookup of an existing node and we 392224135Sdim * don't want to create the field object again. 393224135Sdim */ 394224135Sdim if (!AcpiNsGetAttachedObject (Info->FieldNode)) 395224135Sdim { 396224135Sdim Status = AcpiExPrepFieldValue (Info); 397224135Sdim if (ACPI_FAILURE (Status)) 398224135Sdim { 399224135Sdim return_ACPI_STATUS (Status); 400224135Sdim } 401224135Sdim } 402224135Sdim } 403224135Sdim 404224135Sdim /* Keep track of bit position for the next field */ 405224135Sdim 406224135Sdim Position = (ACPI_INTEGER) Info->FieldBitPosition 407224135Sdim + (ACPI_INTEGER) Arg->Common.Value.Size; 408224135Sdim 409224135Sdim if (Position > ACPI_UINT32_MAX) 410224135Sdim { 411224135Sdim ACPI_ERROR ((AE_INFO, 412224135Sdim "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)", 413224135Sdim ACPI_CAST_PTR (char, &Info->FieldNode->Name))); 414224135Sdim return_ACPI_STATUS (AE_SUPPORT); 415224135Sdim } 416224135Sdim 417224135Sdim Info->FieldBitPosition += Info->FieldBitLength; 418224135Sdim break; 419224135Sdim 420224135Sdim 421224135Sdim default: 422224135Sdim 423224135Sdim ACPI_ERROR ((AE_INFO, 424224135Sdim "Invalid opcode in field list: %X", Arg->Common.AmlOpcode)); 425224135Sdim return_ACPI_STATUS (AE_AML_BAD_OPCODE); 426224135Sdim } 427224135Sdim 428224135Sdim Arg = Arg->Common.Next; 429224135Sdim } 430224135Sdim 431224135Sdim return_ACPI_STATUS (AE_OK); 432234353Sdim} 433224135Sdim 434224135Sdim 435224135Sdim/******************************************************************************* 436224135Sdim * 437224135Sdim * FUNCTION: AcpiDsCreateField 438224135Sdim * 439224135Sdim * PARAMETERS: Op - Op containing the Field definition and args 440224135Sdim * RegionNode - Object for the containing Operation Region 441224135Sdim * ` WalkState - Current method state 442224135Sdim * 443224135Sdim * RETURN: Status 444224135Sdim * 445224135Sdim * DESCRIPTION: Create a new field in the specified operation region 446224135Sdim * 447234353Sdim ******************************************************************************/ 448224135Sdim 449224135SdimACPI_STATUS 450239462SdimAcpiDsCreateField ( 451239462Sdim ACPI_PARSE_OBJECT *Op, 452224135Sdim ACPI_NAMESPACE_NODE *RegionNode, 453224135Sdim ACPI_WALK_STATE *WalkState) 454224135Sdim{ 455224135Sdim ACPI_STATUS Status; 456224135Sdim ACPI_PARSE_OBJECT *Arg; 457224135Sdim ACPI_CREATE_FIELD_INFO Info; 458224135Sdim 459224135Sdim 460224135Sdim ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op); 461224135Sdim 462224135Sdim 463224135Sdim /* First arg is the name of the parent OpRegion (must already exist) */ 464224135Sdim 465234353Sdim Arg = Op->Common.Value.Arg; 466224135Sdim if (!RegionNode) 467224135Sdim { 468224135Sdim Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name, 469224135Sdim ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE, 470224135Sdim ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode); 471224135Sdim if (ACPI_FAILURE (Status)) 472224135Sdim { 473224135Sdim ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status); 474224135Sdim return_ACPI_STATUS (Status); 475224135Sdim } 476224135Sdim } 477224135Sdim 478224135Sdim /* Second arg is the field flags */ 479224135Sdim 480224135Sdim Arg = Arg->Common.Next; 481224135Sdim Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 482234353Sdim Info.Attribute = 0; 483224135Sdim 484224135Sdim /* Each remaining arg is a Named Field */ 485224135Sdim 486224135Sdim Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD; 487224135Sdim Info.RegionNode = RegionNode; 488224135Sdim 489224135Sdim Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 490224135Sdim 491224135Sdim return_ACPI_STATUS (Status); 492224135Sdim} 493224135Sdim 494224135Sdim 495224135Sdim/******************************************************************************* 496224135Sdim * 497224135Sdim * FUNCTION: AcpiDsInitFieldObjects 498224135Sdim * 499224135Sdim * PARAMETERS: Op - Op containing the Field definition and args 500224135Sdim * ` WalkState - Current method state 501224135Sdim * 502224135Sdim * RETURN: Status 503224135Sdim * 504249423Sdim * DESCRIPTION: For each "Field Unit" name in the argument list that is 505249423Sdim * part of the field declaration, enter the name into the 506249423Sdim * namespace. 507224135Sdim * 508224135Sdim ******************************************************************************/ 509224135Sdim 510224135SdimACPI_STATUS 511224135SdimAcpiDsInitFieldObjects ( 512224135Sdim ACPI_PARSE_OBJECT *Op, 513224135Sdim ACPI_WALK_STATE *WalkState) 514224135Sdim{ 515224135Sdim ACPI_STATUS Status; 516224135Sdim ACPI_PARSE_OBJECT *Arg = NULL; 517224135Sdim ACPI_NAMESPACE_NODE *Node; 518224135Sdim UINT8 Type = 0; 519224135Sdim UINT32 Flags; 520224135Sdim 521224135Sdim 522224135Sdim ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op); 523224135Sdim 524224135Sdim 525224135Sdim /* Execute flag should always be set when this function is entered */ 526224135Sdim 527249423Sdim if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE)) 528249423Sdim { 529249423Sdim if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP) 530224135Sdim { 531224135Sdim /* BankField Op is deferred, just return OK */ 532224135Sdim 533224135Sdim return_ACPI_STATUS (AE_OK); 534224135Sdim } 535224135Sdim 536224135Sdim return_ACPI_STATUS (AE_AML_INTERNAL); 537224135Sdim } 538224135Sdim 539234353Sdim /* 540234353Sdim * Get the FieldList argument for this opcode. This is the start of the 541234353Sdim * list of field elements. 542263508Sdim */ 543263508Sdim switch (WalkState->Opcode) 544234353Sdim { 545234353Sdim case AML_FIELD_OP: 546263508Sdim Arg = AcpiPsGetArg (Op, 2); 547263508Sdim Type = ACPI_TYPE_LOCAL_REGION_FIELD; 548263508Sdim break; 549234353Sdim 550234353Sdim case AML_BANK_FIELD_OP: 551263508Sdim Arg = AcpiPsGetArg (Op, 4); 552263508Sdim Type = ACPI_TYPE_LOCAL_BANK_FIELD; 553263508Sdim break; 554263508Sdim 555263508Sdim case AML_INDEX_FIELD_OP: 556263508Sdim Arg = AcpiPsGetArg (Op, 3); 557263508Sdim Type = ACPI_TYPE_LOCAL_INDEX_FIELD; 558263508Sdim break; 559263508Sdim 560263508Sdim default: 561263508Sdim return_ACPI_STATUS (AE_BAD_PARAMETER); 562263508Sdim } 563263508Sdim 564263508Sdim /* Creating new namespace node(s), should not already exist */ 565263508Sdim 566263508Sdim Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 567263508Sdim ACPI_NS_ERROR_IF_FOUND; 568263508Sdim 569263508Sdim /* Mark node(s) temporary if we are executing a method */ 570263508Sdim 571263508Sdim if (WalkState->MethodNode) 572263508Sdim { 573263508Sdim Flags |= ACPI_NS_TEMPORARY; 574234353Sdim } 575263508Sdim 576263508Sdim /* 577263508Sdim * Walk the list of entries in the FieldList 578234353Sdim * Note: FieldList can be of zero length. In this case, Arg will be NULL. 579234353Sdim */ 580234353Sdim while (Arg) 581234353Sdim { 582224135Sdim /* 583234982Sdim * Ignore OFFSET and ACCESSAS terms here; we are only interested in the 584224135Sdim * field names in order to enter them into the namespace. 585224135Sdim */ 586224135Sdim if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP) 587224135Sdim { 588234982Sdim Status = AcpiNsLookup (WalkState->ScopeInfo, 589234982Sdim (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1, 590239462Sdim Flags, WalkState, &Node); 591239462Sdim if (ACPI_FAILURE (Status)) 592224135Sdim { 593224135Sdim ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status); 594224135Sdim if (Status != AE_ALREADY_EXISTS) 595224135Sdim { 596224135Sdim return_ACPI_STATUS (Status); 597224135Sdim } 598224135Sdim 599224135Sdim /* Name already exists, just ignore this error */ 600224135Sdim 601224135Sdim Status = AE_OK; 602224135Sdim } 603224135Sdim 604224135Sdim Arg->Common.Node = Node; 605224135Sdim } 606224135Sdim 607224135Sdim /* Get the next field element in the list */ 608224135Sdim 609224135Sdim Arg = Arg->Common.Next; 610224135Sdim } 611224135Sdim 612224135Sdim return_ACPI_STATUS (AE_OK); 613224135Sdim} 614224135Sdim 615224135Sdim 616224135Sdim/******************************************************************************* 617224135Sdim * 618224135Sdim * FUNCTION: AcpiDsCreateBankField 619224135Sdim * 620224135Sdim * PARAMETERS: Op - Op containing the Field definition and args 621224135Sdim * RegionNode - Object for the containing Operation Region 622224135Sdim * WalkState - Current method state 623224135Sdim * 624224135Sdim * RETURN: Status 625224135Sdim * 626224135Sdim * DESCRIPTION: Create a new bank field in the specified operation region 627224135Sdim * 628224135Sdim ******************************************************************************/ 629224135Sdim 630224135SdimACPI_STATUS 631224135SdimAcpiDsCreateBankField ( 632224135Sdim ACPI_PARSE_OBJECT *Op, 633263508Sdim ACPI_NAMESPACE_NODE *RegionNode, 634224135Sdim ACPI_WALK_STATE *WalkState) 635224135Sdim{ 636234353Sdim ACPI_STATUS Status; 637224135Sdim ACPI_PARSE_OBJECT *Arg; 638263508Sdim ACPI_CREATE_FIELD_INFO Info; 639224135Sdim 640263508Sdim 641263508Sdim ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op); 642263508Sdim 643263508Sdim 644263508Sdim /* First arg is the name of the parent OpRegion (must already exist) */ 645263508Sdim 646263508Sdim Arg = Op->Common.Value.Arg; 647263508Sdim if (!RegionNode) 648263508Sdim { 649263508Sdim Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name, 650263508Sdim ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE, 651263508Sdim ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode); 652263508Sdim if (ACPI_FAILURE (Status)) 653263508Sdim { 654263508Sdim ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status); 655263508Sdim return_ACPI_STATUS (Status); 656263508Sdim } 657263508Sdim } 658224135Sdim 659224135Sdim /* Second arg is the Bank Register (Field) (must already exist) */ 660224135Sdim 661224135Sdim Arg = Arg->Common.Next; 662224135Sdim Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 663224135Sdim ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 664224135Sdim ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode); 665224135Sdim if (ACPI_FAILURE (Status)) 666224135Sdim { 667234353Sdim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 668224135Sdim return_ACPI_STATUS (Status); 669224135Sdim } 670224135Sdim 671224135Sdim /* 672224135Sdim * Third arg is the BankValue 673224135Sdim * This arg is a TermArg, not a constant 674224135Sdim * It will be evaluated later, by AcpiDsEvalBankFieldOperands 675234353Sdim */ 676224135Sdim Arg = Arg->Common.Next; 677224135Sdim 678224135Sdim /* Fourth arg is the field flags */ 679224135Sdim 680224135Sdim Arg = Arg->Common.Next; 681224135Sdim Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 682224135Sdim 683224135Sdim /* Each remaining arg is a Named Field */ 684224135Sdim 685224135Sdim Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD; 686224135Sdim Info.RegionNode = RegionNode; 687224135Sdim 688224135Sdim /* 689224135Sdim * Use Info.DataRegisterNode to store BankField Op 690224135Sdim * It's safe because DataRegisterNode will never be used when create bank field 691224135Sdim * We store AmlStart and AmlLength in the BankField Op for late evaluation 692224135Sdim * Used in AcpiExPrepFieldValue(Info) 693224135Sdim * 694224135Sdim * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like "void *ParentOp"? 695224135Sdim */ 696224135Sdim Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op; 697224135Sdim 698224135Sdim Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 699224135Sdim return_ACPI_STATUS (Status); 700224135Sdim} 701224135Sdim 702224135Sdim 703224135Sdim/******************************************************************************* 704224135Sdim * 705224135Sdim * FUNCTION: AcpiDsCreateIndexField 706243830Sdim * 707224135Sdim * PARAMETERS: Op - Op containing the Field definition and args 708224135Sdim * RegionNode - Object for the containing Operation Region 709224135Sdim * ` WalkState - Current method state 710224135Sdim * 711224135Sdim * RETURN: Status 712224135Sdim * 713234353Sdim * DESCRIPTION: Create a new index field in the specified operation region 714234353Sdim * 715224135Sdim ******************************************************************************/ 716224135Sdim 717224135SdimACPI_STATUS 718224135SdimAcpiDsCreateIndexField ( 719224135Sdim ACPI_PARSE_OBJECT *Op, 720224135Sdim ACPI_NAMESPACE_NODE *RegionNode, 721224135Sdim ACPI_WALK_STATE *WalkState) 722224135Sdim{ 723224135Sdim ACPI_STATUS Status; 724224135Sdim ACPI_PARSE_OBJECT *Arg; 725224135Sdim ACPI_CREATE_FIELD_INFO Info; 726224135Sdim 727263508Sdim 728224135Sdim ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op); 729224135Sdim 730224135Sdim 731224135Sdim /* First arg is the name of the Index register (must already exist) */ 732224135Sdim 733224135Sdim Arg = Op->Common.Value.Arg; 734224135Sdim Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 735224135Sdim ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 736224135Sdim ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode); 737224135Sdim if (ACPI_FAILURE (Status)) 738224135Sdim { 739224135Sdim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 740224135Sdim return_ACPI_STATUS (Status); 741224135Sdim } 742224135Sdim 743224135Sdim /* Second arg is the data register (must already exist) */ 744224135Sdim 745224135Sdim Arg = Arg->Common.Next; 746224135Sdim Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 747224135Sdim ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 748224135Sdim ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode); 749224135Sdim if (ACPI_FAILURE (Status)) 750224135Sdim { 751224135Sdim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 752224135Sdim return_ACPI_STATUS (Status); 753224135Sdim } 754224135Sdim 755224135Sdim /* Next arg is the field flags */ 756224135Sdim 757224135Sdim Arg = Arg->Common.Next; 758224135Sdim Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 759224135Sdim 760224135Sdim /* Each remaining arg is a Named Field */ 761224135Sdim 762224135Sdim Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD; 763224135Sdim Info.RegionNode = RegionNode; 764224135Sdim 765224135Sdim Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 766224135Sdim 767224135Sdim return_ACPI_STATUS (Status); 768224135Sdim} 769224135Sdim 770224135Sdim 771224135Sdim