dsfield.c revision 229989
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: dsfield - Dispatcher field routines 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8229989Sjkim * Copyright (C) 2000 - 2012, 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 60151937Sjkimstatic ACPI_STATUS 61151937SjkimAcpiDsGetFieldNames ( 62151937Sjkim ACPI_CREATE_FIELD_INFO *Info, 63151937Sjkim ACPI_WALK_STATE *WalkState, 64151937Sjkim ACPI_PARSE_OBJECT *Arg); 65151937Sjkim 66151937Sjkim 6767754Smsmith/******************************************************************************* 6867754Smsmith * 6985756Smsmith * FUNCTION: AcpiDsCreateBufferField 7067754Smsmith * 71151937Sjkim * PARAMETERS: Op - Current parse op (CreateXXField) 7285756Smsmith * WalkState - Current state 7367754Smsmith * 7467754Smsmith * RETURN: Status 7567754Smsmith * 7687031Smsmith * DESCRIPTION: Execute the CreateField operators: 7785756Smsmith * CreateBitFieldOp, 7887031Smsmith * CreateByteFieldOp, 7987031Smsmith * CreateWordFieldOp, 8085756Smsmith * CreateDWordFieldOp, 8185756Smsmith * CreateQWordFieldOp, 82151937Sjkim * CreateFieldOp (all of which define a field in a buffer) 8367754Smsmith * 8467754Smsmith ******************************************************************************/ 8567754Smsmith 8667754SmsmithACPI_STATUS 8785756SmsmithAcpiDsCreateBufferField ( 8867754Smsmith ACPI_PARSE_OBJECT *Op, 8967754Smsmith ACPI_WALK_STATE *WalkState) 9067754Smsmith{ 9167754Smsmith ACPI_PARSE_OBJECT *Arg; 9267754Smsmith ACPI_NAMESPACE_NODE *Node; 9385756Smsmith ACPI_STATUS Status; 9485756Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 9587031Smsmith ACPI_OPERAND_OBJECT *SecondDesc = NULL; 9687031Smsmith UINT32 Flags; 9767754Smsmith 9867754Smsmith 99167802Sjkim ACPI_FUNCTION_TRACE (DsCreateBufferField); 10067754Smsmith 10167754Smsmith 102193267Sjkim /* 103193267Sjkim * Get the NameString argument (name of the new BufferField) 104193267Sjkim */ 10599679Siwasaki if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP) 10667754Smsmith { 107193267Sjkim /* For CreateField, name is the 4th argument */ 108193267Sjkim 10985756Smsmith Arg = AcpiPsGetArg (Op, 3); 11067754Smsmith } 11185756Smsmith else 11285756Smsmith { 113193267Sjkim /* For all other CreateXXXField operators, name is the 3rd argument */ 11467754Smsmith 11585756Smsmith Arg = AcpiPsGetArg (Op, 2); 11685756Smsmith } 11767754Smsmith 11885756Smsmith if (!Arg) 11985756Smsmith { 12085756Smsmith return_ACPI_STATUS (AE_AML_NO_OPERAND); 12185756Smsmith } 12267754Smsmith 123123315Snjl if (WalkState->DeferredNode) 12487031Smsmith { 125123315Snjl Node = WalkState->DeferredNode; 126123315Snjl Status = AE_OK; 12787031Smsmith } 12887031Smsmith else 12987031Smsmith { 130193267Sjkim /* Execute flag should always be set when this function is entered */ 131193267Sjkim 132193267Sjkim if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE)) 133123315Snjl { 134193267Sjkim return_ACPI_STATUS (AE_AML_INTERNAL); 135123315Snjl } 136193267Sjkim 137193267Sjkim /* Creating new namespace node, should not already exist */ 138193267Sjkim 139193267Sjkim Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 140193267Sjkim ACPI_NS_ERROR_IF_FOUND; 141193267Sjkim 142197104Sjkim /* 143197104Sjkim * Mark node temporary if we are executing a normal control 144197104Sjkim * method. (Don't mark if this is a module-level code method) 145197104Sjkim */ 146197104Sjkim if (WalkState->MethodNode && 147197104Sjkim !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) 148123315Snjl { 149193267Sjkim Flags |= ACPI_NS_TEMPORARY; 150123315Snjl } 15187031Smsmith 152193267Sjkim /* Enter the NameString into the namespace */ 153193267Sjkim 154123315Snjl Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 155193267Sjkim ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1, 156193267Sjkim Flags, WalkState, &Node); 157123315Snjl if (ACPI_FAILURE (Status)) 158123315Snjl { 159167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 160123315Snjl return_ACPI_STATUS (Status); 161123315Snjl } 16285756Smsmith } 16367754Smsmith 164167802Sjkim /* 165167802Sjkim * We could put the returned object (Node) on the object stack for later, 166151937Sjkim * but for now, we will put it in the "op" object that the parser uses, 167193267Sjkim * so we can get it again at the end of this scope. 16885756Smsmith */ 16999679Siwasaki Op->Common.Node = Node; 17085756Smsmith 17185756Smsmith /* 172151937Sjkim * If there is no object attached to the node, this node was just created 173193267Sjkim * and we need to create the field object. Otherwise, this was a lookup 174151937Sjkim * of an existing node and we don't want to create the field object again. 17585756Smsmith */ 17687031Smsmith ObjDesc = AcpiNsGetAttachedObject (Node); 17787031Smsmith if (ObjDesc) 17885756Smsmith { 17985756Smsmith return_ACPI_STATUS (AE_OK); 18085756Smsmith } 18185756Smsmith 18285756Smsmith /* 18385756Smsmith * The Field definition is not fully parsed at this time. 18485756Smsmith * (We must save the address of the AML for the buffer and index operands) 18585756Smsmith */ 18685756Smsmith 18785756Smsmith /* Create the buffer field object */ 18885756Smsmith 18985756Smsmith ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD); 19085756Smsmith if (!ObjDesc) 19185756Smsmith { 19285756Smsmith Status = AE_NO_MEMORY; 19385756Smsmith goto Cleanup; 19485756Smsmith } 19585756Smsmith 19685756Smsmith /* 197193267Sjkim * Remember location in AML stream of the field unit opcode and operands -- 198193267Sjkim * since the buffer and index operands must be evaluated. 19985756Smsmith */ 20087031Smsmith SecondDesc = ObjDesc->Common.NextObject; 20199679Siwasaki SecondDesc->Extra.AmlStart = Op->Named.Data; 20299679Siwasaki SecondDesc->Extra.AmlLength = Op->Named.Length; 20387031Smsmith ObjDesc->BufferField.Node = Node; 20485756Smsmith 20587031Smsmith /* Attach constructed field descriptors to parent node */ 20685756Smsmith 20785756Smsmith Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD); 20887031Smsmith if (ACPI_FAILURE (Status)) 20987031Smsmith { 21087031Smsmith goto Cleanup; 21187031Smsmith } 21285756Smsmith 21385756Smsmith 21485756SmsmithCleanup: 21585756Smsmith 21685756Smsmith /* Remove local reference to the object */ 21785756Smsmith 21885756Smsmith AcpiUtRemoveReference (ObjDesc); 21985756Smsmith return_ACPI_STATUS (Status); 22085756Smsmith} 22185756Smsmith 22285756Smsmith 22385756Smsmith/******************************************************************************* 22485756Smsmith * 22585756Smsmith * FUNCTION: AcpiDsGetFieldNames 22685756Smsmith * 22785756Smsmith * PARAMETERS: Info - CreateField info structure 22885756Smsmith * ` WalkState - Current method state 22985756Smsmith * Arg - First parser arg for the field name list 23085756Smsmith * 23185756Smsmith * RETURN: Status 23285756Smsmith * 23385756Smsmith * DESCRIPTION: Process all named fields in a field declaration. Names are 23485756Smsmith * entered into the namespace. 23585756Smsmith * 23685756Smsmith ******************************************************************************/ 23785756Smsmith 238151937Sjkimstatic ACPI_STATUS 23985756SmsmithAcpiDsGetFieldNames ( 24085756Smsmith ACPI_CREATE_FIELD_INFO *Info, 24185756Smsmith ACPI_WALK_STATE *WalkState, 24285756Smsmith ACPI_PARSE_OBJECT *Arg) 24385756Smsmith{ 24485756Smsmith ACPI_STATUS Status; 245202771Sjkim UINT64 Position; 246228110Sjkim ACPI_PARSE_OBJECT *Child; 24785756Smsmith 24885756Smsmith 249167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info); 25085756Smsmith 25185756Smsmith 25285756Smsmith /* First field starts at bit zero */ 25385756Smsmith 25485756Smsmith Info->FieldBitPosition = 0; 25585756Smsmith 25685756Smsmith /* Process all elements in the field list (of parse nodes) */ 25785756Smsmith 25867754Smsmith while (Arg) 25967754Smsmith { 26085756Smsmith /* 261228110Sjkim * Four types of field elements are handled: 262228110Sjkim * 1) Name - Enters a new named field into the namespace 263228110Sjkim * 2) Offset - specifies a bit offset 264228110Sjkim * 3) AccessAs - changes the access mode/attributes 265228110Sjkim * 4) Connection - Associate a resource template with the field 26685756Smsmith */ 26799679Siwasaki switch (Arg->Common.AmlOpcode) 26867754Smsmith { 26977424Smsmith case AML_INT_RESERVEDFIELD_OP: 27067754Smsmith 271202771Sjkim Position = (UINT64) Info->FieldBitPosition 272202771Sjkim + (UINT64) Arg->Common.Value.Size; 27399679Siwasaki 27499679Siwasaki if (Position > ACPI_UINT32_MAX) 27591116Smsmith { 276167802Sjkim ACPI_ERROR ((AE_INFO, 277167802Sjkim "Bit offset within field too large (> 0xFFFFFFFF)")); 27891116Smsmith return_ACPI_STATUS (AE_SUPPORT); 27991116Smsmith } 28091116Smsmith 28199679Siwasaki Info->FieldBitPosition = (UINT32) Position; 28267754Smsmith break; 28367754Smsmith 28477424Smsmith case AML_INT_ACCESSFIELD_OP: 285228110Sjkim case AML_INT_EXTACCESSFIELD_OP: 28667754Smsmith /* 287228110Sjkim * Get new AccessType, AccessAttribute, and AccessLength fields 288228110Sjkim * -- to be used for all field units that follow, until the 289228110Sjkim * end-of-field or another AccessAs keyword is encountered. 290228110Sjkim * NOTE. These three bytes are encoded in the integer value 291228110Sjkim * of the parseop for convenience. 29287031Smsmith * 293151937Sjkim * In FieldFlags, preserve the flag bits other than the 294228110Sjkim * ACCESS_TYPE bits. 29567754Smsmith */ 296228110Sjkim 297228110Sjkim /* AccessType (ByteAcc, WordAcc, etc.) */ 298228110Sjkim 299151937Sjkim Info->FieldFlags = (UINT8) 300151937Sjkim ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) | 301228110Sjkim ((UINT8) ((UINT32) (Arg->Common.Value.Integer & 0x07)))); 30287031Smsmith 303228110Sjkim /* AccessAttribute (AttribQuick, AttribByte, etc.) */ 304228110Sjkim 305228110Sjkim Info->Attribute = (UINT8) ((Arg->Common.Value.Integer >> 8) & 0xFF); 306228110Sjkim 307228110Sjkim /* AccessLength (for serial/buffer protocols) */ 308228110Sjkim 309228110Sjkim Info->AccessLength = (UINT8) ((Arg->Common.Value.Integer >> 16) & 0xFF); 31067754Smsmith break; 31167754Smsmith 312228110Sjkim case AML_INT_CONNECTION_OP: 313228110Sjkim /* 314228110Sjkim * Clear any previous connection. New connection is used for all 315228110Sjkim * fields that follow, similar to AccessAs 316228110Sjkim */ 317228110Sjkim Info->ResourceBuffer = NULL; 318228110Sjkim Info->ConnectionNode = NULL; 31967754Smsmith 320228110Sjkim /* 321228110Sjkim * A Connection() is either an actual resource descriptor (buffer) 322228110Sjkim * or a named reference to a resource template 323228110Sjkim */ 324228110Sjkim Child = Arg->Common.Value.Arg; 325228110Sjkim if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP) 326228110Sjkim { 327228110Sjkim Info->ResourceBuffer = Child->Named.Data; 328228110Sjkim Info->ResourceLength = (UINT16) Child->Named.Value.Integer; 329228110Sjkim } 330228110Sjkim else 331228110Sjkim { 332228110Sjkim /* Lookup the Connection() namepath, it should already exist */ 333228110Sjkim 334228110Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, 335228110Sjkim Child->Common.Value.Name, ACPI_TYPE_ANY, 336228110Sjkim ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE, 337228110Sjkim WalkState, &Info->ConnectionNode); 338228110Sjkim if (ACPI_FAILURE (Status)) 339228110Sjkim { 340228110Sjkim ACPI_ERROR_NAMESPACE (Child->Common.Value.Name, Status); 341228110Sjkim return_ACPI_STATUS (Status); 342228110Sjkim } 343228110Sjkim } 344228110Sjkim break; 345228110Sjkim 34677424Smsmith case AML_INT_NAMEDFIELD_OP: 34767754Smsmith 348193267Sjkim /* Lookup the name, it should already exist */ 34985756Smsmith 35067754Smsmith Status = AcpiNsLookup (WalkState->ScopeInfo, 351193267Sjkim (char *) &Arg->Named.Name, Info->FieldType, 352193267Sjkim ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE, 353193267Sjkim WalkState, &Info->FieldNode); 35467754Smsmith if (ACPI_FAILURE (Status)) 35567754Smsmith { 356167802Sjkim ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status); 357193267Sjkim return_ACPI_STATUS (Status); 35867754Smsmith } 35987031Smsmith else 36087031Smsmith { 36199679Siwasaki Arg->Common.Node = Info->FieldNode; 36299679Siwasaki Info->FieldBitLength = Arg->Common.Value.Size; 36367754Smsmith 364193267Sjkim /* 365193267Sjkim * If there is no object attached to the node, this node was 366193267Sjkim * just created and we need to create the field object. 367193267Sjkim * Otherwise, this was a lookup of an existing node and we 368193267Sjkim * don't want to create the field object again. 369193267Sjkim */ 370193267Sjkim if (!AcpiNsGetAttachedObject (Info->FieldNode)) 37187031Smsmith { 372193267Sjkim Status = AcpiExPrepFieldValue (Info); 373193267Sjkim if (ACPI_FAILURE (Status)) 374193267Sjkim { 375193267Sjkim return_ACPI_STATUS (Status); 376193267Sjkim } 37787031Smsmith } 37867754Smsmith } 37967754Smsmith 38085756Smsmith /* Keep track of bit position for the next field */ 38167754Smsmith 382202771Sjkim Position = (UINT64) Info->FieldBitPosition 383202771Sjkim + (UINT64) Arg->Common.Value.Size; 38499679Siwasaki 38599679Siwasaki if (Position > ACPI_UINT32_MAX) 38691116Smsmith { 387167802Sjkim ACPI_ERROR ((AE_INFO, 388167802Sjkim "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)", 389167802Sjkim ACPI_CAST_PTR (char, &Info->FieldNode->Name))); 39091116Smsmith return_ACPI_STATUS (AE_SUPPORT); 39191116Smsmith } 39291116Smsmith 39385756Smsmith Info->FieldBitPosition += Info->FieldBitLength; 39467754Smsmith break; 39585756Smsmith 39685756Smsmith default: 39785756Smsmith 398167802Sjkim ACPI_ERROR ((AE_INFO, 399204773Sjkim "Invalid opcode in field list: 0x%X", Arg->Common.AmlOpcode)); 40099679Siwasaki return_ACPI_STATUS (AE_AML_BAD_OPCODE); 40167754Smsmith } 40267754Smsmith 40399679Siwasaki Arg = Arg->Common.Next; 40467754Smsmith } 40567754Smsmith 40685756Smsmith return_ACPI_STATUS (AE_OK); 40785756Smsmith} 40885756Smsmith 40985756Smsmith 41085756Smsmith/******************************************************************************* 41185756Smsmith * 41285756Smsmith * FUNCTION: AcpiDsCreateField 41385756Smsmith * 41485756Smsmith * PARAMETERS: Op - Op containing the Field definition and args 41585756Smsmith * RegionNode - Object for the containing Operation Region 41685756Smsmith * ` WalkState - Current method state 41785756Smsmith * 41885756Smsmith * RETURN: Status 41985756Smsmith * 42085756Smsmith * DESCRIPTION: Create a new field in the specified operation region 42185756Smsmith * 42285756Smsmith ******************************************************************************/ 42385756Smsmith 42485756SmsmithACPI_STATUS 42585756SmsmithAcpiDsCreateField ( 42685756Smsmith ACPI_PARSE_OBJECT *Op, 42785756Smsmith ACPI_NAMESPACE_NODE *RegionNode, 42885756Smsmith ACPI_WALK_STATE *WalkState) 42985756Smsmith{ 43099679Siwasaki ACPI_STATUS Status; 43185756Smsmith ACPI_PARSE_OBJECT *Arg; 43285756Smsmith ACPI_CREATE_FIELD_INFO Info; 43385756Smsmith 43485756Smsmith 435167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op); 43685756Smsmith 43785756Smsmith 43885756Smsmith /* First arg is the name of the parent OpRegion (must already exist) */ 43985756Smsmith 44099679Siwasaki Arg = Op->Common.Value.Arg; 44185756Smsmith if (!RegionNode) 44285756Smsmith { 44399679Siwasaki Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name, 44491116Smsmith ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE, 44591116Smsmith ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode); 44685756Smsmith if (ACPI_FAILURE (Status)) 44785756Smsmith { 448167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status); 44985756Smsmith return_ACPI_STATUS (Status); 45085756Smsmith } 45185756Smsmith } 45285756Smsmith 453228110Sjkim ACPI_MEMSET (&Info, 0, sizeof (ACPI_CREATE_FIELD_INFO)); 454228110Sjkim 45585756Smsmith /* Second arg is the field flags */ 45685756Smsmith 45799679Siwasaki Arg = Arg->Common.Next; 458117521Snjl Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 45987031Smsmith Info.Attribute = 0; 46085756Smsmith 46185756Smsmith /* Each remaining arg is a Named Field */ 46285756Smsmith 463107325Siwasaki Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD; 46485756Smsmith Info.RegionNode = RegionNode; 46585756Smsmith 46699679Siwasaki Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 46767754Smsmith return_ACPI_STATUS (Status); 46867754Smsmith} 46967754Smsmith 47067754Smsmith 47167754Smsmith/******************************************************************************* 47267754Smsmith * 47387031Smsmith * FUNCTION: AcpiDsInitFieldObjects 47487031Smsmith * 47587031Smsmith * PARAMETERS: Op - Op containing the Field definition and args 47687031Smsmith * ` WalkState - Current method state 47787031Smsmith * 47887031Smsmith * RETURN: Status 47987031Smsmith * 48087031Smsmith * DESCRIPTION: For each "Field Unit" name in the argument list that is 48187031Smsmith * part of the field declaration, enter the name into the 48287031Smsmith * namespace. 48387031Smsmith * 48487031Smsmith ******************************************************************************/ 48587031Smsmith 48687031SmsmithACPI_STATUS 48787031SmsmithAcpiDsInitFieldObjects ( 48887031Smsmith ACPI_PARSE_OBJECT *Op, 48987031Smsmith ACPI_WALK_STATE *WalkState) 49087031Smsmith{ 49199679Siwasaki ACPI_STATUS Status; 49287031Smsmith ACPI_PARSE_OBJECT *Arg = NULL; 49387031Smsmith ACPI_NAMESPACE_NODE *Node; 49487031Smsmith UINT8 Type = 0; 495193267Sjkim UINT32 Flags; 49687031Smsmith 49787031Smsmith 498167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op); 49987031Smsmith 50087031Smsmith 501193267Sjkim /* Execute flag should always be set when this function is entered */ 502193267Sjkim 503193267Sjkim if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE)) 504193267Sjkim { 505193267Sjkim if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP) 506193267Sjkim { 507193267Sjkim /* BankField Op is deferred, just return OK */ 508193267Sjkim 509193267Sjkim return_ACPI_STATUS (AE_OK); 510193267Sjkim } 511193267Sjkim 512193267Sjkim return_ACPI_STATUS (AE_AML_INTERNAL); 513193267Sjkim } 514193267Sjkim 515193267Sjkim /* 516193267Sjkim * Get the FieldList argument for this opcode. This is the start of the 517193267Sjkim * list of field elements. 518193267Sjkim */ 51987031Smsmith switch (WalkState->Opcode) 52087031Smsmith { 52187031Smsmith case AML_FIELD_OP: 52287031Smsmith Arg = AcpiPsGetArg (Op, 2); 523107325Siwasaki Type = ACPI_TYPE_LOCAL_REGION_FIELD; 52487031Smsmith break; 52587031Smsmith 52687031Smsmith case AML_BANK_FIELD_OP: 52787031Smsmith Arg = AcpiPsGetArg (Op, 4); 528107325Siwasaki Type = ACPI_TYPE_LOCAL_BANK_FIELD; 52987031Smsmith break; 53087031Smsmith 53187031Smsmith case AML_INDEX_FIELD_OP: 53287031Smsmith Arg = AcpiPsGetArg (Op, 3); 533107325Siwasaki Type = ACPI_TYPE_LOCAL_INDEX_FIELD; 53487031Smsmith break; 53599679Siwasaki 53699679Siwasaki default: 53799679Siwasaki return_ACPI_STATUS (AE_BAD_PARAMETER); 53887031Smsmith } 53987031Smsmith 540193267Sjkim /* Creating new namespace node(s), should not already exist */ 541193267Sjkim 542193267Sjkim Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 543193267Sjkim ACPI_NS_ERROR_IF_FOUND; 544193267Sjkim 545197104Sjkim /* 546197104Sjkim * Mark node(s) temporary if we are executing a normal control 547197104Sjkim * method. (Don't mark if this is a module-level code method) 548197104Sjkim */ 549197104Sjkim if (WalkState->MethodNode && 550197104Sjkim !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) 551193267Sjkim { 552193267Sjkim Flags |= ACPI_NS_TEMPORARY; 553193267Sjkim } 554193267Sjkim 55587031Smsmith /* 55687031Smsmith * Walk the list of entries in the FieldList 557193267Sjkim * Note: FieldList can be of zero length. In this case, Arg will be NULL. 55887031Smsmith */ 55987031Smsmith while (Arg) 56087031Smsmith { 561193267Sjkim /* 562228110Sjkim * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested 563228110Sjkim * in the field names in order to enter them into the namespace. 564193267Sjkim */ 56599679Siwasaki if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP) 56687031Smsmith { 56787031Smsmith Status = AcpiNsLookup (WalkState->ScopeInfo, 568193267Sjkim (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1, 569193267Sjkim Flags, WalkState, &Node); 57087031Smsmith if (ACPI_FAILURE (Status)) 57187031Smsmith { 572167802Sjkim ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status); 57387031Smsmith if (Status != AE_ALREADY_EXISTS) 57487031Smsmith { 57587031Smsmith return_ACPI_STATUS (Status); 57687031Smsmith } 57787031Smsmith 57899679Siwasaki /* Name already exists, just ignore this error */ 57999679Siwasaki 58099679Siwasaki Status = AE_OK; 58187031Smsmith } 58287031Smsmith 58399679Siwasaki Arg->Common.Node = Node; 58487031Smsmith } 58587031Smsmith 586193267Sjkim /* Get the next field element in the list */ 58787031Smsmith 58899679Siwasaki Arg = Arg->Common.Next; 58987031Smsmith } 59087031Smsmith 59199679Siwasaki return_ACPI_STATUS (AE_OK); 59287031Smsmith} 59387031Smsmith 59487031Smsmith 59587031Smsmith/******************************************************************************* 59687031Smsmith * 59767754Smsmith * FUNCTION: AcpiDsCreateBankField 59867754Smsmith * 59967754Smsmith * PARAMETERS: Op - Op containing the Field definition and args 60077424Smsmith * RegionNode - Object for the containing Operation Region 601193267Sjkim * WalkState - Current method state 60267754Smsmith * 60367754Smsmith * RETURN: Status 60467754Smsmith * 60567754Smsmith * DESCRIPTION: Create a new bank field in the specified operation region 60667754Smsmith * 60767754Smsmith ******************************************************************************/ 60867754Smsmith 60967754SmsmithACPI_STATUS 61067754SmsmithAcpiDsCreateBankField ( 61167754Smsmith ACPI_PARSE_OBJECT *Op, 61267754Smsmith ACPI_NAMESPACE_NODE *RegionNode, 61367754Smsmith ACPI_WALK_STATE *WalkState) 61467754Smsmith{ 61599679Siwasaki ACPI_STATUS Status; 61667754Smsmith ACPI_PARSE_OBJECT *Arg; 61785756Smsmith ACPI_CREATE_FIELD_INFO Info; 61867754Smsmith 61967754Smsmith 620167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op); 62167754Smsmith 62267754Smsmith 62385756Smsmith /* First arg is the name of the parent OpRegion (must already exist) */ 62467754Smsmith 62599679Siwasaki Arg = Op->Common.Value.Arg; 62667754Smsmith if (!RegionNode) 62767754Smsmith { 62899679Siwasaki Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name, 62991116Smsmith ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE, 63091116Smsmith ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode); 63167754Smsmith if (ACPI_FAILURE (Status)) 63267754Smsmith { 633167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status); 63467754Smsmith return_ACPI_STATUS (Status); 63567754Smsmith } 63667754Smsmith } 63767754Smsmith 638107325Siwasaki /* Second arg is the Bank Register (Field) (must already exist) */ 63967754Smsmith 64099679Siwasaki Arg = Arg->Common.Next; 64199679Siwasaki Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 642107325Siwasaki ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 64391116Smsmith ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode); 64467754Smsmith if (ACPI_FAILURE (Status)) 64567754Smsmith { 646167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 64767754Smsmith return_ACPI_STATUS (Status); 64867754Smsmith } 64967754Smsmith 650193267Sjkim /* 651193267Sjkim * Third arg is the BankValue 652193267Sjkim * This arg is a TermArg, not a constant 653193267Sjkim * It will be evaluated later, by AcpiDsEvalBankFieldOperands 654193267Sjkim */ 65599679Siwasaki Arg = Arg->Common.Next; 65667754Smsmith 65785756Smsmith /* Fourth arg is the field flags */ 65867754Smsmith 65999679Siwasaki Arg = Arg->Common.Next; 660117521Snjl Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 66167754Smsmith 66267754Smsmith /* Each remaining arg is a Named Field */ 66367754Smsmith 664107325Siwasaki Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD; 66585756Smsmith Info.RegionNode = RegionNode; 66667754Smsmith 667193267Sjkim /* 668193267Sjkim * Use Info.DataRegisterNode to store BankField Op 669193267Sjkim * It's safe because DataRegisterNode will never be used when create bank field 670193267Sjkim * We store AmlStart and AmlLength in the BankField Op for late evaluation 671193267Sjkim * Used in AcpiExPrepFieldValue(Info) 672193267Sjkim * 673193267Sjkim * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like "void *ParentOp"? 674193267Sjkim */ 675193267Sjkim Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op; 676193267Sjkim 67799679Siwasaki Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 67867754Smsmith return_ACPI_STATUS (Status); 67967754Smsmith} 68067754Smsmith 68167754Smsmith 68267754Smsmith/******************************************************************************* 68367754Smsmith * 68467754Smsmith * FUNCTION: AcpiDsCreateIndexField 68567754Smsmith * 68667754Smsmith * PARAMETERS: Op - Op containing the Field definition and args 68777424Smsmith * RegionNode - Object for the containing Operation Region 68877424Smsmith * ` WalkState - Current method state 68967754Smsmith * 69067754Smsmith * RETURN: Status 69167754Smsmith * 69267754Smsmith * DESCRIPTION: Create a new index field in the specified operation region 69367754Smsmith * 69467754Smsmith ******************************************************************************/ 69567754Smsmith 69667754SmsmithACPI_STATUS 69767754SmsmithAcpiDsCreateIndexField ( 69867754Smsmith ACPI_PARSE_OBJECT *Op, 69977424Smsmith ACPI_NAMESPACE_NODE *RegionNode, 70067754Smsmith ACPI_WALK_STATE *WalkState) 70167754Smsmith{ 70267754Smsmith ACPI_STATUS Status; 70367754Smsmith ACPI_PARSE_OBJECT *Arg; 70485756Smsmith ACPI_CREATE_FIELD_INFO Info; 70567754Smsmith 70667754Smsmith 707167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op); 70867754Smsmith 70967754Smsmith 71085756Smsmith /* First arg is the name of the Index register (must already exist) */ 71185756Smsmith 71299679Siwasaki Arg = Op->Common.Value.Arg; 71399679Siwasaki Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 71491116Smsmith ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 71591116Smsmith ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode); 71667754Smsmith if (ACPI_FAILURE (Status)) 71767754Smsmith { 718167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 71967754Smsmith return_ACPI_STATUS (Status); 72067754Smsmith } 72167754Smsmith 72285756Smsmith /* Second arg is the data register (must already exist) */ 72367754Smsmith 72499679Siwasaki Arg = Arg->Common.Next; 72599679Siwasaki Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 726107325Siwasaki ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 72791116Smsmith ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode); 72867754Smsmith if (ACPI_FAILURE (Status)) 72967754Smsmith { 730167802Sjkim ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 73167754Smsmith return_ACPI_STATUS (Status); 73267754Smsmith } 73367754Smsmith 73467754Smsmith /* Next arg is the field flags */ 73567754Smsmith 73699679Siwasaki Arg = Arg->Common.Next; 737117521Snjl Info.FieldFlags = (UINT8) Arg->Common.Value.Integer; 73867754Smsmith 73967754Smsmith /* Each remaining arg is a Named Field */ 74067754Smsmith 741107325Siwasaki Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD; 74285756Smsmith Info.RegionNode = RegionNode; 74367754Smsmith 74499679Siwasaki Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next); 74567754Smsmith return_ACPI_STATUS (Status); 74667754Smsmith} 74767754Smsmith 74867754Smsmith 749