167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: dsfield - Dispatcher field routines 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 4467754Smsmith#define __DSFIELD_C__ 4567754Smsmith 46193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 47193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 48193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 49193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 50193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 51193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 52193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 5367754Smsmith 5467754Smsmith 5577424Smsmith#define _COMPONENT ACPI_DISPATCHER 5691116Smsmith ACPI_MODULE_NAME ("dsfield") 5767754Smsmith 58151937Sjkim/* Local prototypes */ 5967754Smsmith 60235945Sjkim#ifdef ACPI_ASL_COMPILER 61235945Sjkim#include <contrib/dev/acpica/include/acdisasm.h> 62235945Sjkim 63151937Sjkimstatic ACPI_STATUS 64235945SjkimAcpiDsCreateExternalRegion ( 65235945Sjkim ACPI_STATUS LookupStatus, 66235945Sjkim ACPI_PARSE_OBJECT *Op, 67235945Sjkim char *Path, 68235945Sjkim ACPI_WALK_STATE *WalkState, 69235945Sjkim ACPI_NAMESPACE_NODE **Node); 70235945Sjkim#endif 71235945Sjkim 72235945Sjkimstatic ACPI_STATUS 73151937SjkimAcpiDsGetFieldNames ( 74151937Sjkim ACPI_CREATE_FIELD_INFO *Info, 75151937Sjkim ACPI_WALK_STATE *WalkState, 76151937Sjkim ACPI_PARSE_OBJECT *Arg); 77151937Sjkim 78151937Sjkim 79235945Sjkim#ifdef ACPI_ASL_COMPILER 8067754Smsmith/******************************************************************************* 8167754Smsmith * 82235945Sjkim * FUNCTION: AcpiDsCreateExternalRegion (iASL Disassembler only) 83235945Sjkim * 84235945Sjkim * PARAMETERS: LookupStatus - Status from NsLookup operation 85235945Sjkim * Op - Op containing the Field definition and args 86235945Sjkim * Path - Pathname of the region 87235945Sjkim * ` WalkState - Current method state 88235945Sjkim * Node - Where the new region node is returned 89235945Sjkim * 90235945Sjkim * RETURN: Status 91235945Sjkim * 92235945Sjkim * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new 93235945Sjkim * region node/object. 94235945Sjkim * 95235945Sjkim ******************************************************************************/ 96235945Sjkim 97235945Sjkimstatic ACPI_STATUS 98235945SjkimAcpiDsCreateExternalRegion ( 99235945Sjkim ACPI_STATUS LookupStatus, 100235945Sjkim ACPI_PARSE_OBJECT *Op, 101235945Sjkim char *Path, 102235945Sjkim ACPI_WALK_STATE *WalkState, 103235945Sjkim ACPI_NAMESPACE_NODE **Node) 104235945Sjkim{ 105235945Sjkim ACPI_STATUS Status; 106235945Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 107235945Sjkim 108235945Sjkim 109235945Sjkim if (LookupStatus != AE_NOT_FOUND) 110235945Sjkim { 111235945Sjkim return (LookupStatus); 112235945Sjkim } 113235945Sjkim 114235945Sjkim /* 115235945Sjkim * Table disassembly: 116235945Sjkim * OperationRegion not found. Generate an External for it, and 117235945Sjkim * insert the name into the namespace. 118235945Sjkim */ 119235945Sjkim AcpiDmAddToExternalList (Op, Path, ACPI_TYPE_REGION, 0); 120235945Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_REGION, 121235945Sjkim ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, WalkState, Node); 122235945Sjkim if (ACPI_FAILURE (Status)) 123235945Sjkim { 124235945Sjkim return (Status); 125235945Sjkim } 126235945Sjkim 127235945Sjkim /* Must create and install a region object for the new node */ 128235945Sjkim 129235945Sjkim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION); 130235945Sjkim if (!ObjDesc) 131235945Sjkim { 132235945Sjkim return (AE_NO_MEMORY); 133235945Sjkim } 134235945Sjkim 135235945Sjkim ObjDesc->Region.Node = *Node; 136235945Sjkim Status = AcpiNsAttachObject (*Node, ObjDesc, ACPI_TYPE_REGION); 137235945Sjkim return (Status); 138235945Sjkim} 139235945Sjkim#endif 140235945Sjkim 141235945Sjkim 142235945Sjkim/******************************************************************************* 143235945Sjkim * 14485756Smsmith * FUNCTION: AcpiDsCreateBufferField 14567754Smsmith * 146151937Sjkim * PARAMETERS: Op - Current parse op (CreateXXField) 14785756Smsmith * WalkState - Current state 14867754Smsmith * 14967754Smsmith * RETURN: Status 15067754Smsmith * 15187031Smsmith * DESCRIPTION: Execute the CreateField operators: 15285756Smsmith * CreateBitFieldOp, 15387031Smsmith * CreateByteFieldOp, 15487031Smsmith * CreateWordFieldOp, 155237412Sjkim * CreateDwordFieldOp, 156237412Sjkim * CreateQwordFieldOp, 157151937Sjkim * CreateFieldOp (all of which define a field in a buffer) 15867754Smsmith * 15967754Smsmith ******************************************************************************/ 16067754Smsmith 16167754SmsmithACPI_STATUS 16285756SmsmithAcpiDsCreateBufferField ( 16367754Smsmith ACPI_PARSE_OBJECT *Op, 16467754Smsmith ACPI_WALK_STATE *WalkState) 16567754Smsmith{ 16667754Smsmith ACPI_PARSE_OBJECT *Arg; 16767754Smsmith ACPI_NAMESPACE_NODE *Node; 16885756Smsmith ACPI_STATUS Status; 16985756Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 17087031Smsmith ACPI_OPERAND_OBJECT *SecondDesc = NULL; 17187031Smsmith UINT32 Flags; 17267754Smsmith 17367754Smsmith 174167802Sjkim ACPI_FUNCTION_TRACE (DsCreateBufferField); 17567754Smsmith 17667754Smsmith 177193267Sjkim /* 178193267Sjkim * Get the NameString argument (name of the new BufferField) 179193267Sjkim */ 18099679Siwasaki if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP) 18167754Smsmith { 182193267Sjkim /* For CreateField, name is the 4th argument */ 183193267Sjkim 18485756Smsmith Arg = AcpiPsGetArg (Op, 3); 18567754Smsmith } 18685756Smsmith else 18785756Smsmith { 188193267Sjkim /* For all other CreateXXXField operators, name is the 3rd argument */ 18967754Smsmith 19085756Smsmith Arg = AcpiPsGetArg (Op, 2); 19185756Smsmith } 19267754Smsmith 19385756Smsmith if (!Arg) 19485756Smsmith { 19585756Smsmith return_ACPI_STATUS (AE_AML_NO_OPERAND); 19685756Smsmith } 19767754Smsmith 198123315Snjl if (WalkState->DeferredNode) 19987031Smsmith { 200123315Snjl Node = WalkState->DeferredNode; 201123315Snjl Status = AE_OK; 20287031Smsmith } 20387031Smsmith else 20487031Smsmith { 205193267Sjkim /* Execute flag should always be set when this function is entered */ 206193267Sjkim 207193267Sjkim if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE)) 208123315Snjl { 209193267Sjkim return_ACPI_STATUS (AE_AML_INTERNAL); 210123315Snjl } 211193267Sjkim 212193267Sjkim /* Creating new namespace node, should not already exist */ 213193267Sjkim 214193267Sjkim Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 215193267Sjkim ACPI_NS_ERROR_IF_FOUND; 216193267Sjkim 217197104Sjkim /* 218197104Sjkim * Mark node temporary if we are executing a normal control 219197104Sjkim * method. (Don't mark if this is a module-level code method) 220197104Sjkim */ 221197104Sjkim if (WalkState->MethodNode && 222197104Sjkim !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) 223123315Snjl { 224193267Sjkim Flags |= ACPI_NS_TEMPORARY; 225123315Snjl } 22687031Smsmith 227193267Sjkim /* Enter the NameString into the namespace */ 228193267Sjkim 229123315Snjl Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 230193267Sjkim ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1, 231193267Sjkim Flags, WalkState, &Node); 232123315Snjl if (ACPI_FAILURE (Status)) 233123315Snjl { 234167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 235123315Snjl return_ACPI_STATUS (Status); 236123315Snjl } 23785756Smsmith } 23867754Smsmith 239167802Sjkim /* 240167802Sjkim * We could put the returned object (Node) on the object stack for later, 241151937Sjkim * but for now, we will put it in the "op" object that the parser uses, 242193267Sjkim * so we can get it again at the end of this scope. 24385756Smsmith */ 24499679Siwasaki Op->Common.Node = Node; 24585756Smsmith 24685756Smsmith /* 247151937Sjkim * If there is no object attached to the node, this node was just created 248193267Sjkim * and we need to create the field object. Otherwise, this was a lookup 249151937Sjkim * of an existing node and we don't want to create the field object again. 25085756Smsmith */ 25187031Smsmith ObjDesc = AcpiNsGetAttachedObject (Node); 25287031Smsmith if (ObjDesc) 25385756Smsmith { 25485756Smsmith return_ACPI_STATUS (AE_OK); 25585756Smsmith } 25685756Smsmith 25785756Smsmith /* 25885756Smsmith * The Field definition is not fully parsed at this time. 25985756Smsmith * (We must save the address of the AML for the buffer and index operands) 26085756Smsmith */ 26185756Smsmith 26285756Smsmith /* Create the buffer field object */ 26385756Smsmith 26485756Smsmith ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD); 26585756Smsmith if (!ObjDesc) 26685756Smsmith { 26785756Smsmith Status = AE_NO_MEMORY; 26885756Smsmith goto Cleanup; 26985756Smsmith } 27085756Smsmith 27185756Smsmith /* 272193267Sjkim * Remember location in AML stream of the field unit opcode and operands -- 273193267Sjkim * since the buffer and index operands must be evaluated. 27485756Smsmith */ 27587031Smsmith SecondDesc = ObjDesc->Common.NextObject; 27699679Siwasaki SecondDesc->Extra.AmlStart = Op->Named.Data; 27799679Siwasaki SecondDesc->Extra.AmlLength = Op->Named.Length; 27887031Smsmith ObjDesc->BufferField.Node = Node; 27985756Smsmith 28087031Smsmith /* Attach constructed field descriptors to parent node */ 28185756Smsmith 28285756Smsmith Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD); 28387031Smsmith if (ACPI_FAILURE (Status)) 28487031Smsmith { 28587031Smsmith goto Cleanup; 28687031Smsmith } 28785756Smsmith 28885756Smsmith 28985756SmsmithCleanup: 29085756Smsmith 29185756Smsmith /* Remove local reference to the object */ 29285756Smsmith 29385756Smsmith AcpiUtRemoveReference (ObjDesc); 29485756Smsmith return_ACPI_STATUS (Status); 29585756Smsmith} 29685756Smsmith 29785756Smsmith 29885756Smsmith/******************************************************************************* 29985756Smsmith * 30085756Smsmith * FUNCTION: AcpiDsGetFieldNames 30185756Smsmith * 30285756Smsmith * PARAMETERS: Info - CreateField info structure 30385756Smsmith * ` WalkState - Current method state 30485756Smsmith * Arg - First parser arg for the field name list 30585756Smsmith * 30685756Smsmith * RETURN: Status 30785756Smsmith * 308241973Sjkim * DESCRIPTION: Process all named fields in a field declaration. Names are 30985756Smsmith * entered into the namespace. 31085756Smsmith * 31185756Smsmith ******************************************************************************/ 31285756Smsmith 313151937Sjkimstatic ACPI_STATUS 31485756SmsmithAcpiDsGetFieldNames ( 31585756Smsmith ACPI_CREATE_FIELD_INFO *Info, 31685756Smsmith ACPI_WALK_STATE *WalkState, 31785756Smsmith ACPI_PARSE_OBJECT *Arg) 31885756Smsmith{ 31985756Smsmith ACPI_STATUS Status; 320202771Sjkim UINT64 Position; 321228110Sjkim ACPI_PARSE_OBJECT *Child; 32285756Smsmith 32385756Smsmith 324167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info); 32585756Smsmith 32685756Smsmith 32785756Smsmith /* First field starts at bit zero */ 32885756Smsmith 32985756Smsmith Info->FieldBitPosition = 0; 33085756Smsmith 33185756Smsmith /* Process all elements in the field list (of parse nodes) */ 33285756Smsmith 33367754Smsmith while (Arg) 33467754Smsmith { 33585756Smsmith /* 336228110Sjkim * Four types of field elements are handled: 337228110Sjkim * 1) Name - Enters a new named field into the namespace 338228110Sjkim * 2) Offset - specifies a bit offset 339228110Sjkim * 3) AccessAs - changes the access mode/attributes 340228110Sjkim * 4) Connection - Associate a resource template with the field 34185756Smsmith */ 34299679Siwasaki switch (Arg->Common.AmlOpcode) 34367754Smsmith { 34477424Smsmith case AML_INT_RESERVEDFIELD_OP: 34567754Smsmith 346202771Sjkim Position = (UINT64) Info->FieldBitPosition 347202771Sjkim + (UINT64) Arg->Common.Value.Size; 34899679Siwasaki 34999679Siwasaki if (Position > ACPI_UINT32_MAX) 35091116Smsmith { 351167802Sjkim ACPI_ERROR ((AE_INFO, 352167802Sjkim "Bit offset within field too large (> 0xFFFFFFFF)")); 35391116Smsmith return_ACPI_STATUS (AE_SUPPORT); 35491116Smsmith } 35591116Smsmith 35699679Siwasaki Info->FieldBitPosition = (UINT32) Position; 35767754Smsmith break; 35867754Smsmith 35977424Smsmith case AML_INT_ACCESSFIELD_OP: 360228110Sjkim case AML_INT_EXTACCESSFIELD_OP: 36167754Smsmith /* 362228110Sjkim * Get new AccessType, AccessAttribute, and AccessLength fields 363228110Sjkim * -- to be used for all field units that follow, until the 364228110Sjkim * end-of-field or another AccessAs keyword is encountered. 365228110Sjkim * NOTE. These three bytes are encoded in the integer value 366228110Sjkim * of the parseop for convenience. 36787031Smsmith * 368151937Sjkim * In FieldFlags, preserve the flag bits other than the 369228110Sjkim * ACCESS_TYPE bits. 37067754Smsmith */ 371228110Sjkim 372228110Sjkim /* AccessType (ByteAcc, WordAcc, etc.) */ 373228110Sjkim 374151937Sjkim Info->FieldFlags = (UINT8) 375151937Sjkim ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) | 376228110Sjkim ((UINT8) ((UINT32) (Arg->Common.Value.Integer & 0x07)))); 37787031Smsmith 378228110Sjkim /* AccessAttribute (AttribQuick, AttribByte, etc.) */ 379228110Sjkim 380228110Sjkim Info->Attribute = (UINT8) ((Arg->Common.Value.Integer >> 8) & 0xFF); 381228110Sjkim 382228110Sjkim /* AccessLength (for serial/buffer protocols) */ 383228110Sjkim 384228110Sjkim Info->AccessLength = (UINT8) ((Arg->Common.Value.Integer >> 16) & 0xFF); 38567754Smsmith break; 38667754Smsmith 387228110Sjkim case AML_INT_CONNECTION_OP: 388228110Sjkim /* 389228110Sjkim * Clear any previous connection. New connection is used for all 390228110Sjkim * fields that follow, similar to AccessAs 391228110Sjkim */ 392228110Sjkim Info->ResourceBuffer = NULL; 393228110Sjkim Info->ConnectionNode = NULL; 39467754Smsmith 395228110Sjkim /* 396228110Sjkim * A Connection() is either an actual resource descriptor (buffer) 397228110Sjkim * or a named reference to a resource template 398228110Sjkim */ 399228110Sjkim Child = Arg->Common.Value.Arg; 400228110Sjkim if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP) 401228110Sjkim { 402228110Sjkim Info->ResourceBuffer = Child->Named.Data; 403228110Sjkim Info->ResourceLength = (UINT16) Child->Named.Value.Integer; 404228110Sjkim } 405228110Sjkim else 406228110Sjkim { 407228110Sjkim /* Lookup the Connection() namepath, it should already exist */ 408228110Sjkim 409228110Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, 410228110Sjkim Child->Common.Value.Name, ACPI_TYPE_ANY, 411228110Sjkim ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE, 412228110Sjkim WalkState, &Info->ConnectionNode); 413228110Sjkim if (ACPI_FAILURE (Status)) 414228110Sjkim { 415228110Sjkim ACPI_ERROR_NAMESPACE (Child->Common.Value.Name, Status); 416228110Sjkim return_ACPI_STATUS (Status); 417228110Sjkim } 418228110Sjkim } 419228110Sjkim break; 420228110Sjkim 42177424Smsmith case AML_INT_NAMEDFIELD_OP: 42267754Smsmith 423193267Sjkim /* Lookup the name, it should already exist */ 42485756Smsmith 42567754Smsmith Status = AcpiNsLookup (WalkState->ScopeInfo, 426193267Sjkim (char *) &Arg->Named.Name, Info->FieldType, 427193267Sjkim ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE, 428193267Sjkim WalkState, &Info->FieldNode); 42967754Smsmith if (ACPI_FAILURE (Status)) 43067754Smsmith { 431167802Sjkim ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status); 432193267Sjkim return_ACPI_STATUS (Status); 43367754Smsmith } 43487031Smsmith else 43587031Smsmith { 43699679Siwasaki Arg->Common.Node = Info->FieldNode; 43799679Siwasaki Info->FieldBitLength = Arg->Common.Value.Size; 43867754Smsmith 439193267Sjkim /* 440193267Sjkim * If there is no object attached to the node, this node was 441193267Sjkim * just created and we need to create the field object. 442193267Sjkim * Otherwise, this was a lookup of an existing node and we 443193267Sjkim * don't want to create the field object again. 444193267Sjkim */ 445193267Sjkim if (!AcpiNsGetAttachedObject (Info->FieldNode)) 44687031Smsmith { 447193267Sjkim Status = AcpiExPrepFieldValue (Info); 448193267Sjkim if (ACPI_FAILURE (Status)) 449193267Sjkim { 450193267Sjkim return_ACPI_STATUS (Status); 451193267Sjkim } 45287031Smsmith } 45367754Smsmith } 45467754Smsmith 45585756Smsmith /* Keep track of bit position for the next field */ 45667754Smsmith 457202771Sjkim Position = (UINT64) Info->FieldBitPosition 458202771Sjkim + (UINT64) Arg->Common.Value.Size; 45999679Siwasaki 46099679Siwasaki if (Position > ACPI_UINT32_MAX) 46191116Smsmith { 462167802Sjkim ACPI_ERROR ((AE_INFO, 463167802Sjkim "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)", 464167802Sjkim ACPI_CAST_PTR (char, &Info->FieldNode->Name))); 46591116Smsmith return_ACPI_STATUS (AE_SUPPORT); 46691116Smsmith } 46791116Smsmith 46885756Smsmith Info->FieldBitPosition += Info->FieldBitLength; 46967754Smsmith break; 47085756Smsmith 47185756Smsmith default: 47285756Smsmith 473167802Sjkim ACPI_ERROR ((AE_INFO, 474204773Sjkim "Invalid opcode in field list: 0x%X", Arg->Common.AmlOpcode)); 47599679Siwasaki return_ACPI_STATUS (AE_AML_BAD_OPCODE); 47667754Smsmith } 47767754Smsmith 47899679Siwasaki Arg = Arg->Common.Next; 47967754Smsmith } 48067754Smsmith 48185756Smsmith return_ACPI_STATUS (AE_OK); 48285756Smsmith} 48385756Smsmith 48485756Smsmith 48585756Smsmith/******************************************************************************* 48685756Smsmith * 48785756Smsmith * FUNCTION: AcpiDsCreateField 48885756Smsmith * 48985756Smsmith * PARAMETERS: Op - Op containing the Field definition and args 49085756Smsmith * RegionNode - Object for the containing Operation Region 49185756Smsmith * ` WalkState - Current method state 49285756Smsmith * 49385756Smsmith * RETURN: Status 49485756Smsmith * 49585756Smsmith * DESCRIPTION: Create a new field in the specified operation region 49685756Smsmith * 49785756Smsmith ******************************************************************************/ 49885756Smsmith 49985756SmsmithACPI_STATUS 50085756SmsmithAcpiDsCreateField ( 50185756Smsmith ACPI_PARSE_OBJECT *Op, 50285756Smsmith ACPI_NAMESPACE_NODE *RegionNode, 50385756Smsmith ACPI_WALK_STATE *WalkState) 50485756Smsmith{ 50599679Siwasaki ACPI_STATUS Status; 50685756Smsmith ACPI_PARSE_OBJECT *Arg; 50785756Smsmith ACPI_CREATE_FIELD_INFO Info; 50885756Smsmith 50985756Smsmith 510167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op); 51185756Smsmith 51285756Smsmith 51385756Smsmith /* First arg is the name of the parent OpRegion (must already exist) */ 51485756Smsmith 51599679Siwasaki Arg = Op->Common.Value.Arg; 516235945Sjkim 51785756Smsmith if (!RegionNode) 51885756Smsmith { 51999679Siwasaki Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name, 52091116Smsmith ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE, 52191116Smsmith ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode); 522235945Sjkim#ifdef ACPI_ASL_COMPILER 523235945Sjkim Status = AcpiDsCreateExternalRegion (Status, Arg, 524235945Sjkim Arg->Common.Value.Name, WalkState, &RegionNode); 525235945Sjkim#endif 52685756Smsmith if (ACPI_FAILURE (Status)) 52785756Smsmith { 528167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status); 52985756Smsmith return_ACPI_STATUS (Status); 53085756Smsmith } 53185756Smsmith } 53285756Smsmith 533228110Sjkim ACPI_MEMSET (&Info, 0, sizeof (ACPI_CREATE_FIELD_INFO)); 534228110Sjkim 53585756Smsmith /* Second arg is the field flags */ 53685756Smsmith 53799679Siwasaki Arg = Arg->Common.Next; 538117521Snjl Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 53987031Smsmith Info.Attribute = 0; 54085756Smsmith 54185756Smsmith /* Each remaining arg is a Named Field */ 54285756Smsmith 543107325Siwasaki Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD; 54485756Smsmith Info.RegionNode = RegionNode; 54585756Smsmith 54699679Siwasaki Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 54767754Smsmith return_ACPI_STATUS (Status); 54867754Smsmith} 54967754Smsmith 55067754Smsmith 55167754Smsmith/******************************************************************************* 55267754Smsmith * 55387031Smsmith * FUNCTION: AcpiDsInitFieldObjects 55487031Smsmith * 55587031Smsmith * PARAMETERS: Op - Op containing the Field definition and args 55687031Smsmith * ` WalkState - Current method state 55787031Smsmith * 55887031Smsmith * RETURN: Status 55987031Smsmith * 56087031Smsmith * DESCRIPTION: For each "Field Unit" name in the argument list that is 56187031Smsmith * part of the field declaration, enter the name into the 56287031Smsmith * namespace. 56387031Smsmith * 56487031Smsmith ******************************************************************************/ 56587031Smsmith 56687031SmsmithACPI_STATUS 56787031SmsmithAcpiDsInitFieldObjects ( 56887031Smsmith ACPI_PARSE_OBJECT *Op, 56987031Smsmith ACPI_WALK_STATE *WalkState) 57087031Smsmith{ 57199679Siwasaki ACPI_STATUS Status; 57287031Smsmith ACPI_PARSE_OBJECT *Arg = NULL; 57387031Smsmith ACPI_NAMESPACE_NODE *Node; 57487031Smsmith UINT8 Type = 0; 575193267Sjkim UINT32 Flags; 57687031Smsmith 57787031Smsmith 578167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op); 57987031Smsmith 58087031Smsmith 581193267Sjkim /* Execute flag should always be set when this function is entered */ 582193267Sjkim 583193267Sjkim if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE)) 584193267Sjkim { 585193267Sjkim if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP) 586193267Sjkim { 587193267Sjkim /* BankField Op is deferred, just return OK */ 588193267Sjkim 589193267Sjkim return_ACPI_STATUS (AE_OK); 590193267Sjkim } 591193267Sjkim 592193267Sjkim return_ACPI_STATUS (AE_AML_INTERNAL); 593193267Sjkim } 594193267Sjkim 595193267Sjkim /* 596193267Sjkim * Get the FieldList argument for this opcode. This is the start of the 597193267Sjkim * list of field elements. 598193267Sjkim */ 59987031Smsmith switch (WalkState->Opcode) 60087031Smsmith { 60187031Smsmith case AML_FIELD_OP: 602250838Sjkim 60387031Smsmith Arg = AcpiPsGetArg (Op, 2); 604107325Siwasaki Type = ACPI_TYPE_LOCAL_REGION_FIELD; 60587031Smsmith break; 60687031Smsmith 60787031Smsmith case AML_BANK_FIELD_OP: 608250838Sjkim 60987031Smsmith Arg = AcpiPsGetArg (Op, 4); 610107325Siwasaki Type = ACPI_TYPE_LOCAL_BANK_FIELD; 61187031Smsmith break; 61287031Smsmith 61387031Smsmith case AML_INDEX_FIELD_OP: 614250838Sjkim 61587031Smsmith Arg = AcpiPsGetArg (Op, 3); 616107325Siwasaki Type = ACPI_TYPE_LOCAL_INDEX_FIELD; 61787031Smsmith break; 61899679Siwasaki 61999679Siwasaki default: 620250838Sjkim 62199679Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 62287031Smsmith } 62387031Smsmith 624193267Sjkim /* Creating new namespace node(s), should not already exist */ 625193267Sjkim 626193267Sjkim Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 627193267Sjkim ACPI_NS_ERROR_IF_FOUND; 628193267Sjkim 629197104Sjkim /* 630197104Sjkim * Mark node(s) temporary if we are executing a normal control 631197104Sjkim * method. (Don't mark if this is a module-level code method) 632197104Sjkim */ 633197104Sjkim if (WalkState->MethodNode && 634197104Sjkim !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) 635193267Sjkim { 636193267Sjkim Flags |= ACPI_NS_TEMPORARY; 637193267Sjkim } 638193267Sjkim 63987031Smsmith /* 64087031Smsmith * Walk the list of entries in the FieldList 641193267Sjkim * Note: FieldList can be of zero length. In this case, Arg will be NULL. 64287031Smsmith */ 64387031Smsmith while (Arg) 64487031Smsmith { 645193267Sjkim /* 646228110Sjkim * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested 647228110Sjkim * in the field names in order to enter them into the namespace. 648193267Sjkim */ 64999679Siwasaki if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP) 65087031Smsmith { 65187031Smsmith Status = AcpiNsLookup (WalkState->ScopeInfo, 652193267Sjkim (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1, 653193267Sjkim Flags, WalkState, &Node); 65487031Smsmith if (ACPI_FAILURE (Status)) 65587031Smsmith { 656167802Sjkim ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status); 65787031Smsmith if (Status != AE_ALREADY_EXISTS) 65887031Smsmith { 65987031Smsmith return_ACPI_STATUS (Status); 66087031Smsmith } 66187031Smsmith 66299679Siwasaki /* Name already exists, just ignore this error */ 66399679Siwasaki 66499679Siwasaki Status = AE_OK; 66587031Smsmith } 66687031Smsmith 66799679Siwasaki Arg->Common.Node = Node; 66887031Smsmith } 66987031Smsmith 670193267Sjkim /* Get the next field element in the list */ 67187031Smsmith 67299679Siwasaki Arg = Arg->Common.Next; 67387031Smsmith } 67487031Smsmith 67599679Siwasaki return_ACPI_STATUS (AE_OK); 67687031Smsmith} 67787031Smsmith 67887031Smsmith 67987031Smsmith/******************************************************************************* 68087031Smsmith * 68167754Smsmith * FUNCTION: AcpiDsCreateBankField 68267754Smsmith * 68367754Smsmith * PARAMETERS: Op - Op containing the Field definition and args 68477424Smsmith * RegionNode - Object for the containing Operation Region 685193267Sjkim * WalkState - Current method state 68667754Smsmith * 68767754Smsmith * RETURN: Status 68867754Smsmith * 68967754Smsmith * DESCRIPTION: Create a new bank field in the specified operation region 69067754Smsmith * 69167754Smsmith ******************************************************************************/ 69267754Smsmith 69367754SmsmithACPI_STATUS 69467754SmsmithAcpiDsCreateBankField ( 69567754Smsmith ACPI_PARSE_OBJECT *Op, 69667754Smsmith ACPI_NAMESPACE_NODE *RegionNode, 69767754Smsmith ACPI_WALK_STATE *WalkState) 69867754Smsmith{ 69999679Siwasaki ACPI_STATUS Status; 70067754Smsmith ACPI_PARSE_OBJECT *Arg; 70185756Smsmith ACPI_CREATE_FIELD_INFO Info; 70267754Smsmith 70367754Smsmith 704167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op); 70567754Smsmith 70667754Smsmith 70785756Smsmith /* First arg is the name of the parent OpRegion (must already exist) */ 70867754Smsmith 70999679Siwasaki Arg = Op->Common.Value.Arg; 71067754Smsmith if (!RegionNode) 71167754Smsmith { 71299679Siwasaki Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name, 71391116Smsmith ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE, 71491116Smsmith ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode); 715235945Sjkim#ifdef ACPI_ASL_COMPILER 716235945Sjkim Status = AcpiDsCreateExternalRegion (Status, Arg, 717235945Sjkim Arg->Common.Value.Name, WalkState, &RegionNode); 718235945Sjkim#endif 71967754Smsmith if (ACPI_FAILURE (Status)) 72067754Smsmith { 721167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status); 72267754Smsmith return_ACPI_STATUS (Status); 72367754Smsmith } 72467754Smsmith } 72567754Smsmith 726107325Siwasaki /* Second arg is the Bank Register (Field) (must already exist) */ 72767754Smsmith 72899679Siwasaki Arg = Arg->Common.Next; 72999679Siwasaki Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 730107325Siwasaki ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 73191116Smsmith ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode); 73267754Smsmith if (ACPI_FAILURE (Status)) 73367754Smsmith { 734167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 73567754Smsmith return_ACPI_STATUS (Status); 73667754Smsmith } 73767754Smsmith 738193267Sjkim /* 739193267Sjkim * Third arg is the BankValue 740193267Sjkim * This arg is a TermArg, not a constant 741193267Sjkim * It will be evaluated later, by AcpiDsEvalBankFieldOperands 742193267Sjkim */ 74399679Siwasaki Arg = Arg->Common.Next; 74467754Smsmith 74585756Smsmith /* Fourth arg is the field flags */ 74667754Smsmith 74799679Siwasaki Arg = Arg->Common.Next; 748117521Snjl Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 74967754Smsmith 75067754Smsmith /* Each remaining arg is a Named Field */ 75167754Smsmith 752107325Siwasaki Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD; 75385756Smsmith Info.RegionNode = RegionNode; 75467754Smsmith 755193267Sjkim /* 756193267Sjkim * Use Info.DataRegisterNode to store BankField Op 757193267Sjkim * It's safe because DataRegisterNode will never be used when create bank field 758193267Sjkim * We store AmlStart and AmlLength in the BankField Op for late evaluation 759193267Sjkim * Used in AcpiExPrepFieldValue(Info) 760193267Sjkim * 761193267Sjkim * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like "void *ParentOp"? 762193267Sjkim */ 763193267Sjkim Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op; 764193267Sjkim 76599679Siwasaki Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 76667754Smsmith return_ACPI_STATUS (Status); 76767754Smsmith} 76867754Smsmith 76967754Smsmith 77067754Smsmith/******************************************************************************* 77167754Smsmith * 77267754Smsmith * FUNCTION: AcpiDsCreateIndexField 77367754Smsmith * 77467754Smsmith * PARAMETERS: Op - Op containing the Field definition and args 77577424Smsmith * RegionNode - Object for the containing Operation Region 77677424Smsmith * ` WalkState - Current method state 77767754Smsmith * 77867754Smsmith * RETURN: Status 77967754Smsmith * 78067754Smsmith * DESCRIPTION: Create a new index field in the specified operation region 78167754Smsmith * 78267754Smsmith ******************************************************************************/ 78367754Smsmith 78467754SmsmithACPI_STATUS 78567754SmsmithAcpiDsCreateIndexField ( 78667754Smsmith ACPI_PARSE_OBJECT *Op, 78777424Smsmith ACPI_NAMESPACE_NODE *RegionNode, 78867754Smsmith ACPI_WALK_STATE *WalkState) 78967754Smsmith{ 79067754Smsmith ACPI_STATUS Status; 79167754Smsmith ACPI_PARSE_OBJECT *Arg; 79285756Smsmith ACPI_CREATE_FIELD_INFO Info; 79367754Smsmith 79467754Smsmith 795167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op); 79667754Smsmith 79767754Smsmith 79885756Smsmith /* First arg is the name of the Index register (must already exist) */ 79985756Smsmith 80099679Siwasaki Arg = Op->Common.Value.Arg; 80199679Siwasaki Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 80291116Smsmith ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 80391116Smsmith ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode); 80467754Smsmith if (ACPI_FAILURE (Status)) 80567754Smsmith { 806167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 80767754Smsmith return_ACPI_STATUS (Status); 80867754Smsmith } 80967754Smsmith 81085756Smsmith /* Second arg is the data register (must already exist) */ 81167754Smsmith 81299679Siwasaki Arg = Arg->Common.Next; 81399679Siwasaki Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 814107325Siwasaki ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 81591116Smsmith ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode); 81667754Smsmith if (ACPI_FAILURE (Status)) 81767754Smsmith { 818167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 81967754Smsmith return_ACPI_STATUS (Status); 82067754Smsmith } 82167754Smsmith 82267754Smsmith /* Next arg is the field flags */ 82367754Smsmith 82499679Siwasaki Arg = Arg->Common.Next; 825117521Snjl Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 82667754Smsmith 82767754Smsmith /* Each remaining arg is a Named Field */ 82867754Smsmith 829107325Siwasaki Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD; 83085756Smsmith Info.RegionNode = RegionNode; 83167754Smsmith 83299679Siwasaki Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 83367754Smsmith return_ACPI_STATUS (Status); 83467754Smsmith} 835