dsfield.c revision 85756
1218885Sdim/****************************************************************************** 2218885Sdim * 3218885Sdim * Module Name: dsfield - Dispatcher field routines 4218885Sdim * $Revision: 46 $ 5218885Sdim * 6218885Sdim *****************************************************************************/ 7218885Sdim 8218885Sdim/****************************************************************************** 9218885Sdim * 10218885Sdim * 1. Copyright Notice 11218885Sdim * 12218885Sdim * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 13218885Sdim * All rights reserved. 14218885Sdim * 15218885Sdim * 2. License 16218885Sdim * 17218885Sdim * 2.1. This is your license from Intel Corp. under its intellectual property 18249423Sdim * rights. You may have additional license terms from the party that provided 19218885Sdim * you this software, covering your right to use that party's intellectual 20239462Sdim * property rights. 21249423Sdim * 22249423Sdim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23249423Sdim * copy of the source code appearing in this file ("Covered Code") an 24218885Sdim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25218885Sdim * base code distributed originally by Intel ("Original Intel Code") to copy, 26218885Sdim * make derivatives, distribute, use and display any portion of the Covered 27276479Sdim * Code in any form, with the right to sublicense such rights; and 28276479Sdim * 29218885Sdim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30218885Sdim * license (with the right to sublicense), under only those claims of Intel 31218885Sdim * patents that are infringed by the Original Intel Code, to make, use, sell, 32296417Sdim * offer to sell, and import the Covered Code and derivative works thereof 33296417Sdim * solely to the minimum extent necessary to exercise the above copyright 34249423Sdim * license, and in no event shall the patent license extend to any additions 35249423Sdim * to or modifications of the Original Intel Code. No other license or right 36249423Sdim * is granted directly or by implication, estoppel or otherwise; 37249423Sdim * 38296417Sdim * The above copyright and patent license is granted only if the following 39249423Sdim * conditions are met: 40218885Sdim * 41249423Sdim * 3. Conditions 42249423Sdim * 43249423Sdim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44249423Sdim * Redistribution of source code of any substantial portion of the Covered 45249423Sdim * Code or modification with rights to further distribute source must include 46249423Sdim * the above Copyright Notice, the above License, this list of Conditions, 47249423Sdim * and the following Disclaimer and Export Compliance provision. In addition, 48249423Sdim * Licensee must cause all Covered Code to which Licensee contributes to 49249423Sdim * contain a file documenting the changes Licensee made to create that Covered 50249423Sdim * Code and the date of any change. Licensee must include in that file the 51249423Sdim * documentation of any changes made by any predecessor Licensee. Licensee 52249423Sdim * must include a prominent statement that the modification is derived, 53249423Sdim * directly or indirectly, from Original Intel Code. 54218885Sdim * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89 * PARTICULAR PURPOSE. 90 * 91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98 * LIMITED REMEDY. 99 * 100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 101 * software or system incorporating such software without first obtaining any 102 * required license or other approval from the U. S. Department of Commerce or 103 * any other agency or department of the United States Government. In the 104 * event Licensee exports any such software from the United States or 105 * re-exports any such software from a foreign destination, Licensee shall 106 * ensure that the distribution and export/re-export of the software is in 107 * compliance with all laws, regulations, orders, or other restrictions of the 108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109 * any of its subsidiaries will export/re-export any technical data, process, 110 * software, or service, directly or indirectly, to any country for which the 111 * United States government or any agency thereof requires an export license, 112 * other governmental approval, or letter of assurance, without first obtaining 113 * such license, approval or letter. 114 * 115 *****************************************************************************/ 116 117#define __DSFIELD_C__ 118 119#include "acpi.h" 120#include "amlcode.h" 121#include "acdispat.h" 122#include "acinterp.h" 123#include "acnamesp.h" 124#include "acparser.h" 125 126 127#define _COMPONENT ACPI_DISPATCHER 128 MODULE_NAME ("dsfield") 129 130 131 132/******************************************************************************* 133 * 134 * FUNCTION: AcpiDsCreateBufferField 135 * 136 * PARAMETERS: Opcode - The opcode to be executed 137 * Operands - List of operands for the opcode 138 * WalkState - Current state 139 * 140 * RETURN: Status 141 * 142 * DESCRIPTION: Execute the CreateField operators: 143 * CreateBitFieldOp, 144 * CreateByteFieldOp, 145 * CreateWordFieldOp, 146 * CreateDWordFieldOp, 147 * CreateQWordFieldOp, 148 * CreateFieldOp (all of which define fields in buffers) 149 * 150 ******************************************************************************/ 151 152ACPI_STATUS 153AcpiDsCreateBufferField ( 154 ACPI_PARSE_OBJECT *Op, 155 ACPI_WALK_STATE *WalkState) 156{ 157 ACPI_PARSE_OBJECT *Arg; 158 ACPI_NAMESPACE_NODE *Node; 159 ACPI_STATUS Status; 160 ACPI_OPERAND_OBJECT *ObjDesc; 161 162 163 FUNCTION_TRACE ("DsCreateBufferField"); 164 165 166 /* Get the NameString argument */ 167 168 if (Op->Opcode == AML_CREATE_FIELD_OP) 169 { 170 Arg = AcpiPsGetArg (Op, 3); 171 } 172 else 173 { 174 /* Create Bit/Byte/Word/Dword field */ 175 176 Arg = AcpiPsGetArg (Op, 2); 177 } 178 179 if (!Arg) 180 { 181 return_ACPI_STATUS (AE_AML_NO_OPERAND); 182 } 183 184 /* 185 * Enter the NameString into the namespace 186 */ 187 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Value.String, 188 INTERNAL_TYPE_DEF_ANY, IMODE_LOAD_PASS1, 189 NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE, 190 WalkState, &(Node)); 191 if (ACPI_FAILURE (Status)) 192 { 193 return_ACPI_STATUS (Status); 194 } 195 196 /* We could put the returned object (Node) on the object stack for later, but 197 * for now, we will put it in the "op" object that the parser uses, so we 198 * can get it again at the end of this scope 199 */ 200 Op->Node = Node; 201 202 /* 203 * If there is no object attached to the node, this node was just created and 204 * we need to create the field object. Otherwise, this was a lookup of an 205 * existing node and we don't want to create the field object again. 206 */ 207 if (Node->Object) 208 { 209 return_ACPI_STATUS (AE_OK); 210 } 211 212 /* 213 * The Field definition is not fully parsed at this time. 214 * (We must save the address of the AML for the buffer and index operands) 215 */ 216 217 /* Create the buffer field object */ 218 219 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD); 220 if (!ObjDesc) 221 { 222 Status = AE_NO_MEMORY; 223 goto Cleanup; 224 } 225 226 /* 227 * Allocate a method object for this field unit 228 */ 229 ObjDesc->BufferField.Extra = AcpiUtCreateInternalObject ( 230 INTERNAL_TYPE_EXTRA); 231 if (!ObjDesc->BufferField.Extra) 232 { 233 Status = AE_NO_MEMORY; 234 goto Cleanup; 235 } 236 237 /* 238 * Remember location in AML stream of the field unit 239 * opcode and operands -- since the buffer and index 240 * operands must be evaluated. 241 */ 242 ObjDesc->BufferField.Extra->Extra.AmlStart = ((ACPI_PARSE2_OBJECT *) Op)->Data; 243 ObjDesc->BufferField.Extra->Extra.AmlLength = ((ACPI_PARSE2_OBJECT *) Op)->Length; 244 ObjDesc->BufferField.Node = Node; 245 246 /* Attach constructed field descriptor to parent node */ 247 248 Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD); 249 250 251Cleanup: 252 253 /* Remove local reference to the object */ 254 255 AcpiUtRemoveReference (ObjDesc); 256 return_ACPI_STATUS (Status); 257} 258 259 260 261/******************************************************************************* 262 * 263 * FUNCTION: AcpiDsGetFieldNames 264 * 265 * PARAMETERS: Info - CreateField info structure 266 * ` WalkState - Current method state 267 * Arg - First parser arg for the field name list 268 * 269 * RETURN: Status 270 * 271 * DESCRIPTION: Process all named fields in a field declaration. Names are 272 * entered into the namespace. 273 * 274 ******************************************************************************/ 275 276ACPI_STATUS 277AcpiDsGetFieldNames ( 278 ACPI_CREATE_FIELD_INFO *Info, 279 ACPI_WALK_STATE *WalkState, 280 ACPI_PARSE_OBJECT *Arg) 281{ 282 ACPI_STATUS Status; 283 284 285 FUNCTION_TRACE_U32 ("DsGetFieldNames", Info); 286 287 288 /* First field starts at bit zero */ 289 290 Info->FieldBitPosition = 0; 291 292 /* Process all elements in the field list (of parse nodes) */ 293 294 while (Arg) 295 { 296 /* 297 * Three types of field elements are handled: 298 * 1) Offset - specifies a bit offset 299 * 2) AccessAs - changes the access mode 300 * 3) Name - Enters a new named field into the namespace 301 */ 302 switch (Arg->Opcode) 303 { 304 case AML_INT_RESERVEDFIELD_OP: 305 306 Info->FieldBitPosition += Arg->Value.Size; 307 break; 308 309 310 case AML_INT_ACCESSFIELD_OP: 311 312 /* 313 * Get a new AccessType and AccessAttribute for all 314 * entries (until end or another AccessAs keyword) 315 */ 316 Info->FieldFlags = (UINT8) ((Info->FieldFlags & FIELD_ACCESS_TYPE_MASK) || 317 ((UINT8) (Arg->Value.Integer >> 8))); 318 break; 319 320 321 case AML_INT_NAMEDFIELD_OP: 322 323 /* Enter a new field name into the namespace */ 324 325 Status = AcpiNsLookup (WalkState->ScopeInfo, 326 (NATIVE_CHAR *) &((ACPI_PARSE2_OBJECT *)Arg)->Name, 327 Info->FieldType, IMODE_LOAD_PASS1, 328 NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE, 329 NULL, &Info->FieldNode); 330 if (ACPI_FAILURE (Status)) 331 { 332 return_ACPI_STATUS (Status); 333 } 334 335 /* Create and initialize an object for the new Field Node */ 336 337 Info->FieldBitLength = Arg->Value.Size; 338 339 Status = AcpiExPrepFieldValue (Info); 340 if (ACPI_FAILURE (Status)) 341 { 342 return_ACPI_STATUS (Status); 343 } 344 345 /* Keep track of bit position for the next field */ 346 347 Info->FieldBitPosition += Info->FieldBitLength; 348 break; 349 350 351 default: 352 353 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid opcode in field list: %X\n", 354 Arg->Opcode)); 355 return_ACPI_STATUS (AE_AML_ERROR); 356 break; 357 } 358 359 Arg = Arg->Next; 360 } 361 362 return_ACPI_STATUS (AE_OK); 363} 364 365 366/******************************************************************************* 367 * 368 * FUNCTION: AcpiDsCreateField 369 * 370 * PARAMETERS: Op - Op containing the Field definition and args 371 * RegionNode - Object for the containing Operation Region 372 * ` WalkState - Current method state 373 * 374 * RETURN: Status 375 * 376 * DESCRIPTION: Create a new field in the specified operation region 377 * 378 ******************************************************************************/ 379 380ACPI_STATUS 381AcpiDsCreateField ( 382 ACPI_PARSE_OBJECT *Op, 383 ACPI_NAMESPACE_NODE *RegionNode, 384 ACPI_WALK_STATE *WalkState) 385{ 386 ACPI_STATUS Status = AE_AML_ERROR; 387 ACPI_PARSE_OBJECT *Arg; 388 ACPI_CREATE_FIELD_INFO Info; 389 390 391 FUNCTION_TRACE_PTR ("DsCreateField", Op); 392 393 394 /* First arg is the name of the parent OpRegion (must already exist) */ 395 396 Arg = Op->Value.Arg; 397 if (!RegionNode) 398 { 399 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Value.Name, 400 ACPI_TYPE_REGION, IMODE_EXECUTE, 401 NS_SEARCH_PARENT, WalkState, &RegionNode); 402 if (ACPI_FAILURE (Status)) 403 { 404 return_ACPI_STATUS (Status); 405 } 406 } 407 408 /* Second arg is the field flags */ 409 410 Arg = Arg->Next; 411 Info.FieldFlags = Arg->Value.Integer8; 412 413 /* Each remaining arg is a Named Field */ 414 415 Info.FieldType = INTERNAL_TYPE_REGION_FIELD; 416 Info.RegionNode = RegionNode; 417 418 Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Next); 419 420 return_ACPI_STATUS (Status); 421} 422 423 424/******************************************************************************* 425 * 426 * FUNCTION: AcpiDsCreateBankField 427 * 428 * PARAMETERS: Op - Op containing the Field definition and args 429 * RegionNode - Object for the containing Operation Region 430 * ` WalkState - Current method state 431 * 432 * RETURN: Status 433 * 434 * DESCRIPTION: Create a new bank field in the specified operation region 435 * 436 ******************************************************************************/ 437 438ACPI_STATUS 439AcpiDsCreateBankField ( 440 ACPI_PARSE_OBJECT *Op, 441 ACPI_NAMESPACE_NODE *RegionNode, 442 ACPI_WALK_STATE *WalkState) 443{ 444 ACPI_STATUS Status = AE_AML_ERROR; 445 ACPI_PARSE_OBJECT *Arg; 446 ACPI_CREATE_FIELD_INFO Info; 447 448 449 FUNCTION_TRACE_PTR ("DsCreateBankField", Op); 450 451 452 /* First arg is the name of the parent OpRegion (must already exist) */ 453 454 Arg = Op->Value.Arg; 455 if (!RegionNode) 456 { 457 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Value.Name, 458 ACPI_TYPE_REGION, IMODE_EXECUTE, 459 NS_SEARCH_PARENT, WalkState, &RegionNode); 460 if (ACPI_FAILURE (Status)) 461 { 462 return_ACPI_STATUS (Status); 463 } 464 } 465 466 /* Second arg is the Bank Register (must already exist) */ 467 468 Arg = Arg->Next; 469 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Value.String, 470 INTERNAL_TYPE_BANK_FIELD_DEFN, IMODE_EXECUTE, 471 NS_SEARCH_PARENT, WalkState, &Info.RegisterNode); 472 if (ACPI_FAILURE (Status)) 473 { 474 return_ACPI_STATUS (Status); 475 } 476 477 /* Third arg is the BankValue */ 478 479 Arg = Arg->Next; 480 Info.BankValue = Arg->Value.Integer32; 481 482 /* Fourth arg is the field flags */ 483 484 Arg = Arg->Next; 485 Info.FieldFlags = Arg->Value.Integer8; 486 487 /* Each remaining arg is a Named Field */ 488 489 Info.FieldType = INTERNAL_TYPE_BANK_FIELD; 490 Info.RegionNode = RegionNode; 491 492 Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Next); 493 494 return_ACPI_STATUS (Status); 495} 496 497 498/******************************************************************************* 499 * 500 * FUNCTION: AcpiDsCreateIndexField 501 * 502 * PARAMETERS: Op - Op containing the Field definition and args 503 * RegionNode - Object for the containing Operation Region 504 * ` WalkState - Current method state 505 * 506 * RETURN: Status 507 * 508 * DESCRIPTION: Create a new index field in the specified operation region 509 * 510 ******************************************************************************/ 511 512ACPI_STATUS 513AcpiDsCreateIndexField ( 514 ACPI_PARSE_OBJECT *Op, 515 ACPI_NAMESPACE_NODE *RegionNode, 516 ACPI_WALK_STATE *WalkState) 517{ 518 ACPI_STATUS Status; 519 ACPI_PARSE_OBJECT *Arg; 520 ACPI_CREATE_FIELD_INFO Info; 521 522 523 FUNCTION_TRACE_PTR ("DsCreateIndexField", Op); 524 525 526 /* First arg is the name of the Index register (must already exist) */ 527 528 Arg = Op->Value.Arg; 529 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Value.String, 530 ACPI_TYPE_ANY, IMODE_EXECUTE, 531 NS_SEARCH_PARENT, WalkState, &Info.RegisterNode); 532 if (ACPI_FAILURE (Status)) 533 { 534 return_ACPI_STATUS (Status); 535 } 536 537 /* Second arg is the data register (must already exist) */ 538 539 Arg = Arg->Next; 540 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Value.String, 541 INTERNAL_TYPE_INDEX_FIELD_DEFN, IMODE_EXECUTE, 542 NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode); 543 if (ACPI_FAILURE (Status)) 544 { 545 return_ACPI_STATUS (Status); 546 } 547 548 /* Next arg is the field flags */ 549 550 Arg = Arg->Next; 551 Info.FieldFlags = Arg->Value.Integer8; 552 553 554 /* Each remaining arg is a Named Field */ 555 556 Info.FieldType = INTERNAL_TYPE_INDEX_FIELD; 557 Info.RegionNode = RegionNode; 558 559 Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Next); 560 561 return_ACPI_STATUS (Status); 562} 563 564 565