167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: dsfield - Dispatcher field routines 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, 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 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 47193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 48193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 50193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 5167754Smsmith 5267754Smsmith 5377424Smsmith#define _COMPONENT ACPI_DISPATCHER 5491116Smsmith ACPI_MODULE_NAME ("dsfield") 5567754Smsmith 56151937Sjkim/* Local prototypes */ 5767754Smsmith 58235945Sjkim#ifdef ACPI_ASL_COMPILER 59235945Sjkim#include <contrib/dev/acpica/include/acdisasm.h> 60235945Sjkim 61151937Sjkimstatic ACPI_STATUS 62235945SjkimAcpiDsCreateExternalRegion ( 63235945Sjkim ACPI_STATUS LookupStatus, 64235945Sjkim ACPI_PARSE_OBJECT *Op, 65235945Sjkim char *Path, 66235945Sjkim ACPI_WALK_STATE *WalkState, 67235945Sjkim ACPI_NAMESPACE_NODE **Node); 68235945Sjkim#endif 69235945Sjkim 70235945Sjkimstatic ACPI_STATUS 71151937SjkimAcpiDsGetFieldNames ( 72151937Sjkim ACPI_CREATE_FIELD_INFO *Info, 73151937Sjkim ACPI_WALK_STATE *WalkState, 74151937Sjkim ACPI_PARSE_OBJECT *Arg); 75151937Sjkim 76151937Sjkim 77235945Sjkim#ifdef ACPI_ASL_COMPILER 7867754Smsmith/******************************************************************************* 7967754Smsmith * 80235945Sjkim * FUNCTION: AcpiDsCreateExternalRegion (iASL Disassembler only) 81235945Sjkim * 82235945Sjkim * PARAMETERS: LookupStatus - Status from NsLookup operation 83235945Sjkim * Op - Op containing the Field definition and args 84235945Sjkim * Path - Pathname of the region 85235945Sjkim * ` WalkState - Current method state 86235945Sjkim * Node - Where the new region node is returned 87235945Sjkim * 88235945Sjkim * RETURN: Status 89235945Sjkim * 90235945Sjkim * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new 91235945Sjkim * region node/object. 92235945Sjkim * 93235945Sjkim ******************************************************************************/ 94235945Sjkim 95235945Sjkimstatic ACPI_STATUS 96235945SjkimAcpiDsCreateExternalRegion ( 97235945Sjkim ACPI_STATUS LookupStatus, 98235945Sjkim ACPI_PARSE_OBJECT *Op, 99235945Sjkim char *Path, 100235945Sjkim ACPI_WALK_STATE *WalkState, 101235945Sjkim ACPI_NAMESPACE_NODE **Node) 102235945Sjkim{ 103235945Sjkim ACPI_STATUS Status; 104235945Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 105235945Sjkim 106235945Sjkim 107235945Sjkim if (LookupStatus != AE_NOT_FOUND) 108235945Sjkim { 109235945Sjkim return (LookupStatus); 110235945Sjkim } 111235945Sjkim 112235945Sjkim /* 113235945Sjkim * Table disassembly: 114235945Sjkim * OperationRegion not found. Generate an External for it, and 115235945Sjkim * insert the name into the namespace. 116235945Sjkim */ 117281075Sdim AcpiDmAddOpToExternalList (Op, Path, ACPI_TYPE_REGION, 0, 0); 118306536Sjkim 119235945Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_REGION, 120235945Sjkim ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, WalkState, Node); 121235945Sjkim if (ACPI_FAILURE (Status)) 122235945Sjkim { 123235945Sjkim return (Status); 124235945Sjkim } 125235945Sjkim 126235945Sjkim /* Must create and install a region object for the new node */ 127235945Sjkim 128235945Sjkim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION); 129235945Sjkim if (!ObjDesc) 130235945Sjkim { 131235945Sjkim return (AE_NO_MEMORY); 132235945Sjkim } 133235945Sjkim 134235945Sjkim ObjDesc->Region.Node = *Node; 135235945Sjkim Status = AcpiNsAttachObject (*Node, ObjDesc, ACPI_TYPE_REGION); 136235945Sjkim return (Status); 137235945Sjkim} 138235945Sjkim#endif 139235945Sjkim 140235945Sjkim 141235945Sjkim/******************************************************************************* 142235945Sjkim * 14385756Smsmith * FUNCTION: AcpiDsCreateBufferField 14467754Smsmith * 145151937Sjkim * PARAMETERS: Op - Current parse op (CreateXXField) 14685756Smsmith * WalkState - Current state 14767754Smsmith * 14867754Smsmith * RETURN: Status 14967754Smsmith * 15087031Smsmith * DESCRIPTION: Execute the CreateField operators: 15185756Smsmith * CreateBitFieldOp, 15287031Smsmith * CreateByteFieldOp, 15387031Smsmith * CreateWordFieldOp, 154237412Sjkim * CreateDwordFieldOp, 155237412Sjkim * CreateQwordFieldOp, 156151937Sjkim * CreateFieldOp (all of which define a field in a buffer) 15767754Smsmith * 15867754Smsmith ******************************************************************************/ 15967754Smsmith 16067754SmsmithACPI_STATUS 16185756SmsmithAcpiDsCreateBufferField ( 16267754Smsmith ACPI_PARSE_OBJECT *Op, 16367754Smsmith ACPI_WALK_STATE *WalkState) 16467754Smsmith{ 16567754Smsmith ACPI_PARSE_OBJECT *Arg; 16667754Smsmith ACPI_NAMESPACE_NODE *Node; 16785756Smsmith ACPI_STATUS Status; 16885756Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 16987031Smsmith ACPI_OPERAND_OBJECT *SecondDesc = NULL; 17087031Smsmith UINT32 Flags; 17167754Smsmith 17267754Smsmith 173167802Sjkim ACPI_FUNCTION_TRACE (DsCreateBufferField); 17467754Smsmith 17567754Smsmith 176193267Sjkim /* 177193267Sjkim * Get the NameString argument (name of the new BufferField) 178193267Sjkim */ 17999679Siwasaki if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP) 18067754Smsmith { 181193267Sjkim /* For CreateField, name is the 4th argument */ 182193267Sjkim 18385756Smsmith Arg = AcpiPsGetArg (Op, 3); 18467754Smsmith } 18585756Smsmith else 18685756Smsmith { 187193267Sjkim /* For all other CreateXXXField operators, name is the 3rd argument */ 18867754Smsmith 18985756Smsmith Arg = AcpiPsGetArg (Op, 2); 19085756Smsmith } 19167754Smsmith 19285756Smsmith if (!Arg) 19385756Smsmith { 19485756Smsmith return_ACPI_STATUS (AE_AML_NO_OPERAND); 19585756Smsmith } 19667754Smsmith 197123315Snjl if (WalkState->DeferredNode) 19887031Smsmith { 199123315Snjl Node = WalkState->DeferredNode; 200123315Snjl Status = AE_OK; 20187031Smsmith } 20287031Smsmith else 20387031Smsmith { 204193267Sjkim /* Execute flag should always be set when this function is entered */ 205193267Sjkim 206193267Sjkim if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE)) 207123315Snjl { 208193267Sjkim return_ACPI_STATUS (AE_AML_INTERNAL); 209123315Snjl } 210193267Sjkim 211193267Sjkim /* Creating new namespace node, should not already exist */ 212193267Sjkim 213193267Sjkim Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 214306536Sjkim ACPI_NS_ERROR_IF_FOUND; 215193267Sjkim 216197104Sjkim /* 217197104Sjkim * Mark node temporary if we are executing a normal control 218197104Sjkim * method. (Don't mark if this is a module-level code method) 219197104Sjkim */ 220197104Sjkim if (WalkState->MethodNode && 221197104Sjkim !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) 222123315Snjl { 223193267Sjkim Flags |= ACPI_NS_TEMPORARY; 224123315Snjl } 22587031Smsmith 226193267Sjkim /* Enter the NameString into the namespace */ 227193267Sjkim 228306536Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, 229306536Sjkim Arg->Common.Value.String, ACPI_TYPE_ANY, 230306536Sjkim ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); 231123315Snjl if (ACPI_FAILURE (Status)) 232123315Snjl { 233167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 234123315Snjl return_ACPI_STATUS (Status); 235123315Snjl } 23685756Smsmith } 23767754Smsmith 238167802Sjkim /* 239167802Sjkim * We could put the returned object (Node) on the object stack for later, 240151937Sjkim * but for now, we will put it in the "op" object that the parser uses, 241193267Sjkim * so we can get it again at the end of this scope. 24285756Smsmith */ 24399679Siwasaki Op->Common.Node = Node; 24485756Smsmith 24585756Smsmith /* 246151937Sjkim * If there is no object attached to the node, this node was just created 247193267Sjkim * and we need to create the field object. Otherwise, this was a lookup 248151937Sjkim * of an existing node and we don't want to create the field object again. 24985756Smsmith */ 25087031Smsmith ObjDesc = AcpiNsGetAttachedObject (Node); 25187031Smsmith if (ObjDesc) 25285756Smsmith { 25385756Smsmith return_ACPI_STATUS (AE_OK); 25485756Smsmith } 25585756Smsmith 25685756Smsmith /* 25785756Smsmith * The Field definition is not fully parsed at this time. 25885756Smsmith * (We must save the address of the AML for the buffer and index operands) 25985756Smsmith */ 26085756Smsmith 26185756Smsmith /* Create the buffer field object */ 26285756Smsmith 26385756Smsmith ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD); 26485756Smsmith if (!ObjDesc) 26585756Smsmith { 26685756Smsmith Status = AE_NO_MEMORY; 26785756Smsmith goto Cleanup; 26885756Smsmith } 26985756Smsmith 27085756Smsmith /* 271306536Sjkim * Remember location in AML stream of the field unit opcode and operands 272306536Sjkim * -- since the buffer and index operands must be evaluated. 27385756Smsmith */ 274306536Sjkim SecondDesc = ObjDesc->Common.NextObject; 275306536Sjkim SecondDesc->Extra.AmlStart = Op->Named.Data; 27699679Siwasaki SecondDesc->Extra.AmlLength = Op->Named.Length; 277306536Sjkim ObjDesc->BufferField.Node = Node; 27885756Smsmith 27987031Smsmith /* Attach constructed field descriptors to parent node */ 28085756Smsmith 28185756Smsmith Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD); 28287031Smsmith if (ACPI_FAILURE (Status)) 28387031Smsmith { 28487031Smsmith goto Cleanup; 28587031Smsmith } 28685756Smsmith 28785756Smsmith 28885756SmsmithCleanup: 28985756Smsmith 29085756Smsmith /* Remove local reference to the object */ 29185756Smsmith 29285756Smsmith AcpiUtRemoveReference (ObjDesc); 29385756Smsmith return_ACPI_STATUS (Status); 29485756Smsmith} 29585756Smsmith 29685756Smsmith 29785756Smsmith/******************************************************************************* 29885756Smsmith * 29985756Smsmith * FUNCTION: AcpiDsGetFieldNames 30085756Smsmith * 30185756Smsmith * PARAMETERS: Info - CreateField info structure 30285756Smsmith * ` WalkState - Current method state 30385756Smsmith * Arg - First parser arg for the field name list 30485756Smsmith * 30585756Smsmith * RETURN: Status 30685756Smsmith * 307241973Sjkim * DESCRIPTION: Process all named fields in a field declaration. Names are 30885756Smsmith * entered into the namespace. 30985756Smsmith * 31085756Smsmith ******************************************************************************/ 31185756Smsmith 312151937Sjkimstatic ACPI_STATUS 31385756SmsmithAcpiDsGetFieldNames ( 31485756Smsmith ACPI_CREATE_FIELD_INFO *Info, 31585756Smsmith ACPI_WALK_STATE *WalkState, 31685756Smsmith ACPI_PARSE_OBJECT *Arg) 31785756Smsmith{ 31885756Smsmith ACPI_STATUS Status; 319202771Sjkim UINT64 Position; 320228110Sjkim ACPI_PARSE_OBJECT *Child; 32185756Smsmith 32285756Smsmith 323167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info); 32485756Smsmith 32585756Smsmith 32685756Smsmith /* First field starts at bit zero */ 32785756Smsmith 32885756Smsmith Info->FieldBitPosition = 0; 32985756Smsmith 33085756Smsmith /* Process all elements in the field list (of parse nodes) */ 33185756Smsmith 33267754Smsmith while (Arg) 33367754Smsmith { 33485756Smsmith /* 335228110Sjkim * Four types of field elements are handled: 336228110Sjkim * 1) Name - Enters a new named field into the namespace 337228110Sjkim * 2) Offset - specifies a bit offset 338228110Sjkim * 3) AccessAs - changes the access mode/attributes 339228110Sjkim * 4) Connection - Associate a resource template with the field 34085756Smsmith */ 34199679Siwasaki switch (Arg->Common.AmlOpcode) 34267754Smsmith { 34377424Smsmith case AML_INT_RESERVEDFIELD_OP: 34467754Smsmith 345306536Sjkim Position = (UINT64) Info->FieldBitPosition + 346306536Sjkim (UINT64) Arg->Common.Value.Size; 34799679Siwasaki 34899679Siwasaki if (Position > ACPI_UINT32_MAX) 34991116Smsmith { 350167802Sjkim ACPI_ERROR ((AE_INFO, 351167802Sjkim "Bit offset within field too large (> 0xFFFFFFFF)")); 35291116Smsmith return_ACPI_STATUS (AE_SUPPORT); 35391116Smsmith } 35491116Smsmith 35599679Siwasaki Info->FieldBitPosition = (UINT32) Position; 35667754Smsmith break; 35767754Smsmith 35877424Smsmith case AML_INT_ACCESSFIELD_OP: 359228110Sjkim case AML_INT_EXTACCESSFIELD_OP: 36067754Smsmith /* 361228110Sjkim * Get new AccessType, AccessAttribute, and AccessLength fields 362228110Sjkim * -- to be used for all field units that follow, until the 363228110Sjkim * end-of-field or another AccessAs keyword is encountered. 364228110Sjkim * NOTE. These three bytes are encoded in the integer value 365228110Sjkim * of the parseop for convenience. 36687031Smsmith * 367151937Sjkim * In FieldFlags, preserve the flag bits other than the 368228110Sjkim * ACCESS_TYPE bits. 36967754Smsmith */ 370228110Sjkim 371228110Sjkim /* AccessType (ByteAcc, WordAcc, etc.) */ 372228110Sjkim 373151937Sjkim Info->FieldFlags = (UINT8) 374151937Sjkim ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) | 375228110Sjkim ((UINT8) ((UINT32) (Arg->Common.Value.Integer & 0x07)))); 37687031Smsmith 377228110Sjkim /* AccessAttribute (AttribQuick, AttribByte, etc.) */ 378228110Sjkim 379306536Sjkim Info->Attribute = (UINT8) 380306536Sjkim ((Arg->Common.Value.Integer >> 8) & 0xFF); 381228110Sjkim 382228110Sjkim /* AccessLength (for serial/buffer protocols) */ 383228110Sjkim 384306536Sjkim Info->AccessLength = (UINT8) 385306536Sjkim ((Arg->Common.Value.Integer >> 16) & 0xFF); 38667754Smsmith break; 38767754Smsmith 388228110Sjkim case AML_INT_CONNECTION_OP: 389228110Sjkim /* 390228110Sjkim * Clear any previous connection. New connection is used for all 391228110Sjkim * fields that follow, similar to AccessAs 392228110Sjkim */ 393228110Sjkim Info->ResourceBuffer = NULL; 394228110Sjkim Info->ConnectionNode = NULL; 395281075Sdim Info->PinNumberIndex = 0; 39667754Smsmith 397228110Sjkim /* 398228110Sjkim * A Connection() is either an actual resource descriptor (buffer) 399228110Sjkim * or a named reference to a resource template 400228110Sjkim */ 401228110Sjkim Child = Arg->Common.Value.Arg; 402228110Sjkim if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP) 403228110Sjkim { 404228110Sjkim Info->ResourceBuffer = Child->Named.Data; 405228110Sjkim Info->ResourceLength = (UINT16) Child->Named.Value.Integer; 406228110Sjkim } 407228110Sjkim else 408228110Sjkim { 409228110Sjkim /* Lookup the Connection() namepath, it should already exist */ 410228110Sjkim 411228110Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, 412306536Sjkim Child->Common.Value.Name, ACPI_TYPE_ANY, 413306536Sjkim ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE, 414306536Sjkim WalkState, &Info->ConnectionNode); 415228110Sjkim if (ACPI_FAILURE (Status)) 416228110Sjkim { 417228110Sjkim ACPI_ERROR_NAMESPACE (Child->Common.Value.Name, Status); 418228110Sjkim return_ACPI_STATUS (Status); 419228110Sjkim } 420228110Sjkim } 421228110Sjkim break; 422228110Sjkim 42377424Smsmith case AML_INT_NAMEDFIELD_OP: 42467754Smsmith 425193267Sjkim /* Lookup the name, it should already exist */ 42685756Smsmith 42767754Smsmith Status = AcpiNsLookup (WalkState->ScopeInfo, 428306536Sjkim (char *) &Arg->Named.Name, Info->FieldType, 429306536Sjkim ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE, 430306536Sjkim WalkState, &Info->FieldNode); 43167754Smsmith if (ACPI_FAILURE (Status)) 43267754Smsmith { 433167802Sjkim ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status); 434193267Sjkim return_ACPI_STATUS (Status); 43567754Smsmith } 43687031Smsmith else 43787031Smsmith { 43899679Siwasaki Arg->Common.Node = Info->FieldNode; 43999679Siwasaki Info->FieldBitLength = Arg->Common.Value.Size; 44067754Smsmith 441193267Sjkim /* 442193267Sjkim * If there is no object attached to the node, this node was 443193267Sjkim * just created and we need to create the field object. 444193267Sjkim * Otherwise, this was a lookup of an existing node and we 445193267Sjkim * don't want to create the field object again. 446193267Sjkim */ 447193267Sjkim if (!AcpiNsGetAttachedObject (Info->FieldNode)) 44887031Smsmith { 449193267Sjkim Status = AcpiExPrepFieldValue (Info); 450193267Sjkim if (ACPI_FAILURE (Status)) 451193267Sjkim { 452193267Sjkim return_ACPI_STATUS (Status); 453193267Sjkim } 45487031Smsmith } 45567754Smsmith } 45667754Smsmith 45785756Smsmith /* Keep track of bit position for the next field */ 45867754Smsmith 459306536Sjkim Position = (UINT64) Info->FieldBitPosition + 460306536Sjkim (UINT64) Arg->Common.Value.Size; 46199679Siwasaki 46299679Siwasaki if (Position > ACPI_UINT32_MAX) 46391116Smsmith { 464167802Sjkim ACPI_ERROR ((AE_INFO, 465167802Sjkim "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)", 466167802Sjkim ACPI_CAST_PTR (char, &Info->FieldNode->Name))); 46791116Smsmith return_ACPI_STATUS (AE_SUPPORT); 46891116Smsmith } 46991116Smsmith 47085756Smsmith Info->FieldBitPosition += Info->FieldBitLength; 471281075Sdim Info->PinNumberIndex++; /* Index relative to previous Connection() */ 47267754Smsmith break; 47385756Smsmith 47485756Smsmith default: 47585756Smsmith 476167802Sjkim ACPI_ERROR ((AE_INFO, 477306536Sjkim "Invalid opcode in field list: 0x%X", 478306536Sjkim Arg->Common.AmlOpcode)); 47999679Siwasaki return_ACPI_STATUS (AE_AML_BAD_OPCODE); 48067754Smsmith } 48167754Smsmith 48299679Siwasaki Arg = Arg->Common.Next; 48367754Smsmith } 48467754Smsmith 48585756Smsmith return_ACPI_STATUS (AE_OK); 48685756Smsmith} 48785756Smsmith 48885756Smsmith 48985756Smsmith/******************************************************************************* 49085756Smsmith * 49185756Smsmith * FUNCTION: AcpiDsCreateField 49285756Smsmith * 49385756Smsmith * PARAMETERS: Op - Op containing the Field definition and args 49485756Smsmith * RegionNode - Object for the containing Operation Region 49585756Smsmith * ` WalkState - Current method state 49685756Smsmith * 49785756Smsmith * RETURN: Status 49885756Smsmith * 49985756Smsmith * DESCRIPTION: Create a new field in the specified operation region 50085756Smsmith * 50185756Smsmith ******************************************************************************/ 50285756Smsmith 50385756SmsmithACPI_STATUS 50485756SmsmithAcpiDsCreateField ( 50585756Smsmith ACPI_PARSE_OBJECT *Op, 50685756Smsmith ACPI_NAMESPACE_NODE *RegionNode, 50785756Smsmith ACPI_WALK_STATE *WalkState) 50885756Smsmith{ 50999679Siwasaki ACPI_STATUS Status; 51085756Smsmith ACPI_PARSE_OBJECT *Arg; 51185756Smsmith ACPI_CREATE_FIELD_INFO Info; 51285756Smsmith 51385756Smsmith 514167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op); 51585756Smsmith 51685756Smsmith 51785756Smsmith /* First arg is the name of the parent OpRegion (must already exist) */ 51885756Smsmith 51999679Siwasaki Arg = Op->Common.Value.Arg; 520235945Sjkim 52185756Smsmith if (!RegionNode) 52285756Smsmith { 52399679Siwasaki Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name, 524306536Sjkim ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE, 525306536Sjkim ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode); 526235945Sjkim#ifdef ACPI_ASL_COMPILER 527235945Sjkim Status = AcpiDsCreateExternalRegion (Status, Arg, 528235945Sjkim Arg->Common.Value.Name, WalkState, &RegionNode); 529235945Sjkim#endif 53085756Smsmith if (ACPI_FAILURE (Status)) 53185756Smsmith { 532167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status); 53385756Smsmith return_ACPI_STATUS (Status); 53485756Smsmith } 53585756Smsmith } 53685756Smsmith 537306536Sjkim memset (&Info, 0, sizeof (ACPI_CREATE_FIELD_INFO)); 538228110Sjkim 53985756Smsmith /* Second arg is the field flags */ 54085756Smsmith 54199679Siwasaki Arg = Arg->Common.Next; 542117521Snjl Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 54387031Smsmith Info.Attribute = 0; 54485756Smsmith 54585756Smsmith /* Each remaining arg is a Named Field */ 54685756Smsmith 547107325Siwasaki Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD; 54885756Smsmith Info.RegionNode = RegionNode; 54985756Smsmith 55099679Siwasaki Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 55167754Smsmith return_ACPI_STATUS (Status); 55267754Smsmith} 55367754Smsmith 55467754Smsmith 55567754Smsmith/******************************************************************************* 55667754Smsmith * 55787031Smsmith * FUNCTION: AcpiDsInitFieldObjects 55887031Smsmith * 55987031Smsmith * PARAMETERS: Op - Op containing the Field definition and args 56087031Smsmith * ` WalkState - Current method state 56187031Smsmith * 56287031Smsmith * RETURN: Status 56387031Smsmith * 56487031Smsmith * DESCRIPTION: For each "Field Unit" name in the argument list that is 56587031Smsmith * part of the field declaration, enter the name into the 56687031Smsmith * namespace. 56787031Smsmith * 56887031Smsmith ******************************************************************************/ 56987031Smsmith 57087031SmsmithACPI_STATUS 57187031SmsmithAcpiDsInitFieldObjects ( 57287031Smsmith ACPI_PARSE_OBJECT *Op, 57387031Smsmith ACPI_WALK_STATE *WalkState) 57487031Smsmith{ 57599679Siwasaki ACPI_STATUS Status; 57687031Smsmith ACPI_PARSE_OBJECT *Arg = NULL; 57787031Smsmith ACPI_NAMESPACE_NODE *Node; 57887031Smsmith UINT8 Type = 0; 579193267Sjkim UINT32 Flags; 58087031Smsmith 58187031Smsmith 582167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op); 58387031Smsmith 58487031Smsmith 585193267Sjkim /* Execute flag should always be set when this function is entered */ 586193267Sjkim 587193267Sjkim if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE)) 588193267Sjkim { 589193267Sjkim if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP) 590193267Sjkim { 591193267Sjkim /* BankField Op is deferred, just return OK */ 592193267Sjkim 593193267Sjkim return_ACPI_STATUS (AE_OK); 594193267Sjkim } 595193267Sjkim 596193267Sjkim return_ACPI_STATUS (AE_AML_INTERNAL); 597193267Sjkim } 598193267Sjkim 599193267Sjkim /* 600193267Sjkim * Get the FieldList argument for this opcode. This is the start of the 601193267Sjkim * list of field elements. 602193267Sjkim */ 60387031Smsmith switch (WalkState->Opcode) 60487031Smsmith { 60587031Smsmith case AML_FIELD_OP: 606250838Sjkim 60787031Smsmith Arg = AcpiPsGetArg (Op, 2); 608107325Siwasaki Type = ACPI_TYPE_LOCAL_REGION_FIELD; 60987031Smsmith break; 61087031Smsmith 61187031Smsmith case AML_BANK_FIELD_OP: 612250838Sjkim 61387031Smsmith Arg = AcpiPsGetArg (Op, 4); 614107325Siwasaki Type = ACPI_TYPE_LOCAL_BANK_FIELD; 61587031Smsmith break; 61687031Smsmith 61787031Smsmith case AML_INDEX_FIELD_OP: 618250838Sjkim 61987031Smsmith Arg = AcpiPsGetArg (Op, 3); 620107325Siwasaki Type = ACPI_TYPE_LOCAL_INDEX_FIELD; 62187031Smsmith break; 62299679Siwasaki 62399679Siwasaki default: 624250838Sjkim 62599679Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 62687031Smsmith } 62787031Smsmith 628193267Sjkim /* Creating new namespace node(s), should not already exist */ 629193267Sjkim 630193267Sjkim Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 631306536Sjkim ACPI_NS_ERROR_IF_FOUND; 632193267Sjkim 633197104Sjkim /* 634197104Sjkim * Mark node(s) temporary if we are executing a normal control 635197104Sjkim * method. (Don't mark if this is a module-level code method) 636197104Sjkim */ 637197104Sjkim if (WalkState->MethodNode && 638197104Sjkim !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) 639193267Sjkim { 640193267Sjkim Flags |= ACPI_NS_TEMPORARY; 641193267Sjkim } 642193267Sjkim 64387031Smsmith /* 64487031Smsmith * Walk the list of entries in the FieldList 645193267Sjkim * Note: FieldList can be of zero length. In this case, Arg will be NULL. 64687031Smsmith */ 64787031Smsmith while (Arg) 64887031Smsmith { 649193267Sjkim /* 650228110Sjkim * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested 651228110Sjkim * in the field names in order to enter them into the namespace. 652193267Sjkim */ 65399679Siwasaki if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP) 65487031Smsmith { 65587031Smsmith Status = AcpiNsLookup (WalkState->ScopeInfo, 656306536Sjkim (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1, 657306536Sjkim Flags, WalkState, &Node); 65887031Smsmith if (ACPI_FAILURE (Status)) 65987031Smsmith { 660167802Sjkim ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status); 66187031Smsmith if (Status != AE_ALREADY_EXISTS) 66287031Smsmith { 66387031Smsmith return_ACPI_STATUS (Status); 66487031Smsmith } 66587031Smsmith 66699679Siwasaki /* Name already exists, just ignore this error */ 66799679Siwasaki 66899679Siwasaki Status = AE_OK; 66987031Smsmith } 67087031Smsmith 67199679Siwasaki Arg->Common.Node = Node; 67287031Smsmith } 67387031Smsmith 674193267Sjkim /* Get the next field element in the list */ 67587031Smsmith 67699679Siwasaki Arg = Arg->Common.Next; 67787031Smsmith } 67887031Smsmith 67999679Siwasaki return_ACPI_STATUS (AE_OK); 68087031Smsmith} 68187031Smsmith 68287031Smsmith 68387031Smsmith/******************************************************************************* 68487031Smsmith * 68567754Smsmith * FUNCTION: AcpiDsCreateBankField 68667754Smsmith * 68767754Smsmith * PARAMETERS: Op - Op containing the Field definition and args 68877424Smsmith * RegionNode - Object for the containing Operation Region 689193267Sjkim * WalkState - Current method state 69067754Smsmith * 69167754Smsmith * RETURN: Status 69267754Smsmith * 69367754Smsmith * DESCRIPTION: Create a new bank field in the specified operation region 69467754Smsmith * 69567754Smsmith ******************************************************************************/ 69667754Smsmith 69767754SmsmithACPI_STATUS 69867754SmsmithAcpiDsCreateBankField ( 69967754Smsmith ACPI_PARSE_OBJECT *Op, 70067754Smsmith ACPI_NAMESPACE_NODE *RegionNode, 70167754Smsmith ACPI_WALK_STATE *WalkState) 70267754Smsmith{ 70399679Siwasaki ACPI_STATUS Status; 70467754Smsmith ACPI_PARSE_OBJECT *Arg; 70585756Smsmith ACPI_CREATE_FIELD_INFO Info; 70667754Smsmith 70767754Smsmith 708167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op); 70967754Smsmith 71067754Smsmith 71185756Smsmith /* First arg is the name of the parent OpRegion (must already exist) */ 71267754Smsmith 71399679Siwasaki Arg = Op->Common.Value.Arg; 71467754Smsmith if (!RegionNode) 71567754Smsmith { 71699679Siwasaki Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name, 717306536Sjkim ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE, 718306536Sjkim ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode); 719235945Sjkim#ifdef ACPI_ASL_COMPILER 720235945Sjkim Status = AcpiDsCreateExternalRegion (Status, Arg, 721235945Sjkim Arg->Common.Value.Name, WalkState, &RegionNode); 722235945Sjkim#endif 72367754Smsmith if (ACPI_FAILURE (Status)) 72467754Smsmith { 725167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status); 72667754Smsmith return_ACPI_STATUS (Status); 72767754Smsmith } 72867754Smsmith } 72967754Smsmith 730107325Siwasaki /* Second arg is the Bank Register (Field) (must already exist) */ 73167754Smsmith 73299679Siwasaki Arg = Arg->Common.Next; 73399679Siwasaki Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 734306536Sjkim ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 735306536Sjkim ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode); 73667754Smsmith if (ACPI_FAILURE (Status)) 73767754Smsmith { 738167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 73967754Smsmith return_ACPI_STATUS (Status); 74067754Smsmith } 74167754Smsmith 742193267Sjkim /* 743193267Sjkim * Third arg is the BankValue 744193267Sjkim * This arg is a TermArg, not a constant 745193267Sjkim * It will be evaluated later, by AcpiDsEvalBankFieldOperands 746193267Sjkim */ 74799679Siwasaki Arg = Arg->Common.Next; 74867754Smsmith 74985756Smsmith /* Fourth arg is the field flags */ 75067754Smsmith 75199679Siwasaki Arg = Arg->Common.Next; 752117521Snjl Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 75367754Smsmith 75467754Smsmith /* Each remaining arg is a Named Field */ 75567754Smsmith 756107325Siwasaki Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD; 75785756Smsmith Info.RegionNode = RegionNode; 75867754Smsmith 759193267Sjkim /* 760193267Sjkim * Use Info.DataRegisterNode to store BankField Op 761306536Sjkim * It's safe because DataRegisterNode will never be used when create 762306536Sjkim * bank field \we store AmlStart and AmlLength in the BankField Op for 763306536Sjkim * late evaluation. Used in AcpiExPrepFieldValue(Info) 764193267Sjkim * 765306536Sjkim * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like 766306536Sjkim * "void *ParentOp"? 767193267Sjkim */ 768193267Sjkim Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op; 769193267Sjkim 77099679Siwasaki Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 77167754Smsmith return_ACPI_STATUS (Status); 77267754Smsmith} 77367754Smsmith 77467754Smsmith 77567754Smsmith/******************************************************************************* 77667754Smsmith * 77767754Smsmith * FUNCTION: AcpiDsCreateIndexField 77867754Smsmith * 77967754Smsmith * PARAMETERS: Op - Op containing the Field definition and args 78077424Smsmith * RegionNode - Object for the containing Operation Region 78177424Smsmith * ` WalkState - Current method state 78267754Smsmith * 78367754Smsmith * RETURN: Status 78467754Smsmith * 78567754Smsmith * DESCRIPTION: Create a new index field in the specified operation region 78667754Smsmith * 78767754Smsmith ******************************************************************************/ 78867754Smsmith 78967754SmsmithACPI_STATUS 79067754SmsmithAcpiDsCreateIndexField ( 79167754Smsmith ACPI_PARSE_OBJECT *Op, 79277424Smsmith ACPI_NAMESPACE_NODE *RegionNode, 79367754Smsmith ACPI_WALK_STATE *WalkState) 79467754Smsmith{ 79567754Smsmith ACPI_STATUS Status; 79667754Smsmith ACPI_PARSE_OBJECT *Arg; 79785756Smsmith ACPI_CREATE_FIELD_INFO Info; 79867754Smsmith 79967754Smsmith 800167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op); 80167754Smsmith 80267754Smsmith 80385756Smsmith /* First arg is the name of the Index register (must already exist) */ 80485756Smsmith 80599679Siwasaki Arg = Op->Common.Value.Arg; 80699679Siwasaki Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 807306536Sjkim ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 808306536Sjkim ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode); 80967754Smsmith if (ACPI_FAILURE (Status)) 81067754Smsmith { 811167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 81267754Smsmith return_ACPI_STATUS (Status); 81367754Smsmith } 81467754Smsmith 81585756Smsmith /* Second arg is the data register (must already exist) */ 81667754Smsmith 81799679Siwasaki Arg = Arg->Common.Next; 81899679Siwasaki Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 819306536Sjkim ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 820306536Sjkim ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode); 82167754Smsmith if (ACPI_FAILURE (Status)) 82267754Smsmith { 823167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 82467754Smsmith return_ACPI_STATUS (Status); 82567754Smsmith } 82667754Smsmith 82767754Smsmith /* Next arg is the field flags */ 82867754Smsmith 82999679Siwasaki Arg = Arg->Common.Next; 830117521Snjl Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 83167754Smsmith 83267754Smsmith /* Each remaining arg is a Named Field */ 83367754Smsmith 834107325Siwasaki Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD; 83585756Smsmith Info.RegionNode = RegionNode; 83667754Smsmith 83799679Siwasaki Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 83867754Smsmith return_ACPI_STATUS (Status); 83967754Smsmith} 840