1db2bae30SDana Myers /****************************************************************************** 2db2bae30SDana Myers * 3*385cc6b4SJerry Jelinek * Module Name: exprep - ACPI AML field prep utilities 4db2bae30SDana Myers * 5db2bae30SDana Myers *****************************************************************************/ 6db2bae30SDana Myers 726f3cdf0SGordon Ross /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 9db2bae30SDana Myers * All rights reserved. 10db2bae30SDana Myers * 1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1326f3cdf0SGordon Ross * are met: 1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1626f3cdf0SGordon Ross * without modification. 1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2126f3cdf0SGordon Ross * binary redistribution. 2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2426f3cdf0SGordon Ross * from this software without specific prior written permission. 25db2bae30SDana Myers * 2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2826f3cdf0SGordon Ross * Software Foundation. 29db2bae30SDana Myers * 3026f3cdf0SGordon Ross * NO WARRANTY 3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4226f3cdf0SGordon Ross */ 43db2bae30SDana Myers 44db2bae30SDana Myers #include "acpi.h" 45aa2aa9a6SDana Myers #include "accommon.h" 46db2bae30SDana Myers #include "acinterp.h" 47db2bae30SDana Myers #include "amlcode.h" 48db2bae30SDana Myers #include "acnamesp.h" 49*385cc6b4SJerry Jelinek #include "acdispat.h" 50db2bae30SDana Myers 51db2bae30SDana Myers 52db2bae30SDana Myers #define _COMPONENT ACPI_EXECUTER 53db2bae30SDana Myers ACPI_MODULE_NAME ("exprep") 54db2bae30SDana Myers 55db2bae30SDana Myers /* Local prototypes */ 56db2bae30SDana Myers 57db2bae30SDana Myers static UINT32 58db2bae30SDana Myers AcpiExDecodeFieldAccess ( 59db2bae30SDana Myers ACPI_OPERAND_OBJECT *ObjDesc, 60db2bae30SDana Myers UINT8 FieldFlags, 61db2bae30SDana Myers UINT32 *ReturnByteAlignment); 62db2bae30SDana Myers 63db2bae30SDana Myers 64db2bae30SDana Myers #ifdef ACPI_UNDER_DEVELOPMENT 65db2bae30SDana Myers 66db2bae30SDana Myers static UINT32 67db2bae30SDana Myers AcpiExGenerateAccess ( 68db2bae30SDana Myers UINT32 FieldBitOffset, 69db2bae30SDana Myers UINT32 FieldBitLength, 70db2bae30SDana Myers UINT32 RegionLength); 71db2bae30SDana Myers 72*385cc6b4SJerry Jelinek 73db2bae30SDana Myers /******************************************************************************* 74db2bae30SDana Myers * 75db2bae30SDana Myers * FUNCTION: AcpiExGenerateAccess 76db2bae30SDana Myers * 77db2bae30SDana Myers * PARAMETERS: FieldBitOffset - Start of field within parent region/buffer 78db2bae30SDana Myers * FieldBitLength - Length of field in bits 79db2bae30SDana Myers * RegionLength - Length of parent in bytes 80db2bae30SDana Myers * 81db2bae30SDana Myers * RETURN: Field granularity (8, 16, 32 or 64) and 82db2bae30SDana Myers * ByteAlignment (1, 2, 3, or 4) 83db2bae30SDana Myers * 84db2bae30SDana Myers * DESCRIPTION: Generate an optimal access width for fields defined with the 85db2bae30SDana Myers * AnyAcc keyword. 86db2bae30SDana Myers * 87db2bae30SDana Myers * NOTE: Need to have the RegionLength in order to check for boundary 88db2bae30SDana Myers * conditions (end-of-region). However, the RegionLength is a deferred 89db2bae30SDana Myers * operation. Therefore, to complete this implementation, the generation 90db2bae30SDana Myers * of this access width must be deferred until the region length has 91db2bae30SDana Myers * been evaluated. 92db2bae30SDana Myers * 93db2bae30SDana Myers ******************************************************************************/ 94db2bae30SDana Myers 95db2bae30SDana Myers static UINT32 96db2bae30SDana Myers AcpiExGenerateAccess ( 97db2bae30SDana Myers UINT32 FieldBitOffset, 98db2bae30SDana Myers UINT32 FieldBitLength, 99db2bae30SDana Myers UINT32 RegionLength) 100db2bae30SDana Myers { 101db2bae30SDana Myers UINT32 FieldByteLength; 102db2bae30SDana Myers UINT32 FieldByteOffset; 103db2bae30SDana Myers UINT32 FieldByteEndOffset; 104db2bae30SDana Myers UINT32 AccessByteWidth; 105db2bae30SDana Myers UINT32 FieldStartOffset; 106db2bae30SDana Myers UINT32 FieldEndOffset; 107db2bae30SDana Myers UINT32 MinimumAccessWidth = 0xFFFFFFFF; 108db2bae30SDana Myers UINT32 MinimumAccesses = 0xFFFFFFFF; 109db2bae30SDana Myers UINT32 Accesses; 110db2bae30SDana Myers 111db2bae30SDana Myers 112db2bae30SDana Myers ACPI_FUNCTION_TRACE (ExGenerateAccess); 113db2bae30SDana Myers 114db2bae30SDana Myers 115db2bae30SDana Myers /* Round Field start offset and length to "minimal" byte boundaries */ 116db2bae30SDana Myers 117*385cc6b4SJerry Jelinek FieldByteOffset = ACPI_DIV_8 ( 118*385cc6b4SJerry Jelinek ACPI_ROUND_DOWN (FieldBitOffset, 8)); 119*385cc6b4SJerry Jelinek 120*385cc6b4SJerry Jelinek FieldByteEndOffset = ACPI_DIV_8 ( 121*385cc6b4SJerry Jelinek ACPI_ROUND_UP (FieldBitLength + FieldBitOffset, 8)); 122*385cc6b4SJerry Jelinek 123db2bae30SDana Myers FieldByteLength = FieldByteEndOffset - FieldByteOffset; 124db2bae30SDana Myers 125db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 12626f3cdf0SGordon Ross "Bit length %u, Bit offset %u\n", 127db2bae30SDana Myers FieldBitLength, FieldBitOffset)); 128db2bae30SDana Myers 129db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 13026f3cdf0SGordon Ross "Byte Length %u, Byte Offset %u, End Offset %u\n", 131db2bae30SDana Myers FieldByteLength, FieldByteOffset, FieldByteEndOffset)); 132db2bae30SDana Myers 133db2bae30SDana Myers /* 134db2bae30SDana Myers * Iterative search for the maximum access width that is both aligned 135db2bae30SDana Myers * and does not go beyond the end of the region 136db2bae30SDana Myers * 137db2bae30SDana Myers * Start at ByteAcc and work upwards to QwordAcc max. (1,2,4,8 bytes) 138db2bae30SDana Myers */ 139db2bae30SDana Myers for (AccessByteWidth = 1; AccessByteWidth <= 8; AccessByteWidth <<= 1) 140db2bae30SDana Myers { 141db2bae30SDana Myers /* 142db2bae30SDana Myers * 1) Round end offset up to next access boundary and make sure that 143db2bae30SDana Myers * this does not go beyond the end of the parent region. 144db2bae30SDana Myers * 2) When the Access width is greater than the FieldByteLength, we 145db2bae30SDana Myers * are done. (This does not optimize for the perfectly aligned 146db2bae30SDana Myers * case yet). 147db2bae30SDana Myers */ 148*385cc6b4SJerry Jelinek if (ACPI_ROUND_UP (FieldByteEndOffset, AccessByteWidth) <= 149*385cc6b4SJerry Jelinek RegionLength) 150db2bae30SDana Myers { 151db2bae30SDana Myers FieldStartOffset = 152db2bae30SDana Myers ACPI_ROUND_DOWN (FieldByteOffset, AccessByteWidth) / 153db2bae30SDana Myers AccessByteWidth; 154db2bae30SDana Myers 155db2bae30SDana Myers FieldEndOffset = 156db2bae30SDana Myers ACPI_ROUND_UP ((FieldByteLength + FieldByteOffset), 157db2bae30SDana Myers AccessByteWidth) / AccessByteWidth; 158db2bae30SDana Myers 159db2bae30SDana Myers Accesses = FieldEndOffset - FieldStartOffset; 160db2bae30SDana Myers 161db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 16226f3cdf0SGordon Ross "AccessWidth %u end is within region\n", AccessByteWidth)); 163db2bae30SDana Myers 164db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 16526f3cdf0SGordon Ross "Field Start %u, Field End %u -- requires %u accesses\n", 166db2bae30SDana Myers FieldStartOffset, FieldEndOffset, Accesses)); 167db2bae30SDana Myers 168db2bae30SDana Myers /* Single access is optimal */ 169db2bae30SDana Myers 170db2bae30SDana Myers if (Accesses <= 1) 171db2bae30SDana Myers { 172db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 173*385cc6b4SJerry Jelinek "Entire field can be accessed " 174*385cc6b4SJerry Jelinek "with one operation of size %u\n", 175db2bae30SDana Myers AccessByteWidth)); 176db2bae30SDana Myers return_VALUE (AccessByteWidth); 177db2bae30SDana Myers } 178db2bae30SDana Myers 179db2bae30SDana Myers /* 180db2bae30SDana Myers * Fits in the region, but requires more than one read/write. 181db2bae30SDana Myers * try the next wider access on next iteration 182db2bae30SDana Myers */ 183db2bae30SDana Myers if (Accesses < MinimumAccesses) 184db2bae30SDana Myers { 185db2bae30SDana Myers MinimumAccesses = Accesses; 186db2bae30SDana Myers MinimumAccessWidth = AccessByteWidth; 187db2bae30SDana Myers } 188db2bae30SDana Myers } 189db2bae30SDana Myers else 190db2bae30SDana Myers { 191db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 192*385cc6b4SJerry Jelinek "AccessWidth %u end is NOT within region\n", 193*385cc6b4SJerry Jelinek AccessByteWidth)); 194db2bae30SDana Myers if (AccessByteWidth == 1) 195db2bae30SDana Myers { 196db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 197db2bae30SDana Myers "Field goes beyond end-of-region!\n")); 198db2bae30SDana Myers 199db2bae30SDana Myers /* Field does not fit in the region at all */ 200db2bae30SDana Myers 201db2bae30SDana Myers return_VALUE (0); 202db2bae30SDana Myers } 203db2bae30SDana Myers 204db2bae30SDana Myers /* 205db2bae30SDana Myers * This width goes beyond the end-of-region, back off to 206db2bae30SDana Myers * previous access 207db2bae30SDana Myers */ 208db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 20926f3cdf0SGordon Ross "Backing off to previous optimal access width of %u\n", 210db2bae30SDana Myers MinimumAccessWidth)); 211db2bae30SDana Myers return_VALUE (MinimumAccessWidth); 212db2bae30SDana Myers } 213db2bae30SDana Myers } 214db2bae30SDana Myers 215db2bae30SDana Myers /* 216db2bae30SDana Myers * Could not read/write field with one operation, 217db2bae30SDana Myers * just use max access width 218db2bae30SDana Myers */ 219db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 220db2bae30SDana Myers "Cannot access field in one operation, using width 8\n")); 221*385cc6b4SJerry Jelinek 222db2bae30SDana Myers return_VALUE (8); 223db2bae30SDana Myers } 224db2bae30SDana Myers #endif /* ACPI_UNDER_DEVELOPMENT */ 225db2bae30SDana Myers 226db2bae30SDana Myers 227db2bae30SDana Myers /******************************************************************************* 228db2bae30SDana Myers * 229db2bae30SDana Myers * FUNCTION: AcpiExDecodeFieldAccess 230db2bae30SDana Myers * 231db2bae30SDana Myers * PARAMETERS: ObjDesc - Field object 232db2bae30SDana Myers * FieldFlags - Encoded fieldflags (contains access bits) 233db2bae30SDana Myers * ReturnByteAlignment - Where the byte alignment is returned 234db2bae30SDana Myers * 235db2bae30SDana Myers * RETURN: Field granularity (8, 16, 32 or 64) and 236db2bae30SDana Myers * ByteAlignment (1, 2, 3, or 4) 237db2bae30SDana Myers * 238db2bae30SDana Myers * DESCRIPTION: Decode the AccessType bits of a field definition. 239db2bae30SDana Myers * 240db2bae30SDana Myers ******************************************************************************/ 241db2bae30SDana Myers 242db2bae30SDana Myers static UINT32 243db2bae30SDana Myers AcpiExDecodeFieldAccess ( 244db2bae30SDana Myers ACPI_OPERAND_OBJECT *ObjDesc, 245db2bae30SDana Myers UINT8 FieldFlags, 246db2bae30SDana Myers UINT32 *ReturnByteAlignment) 247db2bae30SDana Myers { 248db2bae30SDana Myers UINT32 Access; 249db2bae30SDana Myers UINT32 ByteAlignment; 250db2bae30SDana Myers UINT32 BitLength; 251db2bae30SDana Myers 252db2bae30SDana Myers 253db2bae30SDana Myers ACPI_FUNCTION_TRACE (ExDecodeFieldAccess); 254db2bae30SDana Myers 255db2bae30SDana Myers 256db2bae30SDana Myers Access = (FieldFlags & AML_FIELD_ACCESS_TYPE_MASK); 257db2bae30SDana Myers 258db2bae30SDana Myers switch (Access) 259db2bae30SDana Myers { 260db2bae30SDana Myers case AML_FIELD_ACCESS_ANY: 261db2bae30SDana Myers 262db2bae30SDana Myers #ifdef ACPI_UNDER_DEVELOPMENT 263db2bae30SDana Myers ByteAlignment = 264db2bae30SDana Myers AcpiExGenerateAccess (ObjDesc->CommonField.StartFieldBitOffset, 265db2bae30SDana Myers ObjDesc->CommonField.BitLength, 266db2bae30SDana Myers 0xFFFFFFFF /* Temp until we pass RegionLength as parameter */); 267db2bae30SDana Myers BitLength = ByteAlignment * 8; 268db2bae30SDana Myers #endif 269db2bae30SDana Myers 270db2bae30SDana Myers ByteAlignment = 1; 271db2bae30SDana Myers BitLength = 8; 272db2bae30SDana Myers break; 273db2bae30SDana Myers 274db2bae30SDana Myers case AML_FIELD_ACCESS_BYTE: 275db2bae30SDana Myers case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 (SMBus Buffer) */ 276*385cc6b4SJerry Jelinek 277db2bae30SDana Myers ByteAlignment = 1; 278db2bae30SDana Myers BitLength = 8; 279db2bae30SDana Myers break; 280db2bae30SDana Myers 281db2bae30SDana Myers case AML_FIELD_ACCESS_WORD: 282*385cc6b4SJerry Jelinek 283db2bae30SDana Myers ByteAlignment = 2; 284db2bae30SDana Myers BitLength = 16; 285db2bae30SDana Myers break; 286db2bae30SDana Myers 287db2bae30SDana Myers case AML_FIELD_ACCESS_DWORD: 288*385cc6b4SJerry Jelinek 289db2bae30SDana Myers ByteAlignment = 4; 290db2bae30SDana Myers BitLength = 32; 291db2bae30SDana Myers break; 292db2bae30SDana Myers 293db2bae30SDana Myers case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */ 294*385cc6b4SJerry Jelinek 295db2bae30SDana Myers ByteAlignment = 8; 296db2bae30SDana Myers BitLength = 64; 297db2bae30SDana Myers break; 298db2bae30SDana Myers 299db2bae30SDana Myers default: 300*385cc6b4SJerry Jelinek 301db2bae30SDana Myers /* Invalid field access type */ 302db2bae30SDana Myers 303db2bae30SDana Myers ACPI_ERROR ((AE_INFO, 30426f3cdf0SGordon Ross "Unknown field access type 0x%X", 305db2bae30SDana Myers Access)); 306*385cc6b4SJerry Jelinek 307db2bae30SDana Myers return_UINT32 (0); 308db2bae30SDana Myers } 309db2bae30SDana Myers 310aa2aa9a6SDana Myers if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD) 311db2bae30SDana Myers { 312db2bae30SDana Myers /* 313db2bae30SDana Myers * BufferField access can be on any byte boundary, so the 314db2bae30SDana Myers * ByteAlignment is always 1 byte -- regardless of any ByteAlignment 315db2bae30SDana Myers * implied by the field access type. 316db2bae30SDana Myers */ 317db2bae30SDana Myers ByteAlignment = 1; 318db2bae30SDana Myers } 319db2bae30SDana Myers 320db2bae30SDana Myers *ReturnByteAlignment = ByteAlignment; 321db2bae30SDana Myers return_UINT32 (BitLength); 322db2bae30SDana Myers } 323db2bae30SDana Myers 324db2bae30SDana Myers 325db2bae30SDana Myers /******************************************************************************* 326db2bae30SDana Myers * 327db2bae30SDana Myers * FUNCTION: AcpiExPrepCommonFieldObject 328db2bae30SDana Myers * 329db2bae30SDana Myers * PARAMETERS: ObjDesc - The field object 330db2bae30SDana Myers * FieldFlags - Access, LockRule, and UpdateRule. 331db2bae30SDana Myers * The format of a FieldFlag is described 332db2bae30SDana Myers * in the ACPI specification 333db2bae30SDana Myers * FieldAttribute - Special attributes (not used) 334db2bae30SDana Myers * FieldBitPosition - Field start position 335db2bae30SDana Myers * FieldBitLength - Field length in number of bits 336db2bae30SDana Myers * 337db2bae30SDana Myers * RETURN: Status 338db2bae30SDana Myers * 339db2bae30SDana Myers * DESCRIPTION: Initialize the areas of the field object that are common 340db2bae30SDana Myers * to the various types of fields. Note: This is very "sensitive" 341db2bae30SDana Myers * code because we are solving the general case for field 342db2bae30SDana Myers * alignment. 343db2bae30SDana Myers * 344db2bae30SDana Myers ******************************************************************************/ 345db2bae30SDana Myers 346db2bae30SDana Myers ACPI_STATUS 347db2bae30SDana Myers AcpiExPrepCommonFieldObject ( 348db2bae30SDana Myers ACPI_OPERAND_OBJECT *ObjDesc, 349db2bae30SDana Myers UINT8 FieldFlags, 350db2bae30SDana Myers UINT8 FieldAttribute, 351db2bae30SDana Myers UINT32 FieldBitPosition, 352db2bae30SDana Myers UINT32 FieldBitLength) 353db2bae30SDana Myers { 354db2bae30SDana Myers UINT32 AccessBitWidth; 355db2bae30SDana Myers UINT32 ByteAlignment; 356db2bae30SDana Myers UINT32 NearestByteAddress; 357db2bae30SDana Myers 358db2bae30SDana Myers 359db2bae30SDana Myers ACPI_FUNCTION_TRACE (ExPrepCommonFieldObject); 360db2bae30SDana Myers 361db2bae30SDana Myers 362db2bae30SDana Myers /* 363db2bae30SDana Myers * Note: the structure being initialized is the 364db2bae30SDana Myers * ACPI_COMMON_FIELD_INFO; No structure fields outside of the common 365db2bae30SDana Myers * area are initialized by this procedure. 366db2bae30SDana Myers */ 367db2bae30SDana Myers ObjDesc->CommonField.FieldFlags = FieldFlags; 368db2bae30SDana Myers ObjDesc->CommonField.Attribute = FieldAttribute; 369db2bae30SDana Myers ObjDesc->CommonField.BitLength = FieldBitLength; 370db2bae30SDana Myers 371db2bae30SDana Myers /* 372db2bae30SDana Myers * Decode the access type so we can compute offsets. The access type gives 373db2bae30SDana Myers * two pieces of information - the width of each field access and the 374db2bae30SDana Myers * necessary ByteAlignment (address granularity) of the access. 375db2bae30SDana Myers * 376db2bae30SDana Myers * For AnyAcc, the AccessBitWidth is the largest width that is both 377db2bae30SDana Myers * necessary and possible in an attempt to access the whole field in one 378db2bae30SDana Myers * I/O operation. However, for AnyAcc, the ByteAlignment is always one 379db2bae30SDana Myers * byte. 380db2bae30SDana Myers * 381db2bae30SDana Myers * For all Buffer Fields, the ByteAlignment is always one byte. 382db2bae30SDana Myers * 383db2bae30SDana Myers * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is 384db2bae30SDana Myers * the same (equivalent) as the ByteAlignment. 385db2bae30SDana Myers */ 386*385cc6b4SJerry Jelinek AccessBitWidth = AcpiExDecodeFieldAccess ( 387*385cc6b4SJerry Jelinek ObjDesc, FieldFlags, &ByteAlignment); 388db2bae30SDana Myers if (!AccessBitWidth) 389db2bae30SDana Myers { 390db2bae30SDana Myers return_ACPI_STATUS (AE_AML_OPERAND_VALUE); 391db2bae30SDana Myers } 392db2bae30SDana Myers 39326f3cdf0SGordon Ross /* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */ 394db2bae30SDana Myers 395db2bae30SDana Myers ObjDesc->CommonField.AccessByteWidth = (UINT8) 39626f3cdf0SGordon Ross ACPI_DIV_8 (AccessBitWidth); 397db2bae30SDana Myers 398db2bae30SDana Myers /* 399db2bae30SDana Myers * BaseByteOffset is the address of the start of the field within the 400db2bae30SDana Myers * region. It is the byte address of the first *datum* (field-width data 401db2bae30SDana Myers * unit) of the field. (i.e., the first datum that contains at least the 402db2bae30SDana Myers * first *bit* of the field.) 403db2bae30SDana Myers * 404db2bae30SDana Myers * Note: ByteAlignment is always either equal to the AccessBitWidth or 8 405db2bae30SDana Myers * (Byte access), and it defines the addressing granularity of the parent 406db2bae30SDana Myers * region or buffer. 407db2bae30SDana Myers */ 408db2bae30SDana Myers NearestByteAddress = 409db2bae30SDana Myers ACPI_ROUND_BITS_DOWN_TO_BYTES (FieldBitPosition); 410db2bae30SDana Myers ObjDesc->CommonField.BaseByteOffset = (UINT32) 411db2bae30SDana Myers ACPI_ROUND_DOWN (NearestByteAddress, ByteAlignment); 412db2bae30SDana Myers 413db2bae30SDana Myers /* 414db2bae30SDana Myers * StartFieldBitOffset is the offset of the first bit of the field within 415db2bae30SDana Myers * a field datum. 416db2bae30SDana Myers */ 417db2bae30SDana Myers ObjDesc->CommonField.StartFieldBitOffset = (UINT8) 418db2bae30SDana Myers (FieldBitPosition - ACPI_MUL_8 (ObjDesc->CommonField.BaseByteOffset)); 419db2bae30SDana Myers 420db2bae30SDana Myers return_ACPI_STATUS (AE_OK); 421db2bae30SDana Myers } 422db2bae30SDana Myers 423db2bae30SDana Myers 424db2bae30SDana Myers /******************************************************************************* 425db2bae30SDana Myers * 426db2bae30SDana Myers * FUNCTION: AcpiExPrepFieldValue 427db2bae30SDana Myers * 428db2bae30SDana Myers * PARAMETERS: Info - Contains all field creation info 429db2bae30SDana Myers * 430db2bae30SDana Myers * RETURN: Status 431db2bae30SDana Myers * 432*385cc6b4SJerry Jelinek * DESCRIPTION: Construct an object of type ACPI_OPERAND_OBJECT with a 433*385cc6b4SJerry Jelinek * subtype of DefField and connect it to the parent Node. 434db2bae30SDana Myers * 435db2bae30SDana Myers ******************************************************************************/ 436db2bae30SDana Myers 437db2bae30SDana Myers ACPI_STATUS 438db2bae30SDana Myers AcpiExPrepFieldValue ( 439db2bae30SDana Myers ACPI_CREATE_FIELD_INFO *Info) 440db2bae30SDana Myers { 441db2bae30SDana Myers ACPI_OPERAND_OBJECT *ObjDesc; 442db2bae30SDana Myers ACPI_OPERAND_OBJECT *SecondDesc = NULL; 443db2bae30SDana Myers ACPI_STATUS Status; 44426f3cdf0SGordon Ross UINT32 AccessByteWidth; 44526f3cdf0SGordon Ross UINT32 Type; 446db2bae30SDana Myers 447db2bae30SDana Myers 448db2bae30SDana Myers ACPI_FUNCTION_TRACE (ExPrepFieldValue); 449db2bae30SDana Myers 450db2bae30SDana Myers 451db2bae30SDana Myers /* Parameter validation */ 452db2bae30SDana Myers 453db2bae30SDana Myers if (Info->FieldType != ACPI_TYPE_LOCAL_INDEX_FIELD) 454db2bae30SDana Myers { 455db2bae30SDana Myers if (!Info->RegionNode) 456db2bae30SDana Myers { 457db2bae30SDana Myers ACPI_ERROR ((AE_INFO, "Null RegionNode")); 458db2bae30SDana Myers return_ACPI_STATUS (AE_AML_NO_OPERAND); 459db2bae30SDana Myers } 460db2bae30SDana Myers 461db2bae30SDana Myers Type = AcpiNsGetType (Info->RegionNode); 462db2bae30SDana Myers if (Type != ACPI_TYPE_REGION) 463db2bae30SDana Myers { 46426f3cdf0SGordon Ross ACPI_ERROR ((AE_INFO, "Needed Region, found type 0x%X (%s)", 465db2bae30SDana Myers Type, AcpiUtGetTypeName (Type))); 466db2bae30SDana Myers 467db2bae30SDana Myers return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 468db2bae30SDana Myers } 469db2bae30SDana Myers } 470db2bae30SDana Myers 471db2bae30SDana Myers /* Allocate a new field object */ 472db2bae30SDana Myers 473db2bae30SDana Myers ObjDesc = AcpiUtCreateInternalObject (Info->FieldType); 474db2bae30SDana Myers if (!ObjDesc) 475db2bae30SDana Myers { 476db2bae30SDana Myers return_ACPI_STATUS (AE_NO_MEMORY); 477db2bae30SDana Myers } 478db2bae30SDana Myers 479db2bae30SDana Myers /* Initialize areas of the object that are common to all fields */ 480db2bae30SDana Myers 481db2bae30SDana Myers ObjDesc->CommonField.Node = Info->FieldNode; 48226f3cdf0SGordon Ross Status = AcpiExPrepCommonFieldObject (ObjDesc, 48326f3cdf0SGordon Ross Info->FieldFlags, Info->Attribute, 48426f3cdf0SGordon Ross Info->FieldBitPosition, Info->FieldBitLength); 485db2bae30SDana Myers if (ACPI_FAILURE (Status)) 486db2bae30SDana Myers { 487db2bae30SDana Myers AcpiUtDeleteObjectDesc (ObjDesc); 488db2bae30SDana Myers return_ACPI_STATUS (Status); 489db2bae30SDana Myers } 490db2bae30SDana Myers 491db2bae30SDana Myers /* Initialize areas of the object that are specific to the field type */ 492db2bae30SDana Myers 493db2bae30SDana Myers switch (Info->FieldType) 494db2bae30SDana Myers { 495db2bae30SDana Myers case ACPI_TYPE_LOCAL_REGION_FIELD: 496db2bae30SDana Myers 497db2bae30SDana Myers ObjDesc->Field.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode); 498db2bae30SDana Myers 499*385cc6b4SJerry Jelinek /* Fields specific to GenericSerialBus fields */ 500*385cc6b4SJerry Jelinek 501*385cc6b4SJerry Jelinek ObjDesc->Field.AccessLength = Info->AccessLength; 502*385cc6b4SJerry Jelinek 503*385cc6b4SJerry Jelinek if (Info->ConnectionNode) 504*385cc6b4SJerry Jelinek { 505*385cc6b4SJerry Jelinek SecondDesc = Info->ConnectionNode->Object; 506*385cc6b4SJerry Jelinek if (!(SecondDesc->Common.Flags & AOPOBJ_DATA_VALID)) 507*385cc6b4SJerry Jelinek { 508*385cc6b4SJerry Jelinek Status = AcpiDsGetBufferArguments (SecondDesc); 509*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 510*385cc6b4SJerry Jelinek { 511*385cc6b4SJerry Jelinek AcpiUtDeleteObjectDesc (ObjDesc); 512*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 513*385cc6b4SJerry Jelinek } 514*385cc6b4SJerry Jelinek } 515*385cc6b4SJerry Jelinek 516*385cc6b4SJerry Jelinek ObjDesc->Field.ResourceBuffer = 517*385cc6b4SJerry Jelinek SecondDesc->Buffer.Pointer; 518*385cc6b4SJerry Jelinek ObjDesc->Field.ResourceLength = 519*385cc6b4SJerry Jelinek (UINT16) SecondDesc->Buffer.Length; 520*385cc6b4SJerry Jelinek } 521*385cc6b4SJerry Jelinek else if (Info->ResourceBuffer) 522*385cc6b4SJerry Jelinek { 523*385cc6b4SJerry Jelinek ObjDesc->Field.ResourceBuffer = Info->ResourceBuffer; 524*385cc6b4SJerry Jelinek ObjDesc->Field.ResourceLength = Info->ResourceLength; 525*385cc6b4SJerry Jelinek } 526*385cc6b4SJerry Jelinek 527*385cc6b4SJerry Jelinek ObjDesc->Field.PinNumberIndex = Info->PinNumberIndex; 528*385cc6b4SJerry Jelinek 52926f3cdf0SGordon Ross /* Allow full data read from EC address space */ 53026f3cdf0SGordon Ross 53126f3cdf0SGordon Ross if ((ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_EC) && 53226f3cdf0SGordon Ross (ObjDesc->CommonField.BitLength > 8)) 53326f3cdf0SGordon Ross { 53426f3cdf0SGordon Ross AccessByteWidth = ACPI_ROUND_BITS_UP_TO_BYTES ( 53526f3cdf0SGordon Ross ObjDesc->CommonField.BitLength); 53626f3cdf0SGordon Ross 53726f3cdf0SGordon Ross /* Maximum byte width supported is 255 */ 53826f3cdf0SGordon Ross 53926f3cdf0SGordon Ross if (AccessByteWidth < 256) 54026f3cdf0SGordon Ross { 541*385cc6b4SJerry Jelinek ObjDesc->CommonField.AccessByteWidth = 542*385cc6b4SJerry Jelinek (UINT8) AccessByteWidth; 54326f3cdf0SGordon Ross } 54426f3cdf0SGordon Ross } 54526f3cdf0SGordon Ross 546db2bae30SDana Myers /* An additional reference for the container */ 547db2bae30SDana Myers 548db2bae30SDana Myers AcpiUtAddReference (ObjDesc->Field.RegionObj); 549db2bae30SDana Myers 550db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 551db2bae30SDana Myers "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", 552*385cc6b4SJerry Jelinek ObjDesc->Field.StartFieldBitOffset, 553*385cc6b4SJerry Jelinek ObjDesc->Field.BaseByteOffset, 554*385cc6b4SJerry Jelinek ObjDesc->Field.AccessByteWidth, 555*385cc6b4SJerry Jelinek ObjDesc->Field.RegionObj)); 556db2bae30SDana Myers break; 557db2bae30SDana Myers 558db2bae30SDana Myers case ACPI_TYPE_LOCAL_BANK_FIELD: 559db2bae30SDana Myers 560db2bae30SDana Myers ObjDesc->BankField.Value = Info->BankValue; 56126f3cdf0SGordon Ross ObjDesc->BankField.RegionObj = 56226f3cdf0SGordon Ross AcpiNsGetAttachedObject (Info->RegionNode); 56326f3cdf0SGordon Ross ObjDesc->BankField.BankObj = 56426f3cdf0SGordon Ross AcpiNsGetAttachedObject (Info->RegisterNode); 565db2bae30SDana Myers 566db2bae30SDana Myers /* An additional reference for the attached objects */ 567db2bae30SDana Myers 568db2bae30SDana Myers AcpiUtAddReference (ObjDesc->BankField.RegionObj); 569db2bae30SDana Myers AcpiUtAddReference (ObjDesc->BankField.BankObj); 570db2bae30SDana Myers 571db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 572db2bae30SDana Myers "Bank Field: BitOff %X, Off %X, Gran %X, Region %p, BankReg %p\n", 573db2bae30SDana Myers ObjDesc->BankField.StartFieldBitOffset, 574db2bae30SDana Myers ObjDesc->BankField.BaseByteOffset, 575db2bae30SDana Myers ObjDesc->Field.AccessByteWidth, 576db2bae30SDana Myers ObjDesc->BankField.RegionObj, 577db2bae30SDana Myers ObjDesc->BankField.BankObj)); 578db2bae30SDana Myers 579db2bae30SDana Myers /* 580db2bae30SDana Myers * Remember location in AML stream of the field unit 581db2bae30SDana Myers * opcode and operands -- since the BankValue 582db2bae30SDana Myers * operands must be evaluated. 583db2bae30SDana Myers */ 584db2bae30SDana Myers SecondDesc = ObjDesc->Common.NextObject; 58526f3cdf0SGordon Ross SecondDesc->Extra.AmlStart = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, 58626f3cdf0SGordon Ross Info->DataRegisterNode)->Named.Data; 58726f3cdf0SGordon Ross SecondDesc->Extra.AmlLength = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, 58826f3cdf0SGordon Ross Info->DataRegisterNode)->Named.Length; 589db2bae30SDana Myers 590db2bae30SDana Myers break; 591db2bae30SDana Myers 592db2bae30SDana Myers case ACPI_TYPE_LOCAL_INDEX_FIELD: 593db2bae30SDana Myers 594db2bae30SDana Myers /* Get the Index and Data registers */ 595db2bae30SDana Myers 59626f3cdf0SGordon Ross ObjDesc->IndexField.IndexObj = 59726f3cdf0SGordon Ross AcpiNsGetAttachedObject (Info->RegisterNode); 59826f3cdf0SGordon Ross ObjDesc->IndexField.DataObj = 59926f3cdf0SGordon Ross AcpiNsGetAttachedObject (Info->DataRegisterNode); 600db2bae30SDana Myers 601db2bae30SDana Myers if (!ObjDesc->IndexField.DataObj || !ObjDesc->IndexField.IndexObj) 602db2bae30SDana Myers { 603db2bae30SDana Myers ACPI_ERROR ((AE_INFO, "Null Index Object during field prep")); 604db2bae30SDana Myers AcpiUtDeleteObjectDesc (ObjDesc); 605db2bae30SDana Myers return_ACPI_STATUS (AE_AML_INTERNAL); 606db2bae30SDana Myers } 607db2bae30SDana Myers 608db2bae30SDana Myers /* An additional reference for the attached objects */ 609db2bae30SDana Myers 610db2bae30SDana Myers AcpiUtAddReference (ObjDesc->IndexField.DataObj); 611db2bae30SDana Myers AcpiUtAddReference (ObjDesc->IndexField.IndexObj); 612db2bae30SDana Myers 613db2bae30SDana Myers /* 614db2bae30SDana Myers * April 2006: Changed to match MS behavior 615db2bae30SDana Myers * 616db2bae30SDana Myers * The value written to the Index register is the byte offset of the 617db2bae30SDana Myers * target field in units of the granularity of the IndexField 618db2bae30SDana Myers * 619db2bae30SDana Myers * Previously, the value was calculated as an index in terms of the 620db2bae30SDana Myers * width of the Data register, as below: 621db2bae30SDana Myers * 622db2bae30SDana Myers * ObjDesc->IndexField.Value = (UINT32) 623db2bae30SDana Myers * (Info->FieldBitPosition / ACPI_MUL_8 ( 624db2bae30SDana Myers * ObjDesc->Field.AccessByteWidth)); 625db2bae30SDana Myers * 626db2bae30SDana Myers * February 2006: Tried value as a byte offset: 627db2bae30SDana Myers * ObjDesc->IndexField.Value = (UINT32) 628db2bae30SDana Myers * ACPI_DIV_8 (Info->FieldBitPosition); 629db2bae30SDana Myers */ 630db2bae30SDana Myers ObjDesc->IndexField.Value = (UINT32) ACPI_ROUND_DOWN ( 631db2bae30SDana Myers ACPI_DIV_8 (Info->FieldBitPosition), 632db2bae30SDana Myers ObjDesc->IndexField.AccessByteWidth); 633db2bae30SDana Myers 634db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 635*385cc6b4SJerry Jelinek "IndexField: BitOff %X, Off %X, Value %X, " 636*385cc6b4SJerry Jelinek "Gran %X, Index %p, Data %p\n", 637db2bae30SDana Myers ObjDesc->IndexField.StartFieldBitOffset, 638db2bae30SDana Myers ObjDesc->IndexField.BaseByteOffset, 639db2bae30SDana Myers ObjDesc->IndexField.Value, 640db2bae30SDana Myers ObjDesc->Field.AccessByteWidth, 641db2bae30SDana Myers ObjDesc->IndexField.IndexObj, 642db2bae30SDana Myers ObjDesc->IndexField.DataObj)); 643db2bae30SDana Myers break; 644db2bae30SDana Myers 645db2bae30SDana Myers default: 646*385cc6b4SJerry Jelinek 647db2bae30SDana Myers /* No other types should get here */ 648*385cc6b4SJerry Jelinek 649db2bae30SDana Myers break; 650db2bae30SDana Myers } 651db2bae30SDana Myers 652db2bae30SDana Myers /* 653db2bae30SDana Myers * Store the constructed descriptor (ObjDesc) into the parent Node, 654db2bae30SDana Myers * preserving the current type of that NamedObj. 655db2bae30SDana Myers */ 656*385cc6b4SJerry Jelinek Status = AcpiNsAttachObject ( 657*385cc6b4SJerry Jelinek Info->FieldNode, ObjDesc, AcpiNsGetType (Info->FieldNode)); 658db2bae30SDana Myers 659*385cc6b4SJerry Jelinek ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 660*385cc6b4SJerry Jelinek "Set NamedObj %p [%4.4s], ObjDesc %p\n", 661db2bae30SDana Myers Info->FieldNode, AcpiUtGetNodeName (Info->FieldNode), ObjDesc)); 662db2bae30SDana Myers 663db2bae30SDana Myers /* Remove local reference to the object */ 664db2bae30SDana Myers 665db2bae30SDana Myers AcpiUtRemoveReference (ObjDesc); 666db2bae30SDana Myers return_ACPI_STATUS (Status); 667db2bae30SDana Myers } 668