exprep.c revision 99679
1 2/****************************************************************************** 3 * 4 * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities 5 * $Revision: 118 $ 6 * 7 *****************************************************************************/ 8 9/****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp. 14 * All rights reserved. 15 * 16 * 2. License 17 * 18 * 2.1. This is your license from Intel Corp. under its intellectual property 19 * rights. You may have additional license terms from the party that provided 20 * you this software, covering your right to use that party's intellectual 21 * property rights. 22 * 23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24 * copy of the source code appearing in this file ("Covered Code") an 25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial portion of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 * 68 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90 * PARTICULAR PURPOSE. 91 * 92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99 * LIMITED REMEDY. 100 * 101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 102 * software or system incorporating such software without first obtaining any 103 * required license or other approval from the U. S. Department of Commerce or 104 * any other agency or department of the United States Government. In the 105 * event Licensee exports any such software from the United States or 106 * re-exports any such software from a foreign destination, Licensee shall 107 * ensure that the distribution and export/re-export of the software is in 108 * compliance with all laws, regulations, orders, or other restrictions of the 109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110 * any of its subsidiaries will export/re-export any technical data, process, 111 * software, or service, directly or indirectly, to any country for which the 112 * United States government or any agency thereof requires an export license, 113 * other governmental approval, or letter of assurance, without first obtaining 114 * such license, approval or letter. 115 * 116 *****************************************************************************/ 117 118#define __EXPREP_C__ 119 120#include "acpi.h" 121#include "acinterp.h" 122#include "amlcode.h" 123#include "acnamesp.h" 124 125 126#define _COMPONENT ACPI_EXECUTER 127 ACPI_MODULE_NAME ("exprep") 128 129 130/******************************************************************************* 131 * 132 * FUNCTION: AcpiExDecodeFieldAccess 133 * 134 * PARAMETERS: Access - Encoded field access bits 135 * Length - Field length. 136 * 137 * RETURN: Field granularity (8, 16, 32 or 64) and 138 * ByteAlignment (1, 2, 3, or 4) 139 * 140 * DESCRIPTION: Decode the AccessType bits of a field definition. 141 * 142 ******************************************************************************/ 143 144static UINT32 145AcpiExDecodeFieldAccess ( 146 ACPI_OPERAND_OBJECT *ObjDesc, 147 UINT8 FieldFlags, 148 UINT32 *ReturnByteAlignment) 149{ 150 UINT32 Access; 151 UINT8 ByteAlignment; 152 UINT8 BitLength; 153/* UINT32 Length; */ 154 155 156 ACPI_FUNCTION_NAME ("ExDecodeFieldAccess"); 157 158 159 Access = (FieldFlags & AML_FIELD_ACCESS_TYPE_MASK); 160 161 switch (Access) 162 { 163 case AML_FIELD_ACCESS_ANY: 164 165 ByteAlignment = 1; 166 BitLength = 8; 167 168#if 0 169 /* 170 * TBD: optimize 171 * 172 * Any attempt to optimize the access size to the size of the field 173 * must take into consideration the length of the region and take 174 * care that an access to the field will not attempt to access 175 * beyond the end of the region. 176 */ 177 178 /* Use the length to set the access type */ 179 180 Length = ObjDesc->CommonField.BitLength; 181 182 if (Length <= 8) 183 { 184 BitLength = 8; 185 } 186 else if (Length <= 16) 187 { 188 BitLength = 16; 189 } 190 else if (Length <= 32) 191 { 192 BitLength = 32; 193 } 194 else if (Length <= 64) 195 { 196 BitLength = 64; 197 } 198 else 199 { 200 /* Larger than Qword - just use byte-size chunks */ 201 202 BitLength = 8; 203 } 204#endif 205 break; 206 207 case AML_FIELD_ACCESS_BYTE: 208 ByteAlignment = 1; 209 BitLength = 8; 210 break; 211 212 case AML_FIELD_ACCESS_WORD: 213 ByteAlignment = 2; 214 BitLength = 16; 215 break; 216 217 case AML_FIELD_ACCESS_DWORD: 218 ByteAlignment = 4; 219 BitLength = 32; 220 break; 221 222 case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */ 223 ByteAlignment = 8; 224 BitLength = 64; 225 break; 226 227 case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 */ 228 ByteAlignment = 8; 229 BitLength = 8; 230 break; 231 232 default: 233 /* Invalid field access type */ 234 235 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 236 "Unknown field access type %X\n", 237 Access)); 238 return (0); 239 } 240 241 if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_BUFFER_FIELD) 242 { 243 /* 244 * BufferField access can be on any byte boundary, so the 245 * ByteAlignment is always 1 byte -- regardless of any ByteAlignment 246 * implied by the field access type. 247 */ 248 ByteAlignment = 1; 249 } 250 251 *ReturnByteAlignment = ByteAlignment; 252 return (BitLength); 253} 254 255 256/******************************************************************************* 257 * 258 * FUNCTION: AcpiExPrepCommonFieldObject 259 * 260 * PARAMETERS: ObjDesc - The field object 261 * FieldFlags - Access, LockRule, and UpdateRule. 262 * The format of a FieldFlag is described 263 * in the ACPI specification 264 * FieldBitPosition - Field start position 265 * FieldBitLength - Field length in number of bits 266 * 267 * RETURN: Status 268 * 269 * DESCRIPTION: Initialize the areas of the field object that are common 270 * to the various types of fields. Note: This is very "sensitive" 271 * code because we are solving the general case for field 272 * alignment. 273 * 274 ******************************************************************************/ 275 276ACPI_STATUS 277AcpiExPrepCommonFieldObject ( 278 ACPI_OPERAND_OBJECT *ObjDesc, 279 UINT8 FieldFlags, 280 UINT8 FieldAttribute, 281 UINT32 FieldBitPosition, 282 UINT32 FieldBitLength) 283{ 284 UINT32 AccessBitWidth; 285 UINT32 ByteAlignment; 286 UINT32 NearestByteAddress; 287 288 289 ACPI_FUNCTION_TRACE ("ExPrepCommonFieldObject"); 290 291 292 /* 293 * Note: the structure being initialized is the 294 * ACPI_COMMON_FIELD_INFO; No structure fields outside of the common 295 * area are initialized by this procedure. 296 */ 297 ObjDesc->CommonField.FieldFlags = FieldFlags; 298 ObjDesc->CommonField.Attribute = FieldAttribute; 299 ObjDesc->CommonField.BitLength = FieldBitLength; 300 301 /* 302 * Decode the access type so we can compute offsets. The access type gives 303 * two pieces of information - the width of each field access and the 304 * necessary ByteAlignment (address granularity) of the access. 305 * 306 * For AnyAcc, the AccessBitWidth is the largest width that is both 307 * necessary and possible in an attempt to access the whole field in one 308 * I/O operation. However, for AnyAcc, the ByteAlignment is always one 309 * byte. 310 * 311 * For all Buffer Fields, the ByteAlignment is always one byte. 312 * 313 * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is 314 * the same (equivalent) as the ByteAlignment. 315 */ 316 AccessBitWidth = AcpiExDecodeFieldAccess (ObjDesc, FieldFlags, 317 &ByteAlignment); 318 if (!AccessBitWidth) 319 { 320 return_ACPI_STATUS (AE_AML_OPERAND_VALUE); 321 } 322 323 /* Setup width (access granularity) fields */ 324 325 ObjDesc->CommonField.AccessByteWidth = (UINT8) 326 ACPI_DIV_8 (AccessBitWidth); /* 1, 2, 4, 8 */ 327 328 /* 329 * BaseByteOffset is the address of the start of the field within the 330 * region. It is the byte address of the first *datum* (field-width data 331 * unit) of the field. (i.e., the first datum that contains at least the 332 * first *bit* of the field.) 333 * 334 * Note: ByteAlignment is always either equal to the AccessBitWidth or 8 335 * (Byte access), and it defines the addressing granularity of the parent 336 * region or buffer. 337 */ 338 NearestByteAddress = 339 ACPI_ROUND_BITS_DOWN_TO_BYTES (FieldBitPosition); 340 ObjDesc->CommonField.BaseByteOffset = 341 ACPI_ROUND_DOWN (NearestByteAddress, ByteAlignment); 342 343 /* 344 * StartFieldBitOffset is the offset of the first bit of the field within 345 * a field datum. 346 */ 347 ObjDesc->CommonField.StartFieldBitOffset = (UINT8) 348 (FieldBitPosition - ACPI_MUL_8 (ObjDesc->CommonField.BaseByteOffset)); 349 350 /* 351 * Valid bits -- the number of bits that compose a partial datum, 352 * 1) At the end of the field within the region (arbitrary starting bit 353 * offset) 354 * 2) At the end of a buffer used to contain the field (starting offset 355 * always zero) 356 */ 357 ObjDesc->CommonField.EndFieldValidBits = (UINT8) 358 ((ObjDesc->CommonField.StartFieldBitOffset + FieldBitLength) % 359 AccessBitWidth); 360 /* StartBufferBitOffset always = 0 */ 361 362 ObjDesc->CommonField.EndBufferValidBits = (UINT8) 363 (FieldBitLength % AccessBitWidth); 364 365 /* 366 * DatumValidBits is the number of valid field bits in the first 367 * field datum. 368 */ 369 ObjDesc->CommonField.DatumValidBits = (UINT8) 370 (AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset); 371 372 /* 373 * Does the entire field fit within a single field access element? (datum) 374 * (i.e., without crossing a datum boundary) 375 */ 376 if ((ObjDesc->CommonField.StartFieldBitOffset + FieldBitLength) <= 377 (UINT16) AccessBitWidth) 378 { 379 ObjDesc->Common.Flags |= AOPOBJ_SINGLE_DATUM; 380 } 381 382 return_ACPI_STATUS (AE_OK); 383} 384 385 386/******************************************************************************* 387 * 388 * FUNCTION: AcpiExPrepFieldValue 389 * 390 * PARAMETERS: Node - Owning Node 391 * RegionNode - Region in which field is being defined 392 * FieldFlags - Access, LockRule, and UpdateRule. 393 * FieldBitPosition - Field start position 394 * FieldBitLength - Field length in number of bits 395 * 396 * RETURN: Status 397 * 398 * DESCRIPTION: Construct an ACPI_OPERAND_OBJECT of type DefField and 399 * connect it to the parent Node. 400 * 401 ******************************************************************************/ 402 403ACPI_STATUS 404AcpiExPrepFieldValue ( 405 ACPI_CREATE_FIELD_INFO *Info) 406{ 407 ACPI_OPERAND_OBJECT *ObjDesc; 408 UINT32 Type; 409 ACPI_STATUS Status; 410 411 412 ACPI_FUNCTION_TRACE ("ExPrepFieldValue"); 413 414 415 /* Parameter validation */ 416 417 if (Info->FieldType != INTERNAL_TYPE_INDEX_FIELD) 418 { 419 if (!Info->RegionNode) 420 { 421 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null RegionNode\n")); 422 return_ACPI_STATUS (AE_AML_NO_OPERAND); 423 } 424 425 Type = AcpiNsGetType (Info->RegionNode); 426 if (Type != ACPI_TYPE_REGION) 427 { 428 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 429 "Needed Region, found type %X %s\n", 430 Type, AcpiUtGetTypeName (Type))); 431 432 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 433 } 434 } 435 436 /* Allocate a new field object */ 437 438 ObjDesc = AcpiUtCreateInternalObject (Info->FieldType); 439 if (!ObjDesc) 440 { 441 return_ACPI_STATUS (AE_NO_MEMORY); 442 } 443 444 /* Initialize areas of the object that are common to all fields */ 445 446 ObjDesc->CommonField.Node = Info->FieldNode; 447 Status = AcpiExPrepCommonFieldObject (ObjDesc, Info->FieldFlags, 448 Info->Attribute, Info->FieldBitPosition, Info->FieldBitLength); 449 if (ACPI_FAILURE (Status)) 450 { 451 AcpiUtDeleteObjectDesc (ObjDesc); 452 return_ACPI_STATUS (Status); 453 } 454 455 /* Initialize areas of the object that are specific to the field type */ 456 457 switch (Info->FieldType) 458 { 459 case INTERNAL_TYPE_REGION_FIELD: 460 461 ObjDesc->Field.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode); 462 463 /* An additional reference for the container */ 464 465 AcpiUtAddReference (ObjDesc->Field.RegionObj); 466 467 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 468 "RegionField: Bitoff=%X Off=%X Gran=%X Region %p\n", 469 ObjDesc->Field.StartFieldBitOffset, ObjDesc->Field.BaseByteOffset, 470 ObjDesc->Field.AccessByteWidth, ObjDesc->Field.RegionObj)); 471 break; 472 473 474 case INTERNAL_TYPE_BANK_FIELD: 475 476 ObjDesc->BankField.Value = Info->BankValue; 477 ObjDesc->BankField.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode); 478 ObjDesc->BankField.BankObj = AcpiNsGetAttachedObject (Info->RegisterNode); 479 480 /* An additional reference for the attached objects */ 481 482 AcpiUtAddReference (ObjDesc->BankField.RegionObj); 483 AcpiUtAddReference (ObjDesc->BankField.BankObj); 484 485 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 486 "Bank Field: BitOff=%X Off=%X Gran=%X Region %p BankReg %p\n", 487 ObjDesc->BankField.StartFieldBitOffset, 488 ObjDesc->BankField.BaseByteOffset, 489 ObjDesc->Field.AccessByteWidth, 490 ObjDesc->BankField.RegionObj, 491 ObjDesc->BankField.BankObj)); 492 break; 493 494 495 case INTERNAL_TYPE_INDEX_FIELD: 496 497 ObjDesc->IndexField.IndexObj = AcpiNsGetAttachedObject (Info->RegisterNode); 498 ObjDesc->IndexField.DataObj = AcpiNsGetAttachedObject (Info->DataRegisterNode); 499 ObjDesc->IndexField.Value = (UINT32) 500 (Info->FieldBitPosition / ACPI_MUL_8 (ObjDesc->Field.AccessByteWidth)); 501 502 if (!ObjDesc->IndexField.DataObj || !ObjDesc->IndexField.IndexObj) 503 { 504 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Index Object\n")); 505 return_ACPI_STATUS (AE_AML_INTERNAL); 506 } 507 508 /* An additional reference for the attached objects */ 509 510 AcpiUtAddReference (ObjDesc->IndexField.DataObj); 511 AcpiUtAddReference (ObjDesc->IndexField.IndexObj); 512 513 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 514 "IndexField: bitoff=%X off=%X gran=%X Index %p Data %p\n", 515 ObjDesc->IndexField.StartFieldBitOffset, 516 ObjDesc->IndexField.BaseByteOffset, 517 ObjDesc->Field.AccessByteWidth, 518 ObjDesc->IndexField.IndexObj, 519 ObjDesc->IndexField.DataObj)); 520 break; 521 522 default: 523 /* No other types should get here */ 524 break; 525 } 526 527 /* 528 * Store the constructed descriptor (ObjDesc) into the parent Node, 529 * preserving the current type of that NamedObj. 530 */ 531 Status = AcpiNsAttachObject (Info->FieldNode, ObjDesc, 532 AcpiNsGetType (Info->FieldNode)); 533 534 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "set NamedObj %p (%4.4s) val = %p\n", 535 Info->FieldNode, Info->FieldNode->Name.Ascii, ObjDesc)); 536 537 /* Remove local reference to the object */ 538 539 AcpiUtRemoveReference (ObjDesc); 540 return_ACPI_STATUS (Status); 541} 542 543