Print this page
acpica-unix2-20130823
PANKOVs restructure
   1 /******************************************************************************
   2  *
   3  * Module Name: exfldio - Aml Field I/O
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.


  81  *
  82  * PARAMETERS:  ObjDesc                 - Field to be read or written
  83  *              FieldDatumByteOffset    - Byte offset of this datum within the
  84  *                                        parent field
  85  *
  86  * RETURN:      Status
  87  *
  88  * DESCRIPTION: Common processing for AcpiExExtractFromField and
  89  *              AcpiExInsertIntoField.  Initialize the Region if necessary and
  90  *              validate the request.
  91  *
  92  ******************************************************************************/
  93 
  94 static ACPI_STATUS
  95 AcpiExSetupRegion (
  96     ACPI_OPERAND_OBJECT     *ObjDesc,
  97     UINT32                  FieldDatumByteOffset)
  98 {
  99     ACPI_STATUS             Status = AE_OK;
 100     ACPI_OPERAND_OBJECT     *RgnDesc;

 101 
 102 
 103     ACPI_FUNCTION_TRACE_U32 (ExSetupRegion, FieldDatumByteOffset);
 104 
 105 
 106     RgnDesc = ObjDesc->CommonField.RegionObj;
 107 
 108     /* We must have a valid region */
 109 
 110     if (RgnDesc->Common.Type != ACPI_TYPE_REGION)
 111     {
 112         ACPI_ERROR ((AE_INFO, "Needed Region, found type 0x%X (%s)",
 113             RgnDesc->Common.Type,
 114             AcpiUtGetObjectTypeName (RgnDesc)));
 115 
 116         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 117     }
 118 










 119     /*
 120      * If the Region Address and Length have not been previously evaluated,
 121      * evaluate them now and save the results.
 122      */
 123     if (!(RgnDesc->Common.Flags & AOPOBJ_DATA_VALID))
 124     {
 125         Status = AcpiDsGetRegionArguments (RgnDesc);
 126         if (ACPI_FAILURE (Status))
 127         {
 128             return_ACPI_STATUS (Status);
 129         }
 130     }
 131 
 132     /*
 133      * Exit now for SMBus or IPMI address space, it has a non-linear
 134      * address space and the request cannot be directly validated
 135      */
 136     if (RgnDesc->Region.SpaceId == ACPI_ADR_SPACE_SMBUS ||
 137         RgnDesc->Region.SpaceId == ACPI_ADR_SPACE_IPMI)

 138     {
 139         /* SMBus or IPMI has a non-linear address space */
 140 
 141         return_ACPI_STATUS (AE_OK);
 142     }
 143 
 144 #ifdef ACPI_UNDER_DEVELOPMENT
 145     /*
 146      * If the Field access is AnyAcc, we can now compute the optimal
 147      * access (because we know know the length of the parent region)
 148      */
 149     if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
 150     {
 151         if (ACPI_FAILURE (Status))
 152         {
 153             return_ACPI_STATUS (Status);
 154         }
 155     }
 156 #endif
 157 


 273     if ((Function & ACPI_IO_MASK) == ACPI_READ)
 274     {
 275         ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[READ]"));
 276     }
 277     else
 278     {
 279         ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[WRITE]"));
 280     }
 281 
 282     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_BFIELD,
 283         " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n",
 284         AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
 285         RgnDesc->Region.SpaceId,
 286         ObjDesc->CommonField.AccessByteWidth,
 287         ObjDesc->CommonField.BaseByteOffset,
 288         FieldDatumByteOffset,
 289         ACPI_CAST_PTR (void, (RgnDesc->Region.Address + RegionOffset))));
 290 
 291     /* Invoke the appropriate AddressSpace/OpRegion handler */
 292 
 293     Status = AcpiEvAddressSpaceDispatch (RgnDesc, Function, RegionOffset,

 294                 ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth), Value);
 295 
 296     if (ACPI_FAILURE (Status))
 297     {
 298         if (Status == AE_NOT_IMPLEMENTED)
 299         {
 300             ACPI_ERROR ((AE_INFO,
 301                 "Region %s (ID=%u) not implemented",
 302                 AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
 303                 RgnDesc->Region.SpaceId));
 304         }
 305         else if (Status == AE_NOT_EXIST)
 306         {
 307             ACPI_ERROR ((AE_INFO,
 308                 "Region %s (ID=%u) has no handler",
 309                 AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
 310                 RgnDesc->Region.SpaceId));
 311         }
 312     }
 313 


 336 AcpiExRegisterOverflow (
 337     ACPI_OPERAND_OBJECT     *ObjDesc,
 338     UINT64                  Value)
 339 {
 340 
 341     if (ObjDesc->CommonField.BitLength >= ACPI_INTEGER_BIT_SIZE)
 342     {
 343         /*
 344          * The field is large enough to hold the maximum integer, so we can
 345          * never overflow it.
 346          */
 347         return (FALSE);
 348     }
 349 
 350     if (Value >= ((UINT64) 1 << ObjDesc->CommonField.BitLength))
 351     {
 352         /*
 353          * The Value is larger than the maximum value that can fit into
 354          * the register.
 355          */





 356         return (TRUE);
 357     }
 358 
 359     /* The Value will fit into the field with no truncation */
 360 
 361     return (FALSE);
 362 }
 363 
 364 
 365 /*******************************************************************************
 366  *
 367  * FUNCTION:    AcpiExFieldDatumIo
 368  *
 369  * PARAMETERS:  ObjDesc                 - Field to be read
 370  *              FieldDatumByteOffset    - Byte offset of this datum within the
 371  *                                        parent field
 372  *              Value                   - Where to store value (must be 64 bits)
 373  *              ReadWrite               - Read or Write flag
 374  *
 375  * RETURN:      Status


 445                 (ObjDesc->BufferField.BufferObj)->Buffer.Pointer +
 446                     ObjDesc->BufferField.BaseByteOffset +
 447                     FieldDatumByteOffset,
 448                 ObjDesc->CommonField.AccessByteWidth);
 449         }
 450         else
 451         {
 452             /*
 453              * Copy the data to the target buffer.
 454              * Length is the field width in bytes.
 455              */
 456             ACPI_MEMCPY ((ObjDesc->BufferField.BufferObj)->Buffer.Pointer +
 457                 ObjDesc->BufferField.BaseByteOffset +
 458                 FieldDatumByteOffset,
 459                 Value, ObjDesc->CommonField.AccessByteWidth);
 460         }
 461 
 462         Status = AE_OK;
 463         break;
 464 
 465 
 466     case ACPI_TYPE_LOCAL_BANK_FIELD:
 467 
 468         /*
 469          * Ensure that the BankValue is not beyond the capacity of
 470          * the register
 471          */
 472         if (AcpiExRegisterOverflow (ObjDesc->BankField.BankObj,
 473                 (UINT64) ObjDesc->BankField.Value))
 474         {
 475             return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
 476         }
 477 
 478         /*
 479          * For BankFields, we must write the BankValue to the BankRegister
 480          * (itself a RegionField) before we can access the data.
 481          */
 482         Status = AcpiExInsertIntoField (ObjDesc->BankField.BankObj,
 483                     &ObjDesc->BankField.Value,
 484                     sizeof (ObjDesc->BankField.Value));
 485         if (ACPI_FAILURE (Status))
 486         {
 487             return_ACPI_STATUS (Status);
 488         }
 489 
 490         /*
 491          * Now that the Bank has been selected, fall through to the
 492          * RegionField case and write the datum to the Operation Region
 493          */
 494 
 495         /*lint -fallthrough */
 496 
 497 
 498     case ACPI_TYPE_LOCAL_REGION_FIELD:
 499         /*
 500          * For simple RegionFields, we just directly access the owning
 501          * Operation Region.
 502          */
 503         Status = AcpiExAccessRegion (ObjDesc, FieldDatumByteOffset, Value,
 504                     ReadWrite);
 505         break;
 506 
 507 
 508     case ACPI_TYPE_LOCAL_INDEX_FIELD:
 509 
 510 
 511         /*
 512          * Ensure that the IndexValue is not beyond the capacity of
 513          * the register
 514          */
 515         if (AcpiExRegisterOverflow (ObjDesc->IndexField.IndexObj,
 516                 (UINT64) ObjDesc->IndexField.Value))
 517         {
 518             return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
 519         }
 520 
 521         /* Write the index value to the IndexRegister (itself a RegionField) */
 522 
 523         FieldDatumByteOffset += ObjDesc->IndexField.Value;
 524 
 525         ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 526             "Write to Index Register: Value %8.8X\n",
 527             FieldDatumByteOffset));
 528 
 529         Status = AcpiExInsertIntoField (ObjDesc->IndexField.IndexObj,
 530                     &FieldDatumByteOffset,


 540 
 541             ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 542                 "Read from Data Register\n"));
 543 
 544             Status = AcpiExExtractFromField (ObjDesc->IndexField.DataObj,
 545                         Value, sizeof (UINT64));
 546         }
 547         else
 548         {
 549             /* Write the datum to the DataRegister */
 550 
 551             ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 552                 "Write to Data Register: Value %8.8X%8.8X\n",
 553                 ACPI_FORMAT_UINT64 (*Value)));
 554 
 555             Status = AcpiExInsertIntoField (ObjDesc->IndexField.DataObj,
 556                         Value, sizeof (UINT64));
 557         }
 558         break;
 559 
 560 
 561     default:
 562 
 563         ACPI_ERROR ((AE_INFO, "Wrong object type in field I/O %u",
 564             ObjDesc->Common.Type));
 565         Status = AE_AML_INTERNAL;
 566         break;
 567     }
 568 
 569     if (ACPI_SUCCESS (Status))
 570     {
 571         if (ReadWrite == ACPI_READ)
 572         {
 573             ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 574                 "Value Read %8.8X%8.8X, Width %u\n",
 575                 ACPI_FORMAT_UINT64 (*Value),
 576                 ObjDesc->CommonField.AccessByteWidth));
 577         }
 578         else
 579         {
 580             ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,


 731     /* Validate target buffer and clear it */
 732 
 733     if (BufferLength <
 734         ACPI_ROUND_BITS_UP_TO_BYTES (ObjDesc->CommonField.BitLength))
 735     {
 736         ACPI_ERROR ((AE_INFO,
 737             "Field size %u (bits) is too large for buffer (%u)",
 738             ObjDesc->CommonField.BitLength, BufferLength));
 739 
 740         return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
 741     }
 742 
 743     ACPI_MEMSET (Buffer, 0, BufferLength);
 744     AccessBitWidth = ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth);
 745 
 746     /* Handle the simple case here */
 747 
 748     if ((ObjDesc->CommonField.StartFieldBitOffset == 0) &&
 749         (ObjDesc->CommonField.BitLength == AccessBitWidth))
 750     {


 751         Status = AcpiExFieldDatumIo (ObjDesc, 0, Buffer, ACPI_READ);









 752         return_ACPI_STATUS (Status);
 753     }
 754 
 755 /* TBD: Move to common setup code */
 756 
 757     /* Field algorithm is limited to sizeof(UINT64), truncate if needed */
 758 
 759     if (ObjDesc->CommonField.AccessByteWidth > sizeof (UINT64))
 760     {
 761         ObjDesc->CommonField.AccessByteWidth = sizeof (UINT64);
 762         AccessBitWidth = sizeof (UINT64) * 8;
 763     }
 764 
 765     /* Compute the number of datums (access width data items) */
 766 
 767     DatumCount = ACPI_ROUND_UP_TO (
 768         ObjDesc->CommonField.BitLength, AccessBitWidth);
 769 
 770     FieldDatumCount = ACPI_ROUND_UP_TO (
 771         ObjDesc->CommonField.BitLength +


1016     if (BufferTailBits)
1017     {
1018         Mask &= ACPI_MASK_BITS_ABOVE (BufferTailBits);
1019     }
1020 
1021     /* Write the last datum to the field */
1022 
1023     MergedDatum &= Mask;
1024     Status = AcpiExWriteWithUpdateRule (ObjDesc,
1025                 Mask, MergedDatum, FieldOffset);
1026 
1027 Exit:
1028     /* Free temporary buffer if we used one */
1029 
1030     if (NewBuffer)
1031     {
1032         ACPI_FREE (NewBuffer);
1033     }
1034     return_ACPI_STATUS (Status);
1035 }
1036 
1037 
   1 /******************************************************************************
   2  *
   3  * Module Name: exfldio - Aml Field I/O
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2013, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.


  81  *
  82  * PARAMETERS:  ObjDesc                 - Field to be read or written
  83  *              FieldDatumByteOffset    - Byte offset of this datum within the
  84  *                                        parent field
  85  *
  86  * RETURN:      Status
  87  *
  88  * DESCRIPTION: Common processing for AcpiExExtractFromField and
  89  *              AcpiExInsertIntoField. Initialize the Region if necessary and
  90  *              validate the request.
  91  *
  92  ******************************************************************************/
  93 
  94 static ACPI_STATUS
  95 AcpiExSetupRegion (
  96     ACPI_OPERAND_OBJECT     *ObjDesc,
  97     UINT32                  FieldDatumByteOffset)
  98 {
  99     ACPI_STATUS             Status = AE_OK;
 100     ACPI_OPERAND_OBJECT     *RgnDesc;
 101     UINT8                   SpaceId;
 102 
 103 
 104     ACPI_FUNCTION_TRACE_U32 (ExSetupRegion, FieldDatumByteOffset);
 105 
 106 
 107     RgnDesc = ObjDesc->CommonField.RegionObj;
 108 
 109     /* We must have a valid region */
 110 
 111     if (RgnDesc->Common.Type != ACPI_TYPE_REGION)
 112     {
 113         ACPI_ERROR ((AE_INFO, "Needed Region, found type 0x%X (%s)",
 114             RgnDesc->Common.Type,
 115             AcpiUtGetObjectTypeName (RgnDesc)));
 116 
 117         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 118     }
 119 
 120     SpaceId = RgnDesc->Region.SpaceId;
 121 
 122     /* Validate the Space ID */
 123 
 124     if (!AcpiIsValidSpaceId (SpaceId))
 125     {
 126         ACPI_ERROR ((AE_INFO, "Invalid/unknown Address Space ID: 0x%2.2X", SpaceId));
 127         return_ACPI_STATUS (AE_AML_INVALID_SPACE_ID);
 128     }
 129 
 130     /*
 131      * If the Region Address and Length have not been previously evaluated,
 132      * evaluate them now and save the results.
 133      */
 134     if (!(RgnDesc->Common.Flags & AOPOBJ_DATA_VALID))
 135     {
 136         Status = AcpiDsGetRegionArguments (RgnDesc);
 137         if (ACPI_FAILURE (Status))
 138         {
 139             return_ACPI_STATUS (Status);
 140         }
 141     }
 142 
 143     /*
 144      * Exit now for SMBus, GSBus or IPMI address space, it has a non-linear
 145      * address space and the request cannot be directly validated
 146      */
 147     if (SpaceId == ACPI_ADR_SPACE_SMBUS ||
 148         SpaceId == ACPI_ADR_SPACE_GSBUS ||
 149         SpaceId == ACPI_ADR_SPACE_IPMI)
 150     {
 151         /* SMBus or IPMI has a non-linear address space */
 152 
 153         return_ACPI_STATUS (AE_OK);
 154     }
 155 
 156 #ifdef ACPI_UNDER_DEVELOPMENT
 157     /*
 158      * If the Field access is AnyAcc, we can now compute the optimal
 159      * access (because we know know the length of the parent region)
 160      */
 161     if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
 162     {
 163         if (ACPI_FAILURE (Status))
 164         {
 165             return_ACPI_STATUS (Status);
 166         }
 167     }
 168 #endif
 169 


 285     if ((Function & ACPI_IO_MASK) == ACPI_READ)
 286     {
 287         ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[READ]"));
 288     }
 289     else
 290     {
 291         ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[WRITE]"));
 292     }
 293 
 294     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_BFIELD,
 295         " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n",
 296         AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
 297         RgnDesc->Region.SpaceId,
 298         ObjDesc->CommonField.AccessByteWidth,
 299         ObjDesc->CommonField.BaseByteOffset,
 300         FieldDatumByteOffset,
 301         ACPI_CAST_PTR (void, (RgnDesc->Region.Address + RegionOffset))));
 302 
 303     /* Invoke the appropriate AddressSpace/OpRegion handler */
 304 
 305     Status = AcpiEvAddressSpaceDispatch (RgnDesc, ObjDesc,
 306                 Function, RegionOffset,
 307                 ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth), Value);
 308 
 309     if (ACPI_FAILURE (Status))
 310     {
 311         if (Status == AE_NOT_IMPLEMENTED)
 312         {
 313             ACPI_ERROR ((AE_INFO,
 314                 "Region %s (ID=%u) not implemented",
 315                 AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
 316                 RgnDesc->Region.SpaceId));
 317         }
 318         else if (Status == AE_NOT_EXIST)
 319         {
 320             ACPI_ERROR ((AE_INFO,
 321                 "Region %s (ID=%u) has no handler",
 322                 AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
 323                 RgnDesc->Region.SpaceId));
 324         }
 325     }
 326 


 349 AcpiExRegisterOverflow (
 350     ACPI_OPERAND_OBJECT     *ObjDesc,
 351     UINT64                  Value)
 352 {
 353 
 354     if (ObjDesc->CommonField.BitLength >= ACPI_INTEGER_BIT_SIZE)
 355     {
 356         /*
 357          * The field is large enough to hold the maximum integer, so we can
 358          * never overflow it.
 359          */
 360         return (FALSE);
 361     }
 362 
 363     if (Value >= ((UINT64) 1 << ObjDesc->CommonField.BitLength))
 364     {
 365         /*
 366          * The Value is larger than the maximum value that can fit into
 367          * the register.
 368          */
 369         ACPI_ERROR ((AE_INFO,
 370             "Index value 0x%8.8X%8.8X overflows field width 0x%X",
 371             ACPI_FORMAT_UINT64 (Value),
 372             ObjDesc->CommonField.BitLength));
 373 
 374         return (TRUE);
 375     }
 376 
 377     /* The Value will fit into the field with no truncation */
 378 
 379     return (FALSE);
 380 }
 381 
 382 
 383 /*******************************************************************************
 384  *
 385  * FUNCTION:    AcpiExFieldDatumIo
 386  *
 387  * PARAMETERS:  ObjDesc                 - Field to be read
 388  *              FieldDatumByteOffset    - Byte offset of this datum within the
 389  *                                        parent field
 390  *              Value                   - Where to store value (must be 64 bits)
 391  *              ReadWrite               - Read or Write flag
 392  *
 393  * RETURN:      Status


 463                 (ObjDesc->BufferField.BufferObj)->Buffer.Pointer +
 464                     ObjDesc->BufferField.BaseByteOffset +
 465                     FieldDatumByteOffset,
 466                 ObjDesc->CommonField.AccessByteWidth);
 467         }
 468         else
 469         {
 470             /*
 471              * Copy the data to the target buffer.
 472              * Length is the field width in bytes.
 473              */
 474             ACPI_MEMCPY ((ObjDesc->BufferField.BufferObj)->Buffer.Pointer +
 475                 ObjDesc->BufferField.BaseByteOffset +
 476                 FieldDatumByteOffset,
 477                 Value, ObjDesc->CommonField.AccessByteWidth);
 478         }
 479 
 480         Status = AE_OK;
 481         break;
 482 

 483     case ACPI_TYPE_LOCAL_BANK_FIELD:

 484         /*
 485          * Ensure that the BankValue is not beyond the capacity of
 486          * the register
 487          */
 488         if (AcpiExRegisterOverflow (ObjDesc->BankField.BankObj,
 489                 (UINT64) ObjDesc->BankField.Value))
 490         {
 491             return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
 492         }
 493 
 494         /*
 495          * For BankFields, we must write the BankValue to the BankRegister
 496          * (itself a RegionField) before we can access the data.
 497          */
 498         Status = AcpiExInsertIntoField (ObjDesc->BankField.BankObj,
 499                     &ObjDesc->BankField.Value,
 500                     sizeof (ObjDesc->BankField.Value));
 501         if (ACPI_FAILURE (Status))
 502         {
 503             return_ACPI_STATUS (Status);
 504         }
 505 
 506         /*
 507          * Now that the Bank has been selected, fall through to the
 508          * RegionField case and write the datum to the Operation Region
 509          */
 510 
 511         /*lint -fallthrough */
 512 

 513     case ACPI_TYPE_LOCAL_REGION_FIELD:
 514         /*
 515          * For simple RegionFields, we just directly access the owning
 516          * Operation Region.
 517          */
 518         Status = AcpiExAccessRegion (ObjDesc, FieldDatumByteOffset, Value,
 519                     ReadWrite);
 520         break;
 521 

 522     case ACPI_TYPE_LOCAL_INDEX_FIELD:


 523         /*
 524          * Ensure that the IndexValue is not beyond the capacity of
 525          * the register
 526          */
 527         if (AcpiExRegisterOverflow (ObjDesc->IndexField.IndexObj,
 528                 (UINT64) ObjDesc->IndexField.Value))
 529         {
 530             return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
 531         }
 532 
 533         /* Write the index value to the IndexRegister (itself a RegionField) */
 534 
 535         FieldDatumByteOffset += ObjDesc->IndexField.Value;
 536 
 537         ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 538             "Write to Index Register: Value %8.8X\n",
 539             FieldDatumByteOffset));
 540 
 541         Status = AcpiExInsertIntoField (ObjDesc->IndexField.IndexObj,
 542                     &FieldDatumByteOffset,


 552 
 553             ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 554                 "Read from Data Register\n"));
 555 
 556             Status = AcpiExExtractFromField (ObjDesc->IndexField.DataObj,
 557                         Value, sizeof (UINT64));
 558         }
 559         else
 560         {
 561             /* Write the datum to the DataRegister */
 562 
 563             ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 564                 "Write to Data Register: Value %8.8X%8.8X\n",
 565                 ACPI_FORMAT_UINT64 (*Value)));
 566 
 567             Status = AcpiExInsertIntoField (ObjDesc->IndexField.DataObj,
 568                         Value, sizeof (UINT64));
 569         }
 570         break;
 571 

 572     default:
 573 
 574         ACPI_ERROR ((AE_INFO, "Wrong object type in field I/O %u",
 575             ObjDesc->Common.Type));
 576         Status = AE_AML_INTERNAL;
 577         break;
 578     }
 579 
 580     if (ACPI_SUCCESS (Status))
 581     {
 582         if (ReadWrite == ACPI_READ)
 583         {
 584             ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 585                 "Value Read %8.8X%8.8X, Width %u\n",
 586                 ACPI_FORMAT_UINT64 (*Value),
 587                 ObjDesc->CommonField.AccessByteWidth));
 588         }
 589         else
 590         {
 591             ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,


 742     /* Validate target buffer and clear it */
 743 
 744     if (BufferLength <
 745         ACPI_ROUND_BITS_UP_TO_BYTES (ObjDesc->CommonField.BitLength))
 746     {
 747         ACPI_ERROR ((AE_INFO,
 748             "Field size %u (bits) is too large for buffer (%u)",
 749             ObjDesc->CommonField.BitLength, BufferLength));
 750 
 751         return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
 752     }
 753 
 754     ACPI_MEMSET (Buffer, 0, BufferLength);
 755     AccessBitWidth = ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth);
 756 
 757     /* Handle the simple case here */
 758 
 759     if ((ObjDesc->CommonField.StartFieldBitOffset == 0) &&
 760         (ObjDesc->CommonField.BitLength == AccessBitWidth))
 761     {
 762         if (BufferLength >= sizeof (UINT64))
 763         {
 764             Status = AcpiExFieldDatumIo (ObjDesc, 0, Buffer, ACPI_READ);
 765         }
 766         else
 767         {
 768             /* Use RawDatum (UINT64) to handle buffers < 64 bits */
 769 
 770             Status = AcpiExFieldDatumIo (ObjDesc, 0, &RawDatum, ACPI_READ);
 771             ACPI_MEMCPY (Buffer, &RawDatum, BufferLength);
 772         }
 773 
 774         return_ACPI_STATUS (Status);
 775     }
 776 
 777 /* TBD: Move to common setup code */
 778 
 779     /* Field algorithm is limited to sizeof(UINT64), truncate if needed */
 780 
 781     if (ObjDesc->CommonField.AccessByteWidth > sizeof (UINT64))
 782     {
 783         ObjDesc->CommonField.AccessByteWidth = sizeof (UINT64);
 784         AccessBitWidth = sizeof (UINT64) * 8;
 785     }
 786 
 787     /* Compute the number of datums (access width data items) */
 788 
 789     DatumCount = ACPI_ROUND_UP_TO (
 790         ObjDesc->CommonField.BitLength, AccessBitWidth);
 791 
 792     FieldDatumCount = ACPI_ROUND_UP_TO (
 793         ObjDesc->CommonField.BitLength +


1038     if (BufferTailBits)
1039     {
1040         Mask &= ACPI_MASK_BITS_ABOVE (BufferTailBits);
1041     }
1042 
1043     /* Write the last datum to the field */
1044 
1045     MergedDatum &= Mask;
1046     Status = AcpiExWriteWithUpdateRule (ObjDesc,
1047                 Mask, MergedDatum, FieldOffset);
1048 
1049 Exit:
1050     /* Free temporary buffer if we used one */
1051 
1052     if (NewBuffer)
1053     {
1054         ACPI_FREE (NewBuffer);
1055     }
1056     return_ACPI_STATUS (Status);
1057 }