exprep.c revision 138287
1184610Salfred 2184610Salfred/****************************************************************************** 3184610Salfred * 4184610Salfred * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities 5184610Salfred * $Revision: 128 $ 6184610Salfred * 7184610Salfred *****************************************************************************/ 8184610Salfred 9184610Salfred/****************************************************************************** 10184610Salfred * 11184610Salfred * 1. Copyright Notice 12184610Salfred * 13184610Salfred * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp. 14184610Salfred * All rights reserved. 15184610Salfred * 16184610Salfred * 2. License 17184610Salfred * 18184610Salfred * 2.1. This is your license from Intel Corp. under its intellectual property 19184610Salfred * rights. You may have additional license terms from the party that provided 20184610Salfred * you this software, covering your right to use that party's intellectual 21184610Salfred * property rights. 22184610Salfred * 23184610Salfred * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24184610Salfred * copy of the source code appearing in this file ("Covered Code") an 25184610Salfred * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26184610Salfred * base code distributed originally by Intel ("Original Intel Code") to copy, 27184610Salfred * make derivatives, distribute, use and display any portion of the Covered 28184610Salfred * Code in any form, with the right to sublicense such rights; and 29184610Salfred * 30184610Salfred * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31184610Salfred * license (with the right to sublicense), under only those claims of Intel 32184610Salfred * patents that are infringed by the Original Intel Code, to make, use, sell, 33184610Salfred * offer to sell, and import the Covered Code and derivative works thereof 34184610Salfred * solely to the minimum extent necessary to exercise the above copyright 35184610Salfred * license, and in no event shall the patent license extend to any additions 36184610Salfred * to or modifications of the Original Intel Code. No other license or right 37184610Salfred * is granted directly or by implication, estoppel or otherwise; 38184610Salfred * 39184610Salfred * The above copyright and patent license is granted only if the following 40184610Salfred * conditions are met: 41190174Sthompsa * 42187170Sthompsa * 3. Conditions 43190754Sthompsa * 44184610Salfred * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45184610Salfred * Redistribution of source code of any substantial portion of the Covered 46184610Salfred * Code or modification with rights to further distribute source must include 47184610Salfred * the above Copyright Notice, the above License, this list of Conditions, 48184610Salfred * and the following Disclaimer and Export Compliance provision. In addition, 49184610Salfred * Licensee must cause all Covered Code to which Licensee contributes to 50184610Salfred * contain a file documenting the changes Licensee made to create that Covered 51184610Salfred * Code and the date of any change. Licensee must include in that file the 52184610Salfred * documentation of any changes made by any predecessor Licensee. Licensee 53184610Salfred * must include a prominent statement that the modification is derived, 54184610Salfred * directly or indirectly, from Original Intel Code. 55184610Salfred * 56184610Salfred * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57184610Salfred * Redistribution of source code of any substantial portion of the Covered 58184610Salfred * Code or modification without rights to further distribute source must 59184610Salfred * include the following Disclaimer and Export Compliance provision in the 60184610Salfred * documentation and/or other materials provided with distribution. In 61184610Salfred * addition, Licensee may not authorize further sublicense of source of any 62184610Salfred * portion of the Covered Code, and must include terms to the effect that the 63184610Salfred * license from Licensee to its licensee is limited to the intellectual 64184610Salfred * property embodied in the software Licensee provides to its licensee, and 65184610Salfred * not to intellectual property embodied in modifications its licensee may 66184610Salfred * make. 67184610Salfred * 68184610Salfred * 3.3. Redistribution of Executable. Redistribution in executable form of any 69184610Salfred * substantial portion of the Covered Code or modification must reproduce the 70184610Salfred * above Copyright Notice, and the following Disclaimer and Export Compliance 71184610Salfred * provision in the documentation and/or other materials provided with the 72184610Salfred * distribution. 73184610Salfred * 74184610Salfred * 3.4. Intel retains all right, title, and interest in and to the Original 75184610Salfred * Intel Code. 76184610Salfred * 77184610Salfred * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78184610Salfred * Intel shall be used in advertising or otherwise to promote the sale, use or 79184610Salfred * other dealings in products derived from or relating to the Covered Code 80184610Salfred * without prior written authorization from Intel. 81184610Salfred * 82184610Salfred * 4. Disclaimer and Export Compliance 83184610Salfred * 84184610Salfred * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85184610Salfred * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86184610Salfred * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87184610Salfred * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88184610Salfred * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89184610Salfred * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90184610Salfred * PARTICULAR PURPOSE. 91184610Salfred * 92184610Salfred * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93184610Salfred * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94184610Salfred * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95184610Salfred * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96184610Salfred * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97184610Salfred * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98184610Salfred * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99184610Salfred * LIMITED REMEDY. 100184610Salfred * 101184610Salfred * 4.3. Licensee shall not export, either directly or indirectly, any of this 102184610Salfred * software or system incorporating such software without first obtaining any 103184610Salfred * required license or other approval from the U. S. Department of Commerce or 104184610Salfred * any other agency or department of the United States Government. In the 105184610Salfred * event Licensee exports any such software from the United States or 106184610Salfred * re-exports any such software from a foreign destination, Licensee shall 107184610Salfred * ensure that the distribution and export/re-export of the software is in 108184610Salfred * compliance with all laws, regulations, orders, or other restrictions of the 109184610Salfred * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110184610Salfred * any of its subsidiaries will export/re-export any technical data, process, 111184610Salfred * software, or service, directly or indirectly, to any country for which the 112184610Salfred * United States government or any agency thereof requires an export license, 113184610Salfred * other governmental approval, or letter of assurance, without first obtaining 114184610Salfred * such license, approval or letter. 115184610Salfred * 116184610Salfred *****************************************************************************/ 117184610Salfred 118184610Salfred#define __EXPREP_C__ 119184610Salfred 120184610Salfred#include "acpi.h" 121184610Salfred#include "acinterp.h" 122184610Salfred#include "amlcode.h" 123184610Salfred#include "acnamesp.h" 124184610Salfred 125184610Salfred 126184610Salfred#define _COMPONENT ACPI_EXECUTER 127184610Salfred ACPI_MODULE_NAME ("exprep") 128184610Salfred 129184610Salfred 130184610Salfred#ifdef ACPI_UNDER_DEVELOPMENT 131184610Salfred/******************************************************************************* 132184610Salfred * 133184610Salfred * FUNCTION: AcpiExGenerateAccess 134184610Salfred * 135184610Salfred * PARAMETERS: FieldBitOffset - Start of field within parent region/buffer 136184610Salfred * FieldBitLength - Length of field in bits 137184610Salfred * RegionLength - Length of parent in bytes 138184610Salfred * 139184610Salfred * RETURN: Field granularity (8, 16, 32 or 64) and 140184610Salfred * ByteAlignment (1, 2, 3, or 4) 141184610Salfred * 142184610Salfred * DESCRIPTION: Generate an optimal access width for fields defined with the 143184610Salfred * AnyAcc keyword. 144184610Salfred * 145184610Salfred * NOTE: Need to have the RegionLength in order to check for boundary 146184610Salfred * conditions (end-of-region). However, the RegionLength is a deferred 147184610Salfred * operation. Therefore, to complete this implementation, the generation 148184610Salfred * of this access width must be deferred until the region length has 149184610Salfred * been evaluated. 150184610Salfred * 151184610Salfred ******************************************************************************/ 152184610Salfred 153184610Salfredstatic UINT32 154184610SalfredAcpiExGenerateAccess ( 155184610Salfred UINT32 FieldBitOffset, 156184610Salfred UINT32 FieldBitLength, 157184610Salfred UINT32 RegionLength) 158184610Salfred{ 159184610Salfred UINT32 FieldByteLength; 160184610Salfred UINT32 FieldByteOffset; 161184610Salfred UINT32 FieldByteEndOffset; 162184610Salfred UINT32 AccessByteWidth; 163184610Salfred UINT32 FieldStartOffset; 164184610Salfred UINT32 FieldEndOffset; 165186730Salfred UINT32 MinimumAccessWidth = 0xFFFFFFFF; 166186730Salfred UINT32 MinimumAccesses = 0xFFFFFFFF; 167186730Salfred UINT32 Accesses; 168186730Salfred 169186730Salfred 170186730Salfred ACPI_FUNCTION_TRACE ("ExGenerateAccess"); 171186730Salfred 172186730Salfred 173186730Salfred /* Round Field start offset and length to "minimal" byte boundaries */ 174184610Salfred 175184610Salfred FieldByteOffset = ACPI_DIV_8 (ACPI_ROUND_DOWN (FieldBitOffset, 8)); 176184610Salfred FieldByteEndOffset = ACPI_DIV_8 (ACPI_ROUND_UP (FieldBitLength + FieldBitOffset, 8)); 177184610Salfred FieldByteLength = FieldByteEndOffset - FieldByteOffset; 178184610Salfred 179184610Salfred ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 180184610Salfred "Bit length %d, Bit offset %d\n", 181184610Salfred FieldBitLength, FieldBitOffset)); 182184610Salfred ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 183184610Salfred "Byte Length %d, Byte Offset %d, End Offset %d\n", 184184610Salfred FieldByteLength, FieldByteOffset, FieldByteEndOffset)); 185184610Salfred 186184610Salfred /* 187184610Salfred * Iterative search for the maximum access width that is both aligned 188184610Salfred * and does not go beyond the end of the region 189184610Salfred * 190184610Salfred * Start at ByteAcc and work upwards to QwordAcc max. (1,2,4,8 bytes) 191184610Salfred */ 192184610Salfred for (AccessByteWidth = 1; AccessByteWidth <= 8; AccessByteWidth <<= 1) 193184610Salfred { 194184610Salfred /* 195184610Salfred * 1) Round end offset up to next access boundary and make sure that this 196184610Salfred * does not go beyond the end of the parent region. 197184610Salfred * 2) When the Access width is greater than the FieldByteLength, we are done. 198184610Salfred * (This does not optimize for the perfectly aligned case yet). 199184610Salfred */ 200184610Salfred if (ACPI_ROUND_UP (FieldByteEndOffset, AccessByteWidth) <= RegionLength) 201184610Salfred { 202184610Salfred FieldStartOffset = ACPI_ROUND_DOWN (FieldByteOffset, AccessByteWidth) / 203184610Salfred AccessByteWidth; 204184610Salfred FieldEndOffset = ACPI_ROUND_UP ((FieldByteLength + FieldByteOffset), 205184610Salfred AccessByteWidth) / AccessByteWidth; 206184610Salfred Accesses = FieldEndOffset - FieldStartOffset; 207184610Salfred 208184610Salfred ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 209184610Salfred "AccessWidth %d end is within region\n", AccessByteWidth)); 210184610Salfred ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 211184610Salfred "Field Start %d, Field End %d -- requires %d accesses\n", 212184610Salfred FieldStartOffset, FieldEndOffset, Accesses)); 213184610Salfred 214184610Salfred /* Single access is optimal */ 215184610Salfred 216184610Salfred if (Accesses <= 1) 217184610Salfred { 218184610Salfred ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 219184610Salfred "Entire field can be accessed with one operation of size %d\n", 220184610Salfred AccessByteWidth)); 221184610Salfred return_VALUE (AccessByteWidth); 222184610Salfred } 223184610Salfred 224184610Salfred /* 225184610Salfred * Fits in the region, but requires more than one read/write. 226184610Salfred * try the next wider access on next iteration 227184610Salfred */ 228184610Salfred if (Accesses < MinimumAccesses) 229184610Salfred { 230184610Salfred MinimumAccesses = Accesses; 231184610Salfred MinimumAccessWidth = AccessByteWidth; 232184610Salfred } 233184610Salfred } 234184610Salfred else 235184610Salfred { 236184610Salfred ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 237184610Salfred "AccessWidth %d end is NOT within region\n", AccessByteWidth)); 238184610Salfred if (AccessByteWidth == 1) 239184610Salfred { 240184610Salfred ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 241184610Salfred "Field goes beyond end-of-region!\n")); 242184610Salfred return_VALUE (0); /* Field does not fit in the region at all */ 243184610Salfred } 244184610Salfred 245184610Salfred /* This width goes beyond the end-of-region, back off to previous access */ 246184610Salfred 247184610Salfred ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 248184610Salfred "Backing off to previous optimal access width of %d\n", 249184610Salfred MinimumAccessWidth)); 250184610Salfred return_VALUE (MinimumAccessWidth); 251184610Salfred } 252184610Salfred } 253184610Salfred 254184610Salfred /* Could not read/write field with one operation, just use max access width */ 255184610Salfred 256192984Sthompsa ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 257184610Salfred "Cannot access field in one operation, using width 8\n")); 258184610Salfred return_VALUE (8); 259184610Salfred} 260184610Salfred#endif /* ACPI_UNDER_DEVELOPMENT */ 261184610Salfred 262184610Salfred 263184610Salfred/******************************************************************************* 264184610Salfred * 265184610Salfred * FUNCTION: AcpiExDecodeFieldAccess 266184610Salfred * 267184610Salfred * PARAMETERS: Access - Encoded field access bits 268184610Salfred * Length - Field length. 269184610Salfred * 270184610Salfred * RETURN: Field granularity (8, 16, 32 or 64) and 271184610Salfred * ByteAlignment (1, 2, 3, or 4) 272184610Salfred * 273184610Salfred * DESCRIPTION: Decode the AccessType bits of a field definition. 274184610Salfred * 275184610Salfred ******************************************************************************/ 276184610Salfred 277184610Salfredstatic UINT32 278184610SalfredAcpiExDecodeFieldAccess ( 279184610Salfred ACPI_OPERAND_OBJECT *ObjDesc, 280184610Salfred UINT8 FieldFlags, 281184610Salfred UINT32 *ReturnByteAlignment) 282184610Salfred{ 283184610Salfred UINT32 Access; 284184610Salfred UINT32 ByteAlignment; 285184610Salfred UINT32 BitLength; 286184610Salfred 287184610Salfred 288184610Salfred ACPI_FUNCTION_TRACE ("ExDecodeFieldAccess"); 289184610Salfred 290184610Salfred 291184610Salfred Access = (FieldFlags & AML_FIELD_ACCESS_TYPE_MASK); 292184610Salfred 293184610Salfred switch (Access) 294184610Salfred { 295184610Salfred case AML_FIELD_ACCESS_ANY: 296184610Salfred 297184610Salfred#ifdef ACPI_UNDER_DEVELOPMENT 298184610Salfred ByteAlignment = AcpiExGenerateAccess (ObjDesc->CommonField.StartFieldBitOffset, 299184610Salfred ObjDesc->CommonField.BitLength, 300184610Salfred 0xFFFFFFFF /* Temp until we pass RegionLength as param */); 301184610Salfred BitLength = ByteAlignment * 8; 302184610Salfred#endif 303184610Salfred 304192984Sthompsa ByteAlignment = 1; 305184610Salfred BitLength = 8; 306184610Salfred break; 307184610Salfred 308184610Salfred case AML_FIELD_ACCESS_BYTE: 309184610Salfred case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 (SMBus Buffer) */ 310184610Salfred ByteAlignment = 1; 311184610Salfred BitLength = 8; 312184610Salfred break; 313184610Salfred 314184610Salfred case AML_FIELD_ACCESS_WORD: 315184610Salfred ByteAlignment = 2; 316184610Salfred BitLength = 16; 317184610Salfred break; 318184610Salfred 319184610Salfred case AML_FIELD_ACCESS_DWORD: 320184610Salfred ByteAlignment = 4; 321184610Salfred BitLength = 32; 322184610Salfred break; 323184610Salfred 324184610Salfred case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */ 325184610Salfred ByteAlignment = 8; 326184610Salfred BitLength = 64; 327184610Salfred break; 328184610Salfred 329184610Salfred default: 330184610Salfred /* Invalid field access type */ 331184610Salfred 332184610Salfred ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 333184610Salfred "Unknown field access type %X\n", 334184610Salfred Access)); 335184610Salfred return_VALUE (0); 336184610Salfred } 337184610Salfred 338184610Salfred if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_BUFFER_FIELD) 339184610Salfred { 340184610Salfred /* 341184610Salfred * BufferField access can be on any byte boundary, so the 342184610Salfred * ByteAlignment is always 1 byte -- regardless of any ByteAlignment 343184610Salfred * implied by the field access type. 344184610Salfred */ 345184610Salfred ByteAlignment = 1; 346184610Salfred } 347184610Salfred 348184610Salfred *ReturnByteAlignment = ByteAlignment; 349184610Salfred return_VALUE (BitLength); 350192984Sthompsa} 351184610Salfred 352184610Salfred 353184610Salfred/******************************************************************************* 354184610Salfred * 355184610Salfred * FUNCTION: AcpiExPrepCommonFieldObject 356184610Salfred * 357184610Salfred * PARAMETERS: ObjDesc - The field object 358184610Salfred * FieldFlags - Access, LockRule, and UpdateRule. 359184610Salfred * The format of a FieldFlag is described 360184610Salfred * in the ACPI specification 361184610Salfred * FieldBitPosition - Field start position 362184610Salfred * FieldBitLength - Field length in number of bits 363184610Salfred * 364184610Salfred * RETURN: Status 365184610Salfred * 366184610Salfred * DESCRIPTION: Initialize the areas of the field object that are common 367184610Salfred * to the various types of fields. Note: This is very "sensitive" 368184610Salfred * code because we are solving the general case for field 369184610Salfred * alignment. 370184610Salfred * 371184610Salfred ******************************************************************************/ 372184610Salfred 373184610SalfredACPI_STATUS 374184610SalfredAcpiExPrepCommonFieldObject ( 375184610Salfred ACPI_OPERAND_OBJECT *ObjDesc, 376184610Salfred UINT8 FieldFlags, 377184610Salfred UINT8 FieldAttribute, 378184610Salfred UINT32 FieldBitPosition, 379184610Salfred UINT32 FieldBitLength) 380184610Salfred{ 381184610Salfred UINT32 AccessBitWidth; 382184610Salfred UINT32 ByteAlignment; 383184610Salfred UINT32 NearestByteAddress; 384184610Salfred 385184610Salfred 386184610Salfred ACPI_FUNCTION_TRACE ("ExPrepCommonFieldObject"); 387184610Salfred 388184610Salfred 389184610Salfred /* 390184610Salfred * Note: the structure being initialized is the 391184610Salfred * ACPI_COMMON_FIELD_INFO; No structure fields outside of the common 392184610Salfred * area are initialized by this procedure. 393184610Salfred */ 394184610Salfred ObjDesc->CommonField.FieldFlags = FieldFlags; 395184610Salfred ObjDesc->CommonField.Attribute = FieldAttribute; 396184610Salfred ObjDesc->CommonField.BitLength = FieldBitLength; 397184610Salfred 398184610Salfred /* 399184610Salfred * Decode the access type so we can compute offsets. The access type gives 400184610Salfred * two pieces of information - the width of each field access and the 401184610Salfred * necessary ByteAlignment (address granularity) of the access. 402184610Salfred * 403184610Salfred * For AnyAcc, the AccessBitWidth is the largest width that is both 404184610Salfred * necessary and possible in an attempt to access the whole field in one 405184610Salfred * I/O operation. However, for AnyAcc, the ByteAlignment is always one 406184610Salfred * byte. 407184610Salfred * 408184610Salfred * For all Buffer Fields, the ByteAlignment is always one byte. 409184610Salfred * 410184610Salfred * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is 411184610Salfred * the same (equivalent) as the ByteAlignment. 412192984Sthompsa */ 413184610Salfred AccessBitWidth = AcpiExDecodeFieldAccess (ObjDesc, FieldFlags, 414184610Salfred &ByteAlignment); 415184610Salfred if (!AccessBitWidth) 416184610Salfred { 417184610Salfred return_ACPI_STATUS (AE_AML_OPERAND_VALUE); 418184610Salfred } 419184610Salfred 420184610Salfred /* Setup width (access granularity) fields */ 421184610Salfred 422184610Salfred ObjDesc->CommonField.AccessByteWidth = (UINT8) 423184610Salfred ACPI_DIV_8 (AccessBitWidth); /* 1, 2, 4, 8 */ 424184610Salfred 425184610Salfred /* 426184610Salfred * BaseByteOffset is the address of the start of the field within the 427192984Sthompsa * region. It is the byte address of the first *datum* (field-width data 428192984Sthompsa * unit) of the field. (i.e., the first datum that contains at least the 429192984Sthompsa * first *bit* of the field.) 430192984Sthompsa * 431192984Sthompsa * Note: ByteAlignment is always either equal to the AccessBitWidth or 8 432184610Salfred * (Byte access), and it defines the addressing granularity of the parent 433192984Sthompsa * region or buffer. 434192984Sthompsa */ 435192984Sthompsa NearestByteAddress = 436192984Sthompsa ACPI_ROUND_BITS_DOWN_TO_BYTES (FieldBitPosition); 437192984Sthompsa ObjDesc->CommonField.BaseByteOffset = (UINT32) 438184610Salfred ACPI_ROUND_DOWN (NearestByteAddress, ByteAlignment); 439184610Salfred 440184610Salfred /* 441192984Sthompsa * StartFieldBitOffset is the offset of the first bit of the field within 442192984Sthompsa * a field datum. 443192984Sthompsa */ 444184610Salfred ObjDesc->CommonField.StartFieldBitOffset = (UINT8) 445184610Salfred (FieldBitPosition - ACPI_MUL_8 (ObjDesc->CommonField.BaseByteOffset)); 446184610Salfred 447192984Sthompsa /* 448192984Sthompsa * Valid bits -- the number of bits that compose a partial datum, 449192984Sthompsa * 1) At the end of the field within the region (arbitrary starting bit 450184610Salfred * offset) 451184610Salfred * 2) At the end of a buffer used to contain the field (starting offset 452184610Salfred * always zero) 453184610Salfred */ 454184610Salfred ObjDesc->CommonField.EndFieldValidBits = (UINT8) 455192984Sthompsa ((ObjDesc->CommonField.StartFieldBitOffset + FieldBitLength) % 456192984Sthompsa AccessBitWidth); 457184610Salfred /* StartBufferBitOffset always = 0 */ 458184610Salfred 459192984Sthompsa ObjDesc->CommonField.EndBufferValidBits = (UINT8) 460184610Salfred (FieldBitLength % AccessBitWidth); 461184610Salfred 462184610Salfred /* 463184610Salfred * DatumValidBits is the number of valid field bits in the first 464184610Salfred * field datum. 465184610Salfred */ 466184610Salfred ObjDesc->CommonField.DatumValidBits = (UINT8) 467184610Salfred (AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset); 468184610Salfred 469184610Salfred /* 470184610Salfred * Does the entire field fit within a single field access element? (datum) 471184610Salfred * (i.e., without crossing a datum boundary) 472184610Salfred */ 473184610Salfred if ((ObjDesc->CommonField.StartFieldBitOffset + FieldBitLength) <= 474184610Salfred (UINT16) AccessBitWidth) 475184610Salfred { 476184610Salfred ObjDesc->Common.Flags |= AOPOBJ_SINGLE_DATUM; 477185087Salfred } 478186730Salfred 479186730Salfred return_ACPI_STATUS (AE_OK); 480186730Salfred} 481186730Salfred 482186730Salfred 483186730Salfred/******************************************************************************* 484184610Salfred * 485184610Salfred * FUNCTION: AcpiExPrepFieldValue 486184610Salfred * 487184610Salfred * PARAMETERS: Node - Owning Node 488184610Salfred * RegionNode - Region in which field is being defined 489184610Salfred * FieldFlags - Access, LockRule, and UpdateRule. 490184610Salfred * FieldBitPosition - Field start position 491184610Salfred * FieldBitLength - Field length in number of bits 492184610Salfred * 493184610Salfred * RETURN: Status 494184610Salfred * 495184610Salfred * DESCRIPTION: Construct an ACPI_OPERAND_OBJECT of type DefField and 496184610Salfred * connect it to the parent Node. 497184610Salfred * 498184610Salfred ******************************************************************************/ 499184610Salfred 500184610SalfredACPI_STATUS 501184610SalfredAcpiExPrepFieldValue ( 502184610Salfred ACPI_CREATE_FIELD_INFO *Info) 503184610Salfred{ 504184610Salfred ACPI_OPERAND_OBJECT *ObjDesc; 505184610Salfred UINT32 Type; 506184610Salfred ACPI_STATUS Status; 507184610Salfred 508184610Salfred 509184610Salfred ACPI_FUNCTION_TRACE ("ExPrepFieldValue"); 510184610Salfred 511184610Salfred 512184610Salfred /* Parameter validation */ 513184610Salfred 514184610Salfred if (Info->FieldType != ACPI_TYPE_LOCAL_INDEX_FIELD) 515184610Salfred { 516184610Salfred if (!Info->RegionNode) 517184610Salfred { 518184610Salfred ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null RegionNode\n")); 519189496Sthompsa return_ACPI_STATUS (AE_AML_NO_OPERAND); 520189496Sthompsa } 521189496Sthompsa 522189496Sthompsa Type = AcpiNsGetType (Info->RegionNode); 523189496Sthompsa if (Type != ACPI_TYPE_REGION) 524189496Sthompsa { 525189496Sthompsa ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 526189496Sthompsa "Needed Region, found type %X (%s)\n", 527189496Sthompsa Type, AcpiUtGetTypeName (Type))); 528189496Sthompsa 529189496Sthompsa return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 530189496Sthompsa } 531189496Sthompsa } 532189496Sthompsa 533189496Sthompsa /* Allocate a new field object */ 534189496Sthompsa 535189496Sthompsa ObjDesc = AcpiUtCreateInternalObject (Info->FieldType); 536189496Sthompsa if (!ObjDesc) 537189496Sthompsa { 538189496Sthompsa return_ACPI_STATUS (AE_NO_MEMORY); 539189496Sthompsa } 540189496Sthompsa 541189496Sthompsa /* Initialize areas of the object that are common to all fields */ 542189496Sthompsa 543189496Sthompsa ObjDesc->CommonField.Node = Info->FieldNode; 544189496Sthompsa Status = AcpiExPrepCommonFieldObject (ObjDesc, Info->FieldFlags, 545189496Sthompsa Info->Attribute, Info->FieldBitPosition, Info->FieldBitLength); 546189496Sthompsa if (ACPI_FAILURE (Status)) 547189496Sthompsa { 548189496Sthompsa AcpiUtDeleteObjectDesc (ObjDesc); 549189496Sthompsa return_ACPI_STATUS (Status); 550189496Sthompsa } 551189496Sthompsa 552189496Sthompsa /* Initialize areas of the object that are specific to the field type */ 553189496Sthompsa 554189496Sthompsa switch (Info->FieldType) 555189496Sthompsa { 556189496Sthompsa case ACPI_TYPE_LOCAL_REGION_FIELD: 557189496Sthompsa 558189496Sthompsa ObjDesc->Field.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode); 559189496Sthompsa 560189496Sthompsa /* An additional reference for the container */ 561189496Sthompsa 562189496Sthompsa AcpiUtAddReference (ObjDesc->Field.RegionObj); 563189496Sthompsa 564189496Sthompsa ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 565189496Sthompsa "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", 566189496Sthompsa ObjDesc->Field.StartFieldBitOffset, ObjDesc->Field.BaseByteOffset, 567189496Sthompsa ObjDesc->Field.AccessByteWidth, ObjDesc->Field.RegionObj)); 568189496Sthompsa break; 569189496Sthompsa 570189496Sthompsa 571189496Sthompsa case ACPI_TYPE_LOCAL_BANK_FIELD: 572189496Sthompsa 573189496Sthompsa ObjDesc->BankField.Value = Info->BankValue; 574189496Sthompsa ObjDesc->BankField.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode); 575189496Sthompsa ObjDesc->BankField.BankObj = AcpiNsGetAttachedObject (Info->RegisterNode); 576189496Sthompsa 577193045Sthompsa /* An additional reference for the attached objects */ 578184610Salfred 579193045Sthompsa AcpiUtAddReference (ObjDesc->BankField.RegionObj); 580193045Sthompsa AcpiUtAddReference (ObjDesc->BankField.BankObj); 581184610Salfred 582184610Salfred ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 583184610Salfred "Bank Field: BitOff %X, Off %X, Gran %X, Region %p, BankReg %p\n", 584184610Salfred ObjDesc->BankField.StartFieldBitOffset, 585184610Salfred ObjDesc->BankField.BaseByteOffset, 586184610Salfred ObjDesc->Field.AccessByteWidth, 587184610Salfred ObjDesc->BankField.RegionObj, 588 ObjDesc->BankField.BankObj)); 589 break; 590 591 592 case ACPI_TYPE_LOCAL_INDEX_FIELD: 593 594 ObjDesc->IndexField.IndexObj = AcpiNsGetAttachedObject (Info->RegisterNode); 595 ObjDesc->IndexField.DataObj = AcpiNsGetAttachedObject (Info->DataRegisterNode); 596 ObjDesc->IndexField.Value = (UINT32) 597 (Info->FieldBitPosition / ACPI_MUL_8 (ObjDesc->Field.AccessByteWidth)); 598 599 if (!ObjDesc->IndexField.DataObj || !ObjDesc->IndexField.IndexObj) 600 { 601 ACPI_REPORT_ERROR (("Null Index Object during field prep\n")); 602 AcpiUtDeleteObjectDesc (ObjDesc); 603 return_ACPI_STATUS (AE_AML_INTERNAL); 604 } 605 606 /* An additional reference for the attached objects */ 607 608 AcpiUtAddReference (ObjDesc->IndexField.DataObj); 609 AcpiUtAddReference (ObjDesc->IndexField.IndexObj); 610 611 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 612 "IndexField: BitOff %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n", 613 ObjDesc->IndexField.StartFieldBitOffset, 614 ObjDesc->IndexField.BaseByteOffset, 615 ObjDesc->IndexField.Value, 616 ObjDesc->Field.AccessByteWidth, 617 ObjDesc->IndexField.IndexObj, 618 ObjDesc->IndexField.DataObj)); 619 break; 620 621 default: 622 /* No other types should get here */ 623 break; 624 } 625 626 /* 627 * Store the constructed descriptor (ObjDesc) into the parent Node, 628 * preserving the current type of that NamedObj. 629 */ 630 Status = AcpiNsAttachObject (Info->FieldNode, ObjDesc, 631 AcpiNsGetType (Info->FieldNode)); 632 633 ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Set NamedObj %p [%4.4s], ObjDesc %p\n", 634 Info->FieldNode, AcpiUtGetNodeName (Info->FieldNode), ObjDesc)); 635 636 /* Remove local reference to the object */ 637 638 AcpiUtRemoveReference (ObjDesc); 639 return_ACPI_STATUS (Status); 640} 641 642