ReactOS  0.4.14-dev-297-g23e575c
exfldio.c File Reference
#include "acpi.h"
#include "accommon.h"
#include "acinterp.h"
#include "amlcode.h"
#include "acevents.h"
#include "acdispat.h"
Include dependency graph for exfldio.c:

Go to the source code of this file.

Macros

#define _COMPONENT   ACPI_EXECUTER
 

Functions

static ACPI_STATUS AcpiExFieldDatumIo (ACPI_OPERAND_OBJECT *ObjDesc, UINT32 FieldDatumByteOffset, UINT64 *Value, UINT32 ReadWrite)
 
static BOOLEAN AcpiExRegisterOverflow (ACPI_OPERAND_OBJECT *ObjDesc, UINT64 Value)
 
static ACPI_STATUS AcpiExSetupRegion (ACPI_OPERAND_OBJECT *ObjDesc, UINT32 FieldDatumByteOffset)
 
ACPI_STATUS AcpiExAccessRegion (ACPI_OPERAND_OBJECT *ObjDesc, UINT32 FieldDatumByteOffset, UINT64 *Value, UINT32 Function)
 
ACPI_STATUS AcpiExWriteWithUpdateRule (ACPI_OPERAND_OBJECT *ObjDesc, UINT64 Mask, UINT64 FieldValue, UINT32 FieldDatumByteOffset)
 
ACPI_STATUS AcpiExExtractFromField (ACPI_OPERAND_OBJECT *ObjDesc, void *Buffer, UINT32 BufferLength)
 
ACPI_STATUS AcpiExInsertIntoField (ACPI_OPERAND_OBJECT *ObjDesc, void *Buffer, UINT32 BufferLength)
 

Macro Definition Documentation

◆ _COMPONENT

#define _COMPONENT   ACPI_EXECUTER

Definition at line 52 of file exfldio.c.

Function Documentation

◆ AcpiExAccessRegion()

ACPI_STATUS AcpiExAccessRegion ( ACPI_OPERAND_OBJECT ObjDesc,
UINT32  FieldDatumByteOffset,
UINT64 Value,
UINT32  Function 
)

Definition at line 249 of file exfldio.c.

254 {
256  ACPI_OPERAND_OBJECT *RgnDesc;
257  UINT32 RegionOffset;
258 
259 
260  ACPI_FUNCTION_TRACE (ExAccessRegion);
261 
262 
263  /*
264  * Ensure that the region operands are fully evaluated and verify
265  * the validity of the request
266  */
267  Status = AcpiExSetupRegion (ObjDesc, FieldDatumByteOffset);
268  if (ACPI_FAILURE (Status))
269  {
271  }
272 
273  /*
274  * The physical address of this field datum is:
275  *
276  * 1) The base of the region, plus
277  * 2) The base offset of the field, plus
278  * 3) The current offset into the field
279  */
280  RgnDesc = ObjDesc->CommonField.RegionObj;
281  RegionOffset =
282  ObjDesc->CommonField.BaseByteOffset +
283  FieldDatumByteOffset;
284 
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 
295  " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n",
297  RgnDesc->Region.SpaceId,
298  ObjDesc->CommonField.AccessByteWidth,
299  ObjDesc->CommonField.BaseByteOffset,
300  FieldDatumByteOffset,
301  ACPI_FORMAT_UINT64 (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  {
314  "Region %s (ID=%u) not implemented",
316  RgnDesc->Region.SpaceId));
317  }
318  else if (Status == AE_NOT_EXIST)
319  {
321  "Region %s (ID=%u) has no handler",
323  RgnDesc->Region.SpaceId));
324  }
325  }
326 
328 }
#define ACPI_DEBUG_PRINT_RAW(pl)
Definition: acoutput.h:476
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define ACPI_DB_BFIELD
Definition: acoutput.h:168
static ACPI_STATUS AcpiExSetupRegion(ACPI_OPERAND_OBJECT *ObjDesc, UINT32 FieldDatumByteOffset)
Definition: exfldio.c:92
#define ACPI_READ
Definition: actypes.h:742
ACPI_OBJECT_FIELD_COMMON CommonField
Definition: acobject.h:530
#define ACPI_MUL_8(a)
Definition: acmacros.h:215
UINT32 ACPI_STATUS
Definition: actypes.h:460
ACPI_OBJECT_COMMON_HEADER UINT8 SpaceId
Definition: acobject.h:202
#define AE_NOT_IMPLEMENTED
Definition: acexcep.h:122
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
ACPI_STATUS AcpiEvAddressSpaceDispatch(ACPI_OPERAND_OBJECT *RegionObj, ACPI_OPERAND_OBJECT *FieldObj, UINT32 Function, UINT32 RegionOffset, UINT32 BitWidth, UINT64 *Value)
Definition: evregion.c:148
const char * AcpiUtGetRegionName(UINT8 SpaceId)
Definition: utdecode.c:124
static LPOVERLAPPED_COMPLETION_ROUTINE Function
Definition: sync.c:684
unsigned int UINT32
ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object * RegionObj
Definition: acobject.h:335
#define AE_INFO
Definition: acoutput.h:230
ACPI_OBJECT_REGION Region
Definition: acobject.h:524
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
#define AE_NOT_EXIST
Definition: acexcep.h:114
Status
Definition: gdiplustypes.h:24
#define ACPI_IO_MASK
Definition: actypes.h:744
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_FORMAT_UINT64(i)
Definition: acmacros.h:71
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
ACPI_PHYSICAL_ADDRESS Address
Definition: acobject.h:206

Referenced by AcpiExFieldDatumIo(), AcpiExReadGpio(), AcpiExReadSerialBus(), AcpiExWriteDataToField(), AcpiExWriteGpio(), and AcpiExWriteSerialBus().

◆ AcpiExExtractFromField()

ACPI_STATUS AcpiExExtractFromField ( ACPI_OPERAND_OBJECT ObjDesc,
void Buffer,
UINT32  BufferLength 
)

Definition at line 723 of file exfldio.c.

727 {
729  UINT64 RawDatum;
730  UINT64 MergedDatum;
731  UINT32 FieldOffset = 0;
732  UINT32 BufferOffset = 0;
733  UINT32 BufferTailBits;
734  UINT32 DatumCount;
735  UINT32 FieldDatumCount;
736  UINT32 AccessBitWidth;
737  UINT32 i;
738 
739 
740  ACPI_FUNCTION_TRACE (ExExtractFromField);
741 
742 
743  /* Validate target buffer and clear it */
744 
745  if (BufferLength <
746  ACPI_ROUND_BITS_UP_TO_BYTES (ObjDesc->CommonField.BitLength))
747  {
749  "Field size %u (bits) is too large for buffer (%u)",
750  ObjDesc->CommonField.BitLength, BufferLength));
751 
753  }
754 
755  memset (Buffer, 0, BufferLength);
756  AccessBitWidth = ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth);
757 
758  /* Handle the simple case here */
759 
760  if ((ObjDesc->CommonField.StartFieldBitOffset == 0) &&
761  (ObjDesc->CommonField.BitLength == AccessBitWidth))
762  {
763  if (BufferLength >= sizeof (UINT64))
764  {
765  Status = AcpiExFieldDatumIo (ObjDesc, 0, Buffer, ACPI_READ);
766  }
767  else
768  {
769  /* Use RawDatum (UINT64) to handle buffers < 64 bits */
770 
771  Status = AcpiExFieldDatumIo (ObjDesc, 0, &RawDatum, ACPI_READ);
772  memcpy (Buffer, &RawDatum, BufferLength);
773  }
774 
776  }
777 
778 /* TBD: Move to common setup code */
779 
780  /* Field algorithm is limited to sizeof(UINT64), truncate if needed */
781 
782  if (ObjDesc->CommonField.AccessByteWidth > sizeof (UINT64))
783  {
784  ObjDesc->CommonField.AccessByteWidth = sizeof (UINT64);
785  AccessBitWidth = sizeof (UINT64) * 8;
786  }
787 
788  /* Compute the number of datums (access width data items) */
789 
790  DatumCount = ACPI_ROUND_UP_TO (
791  ObjDesc->CommonField.BitLength, AccessBitWidth);
792 
793  FieldDatumCount = ACPI_ROUND_UP_TO (
794  ObjDesc->CommonField.BitLength +
795  ObjDesc->CommonField.StartFieldBitOffset, AccessBitWidth);
796 
797  /* Priming read from the field */
798 
799  Status = AcpiExFieldDatumIo (ObjDesc, FieldOffset, &RawDatum, ACPI_READ);
800  if (ACPI_FAILURE (Status))
801  {
803  }
804  MergedDatum = RawDatum >> ObjDesc->CommonField.StartFieldBitOffset;
805 
806  /* Read the rest of the field */
807 
808  for (i = 1; i < FieldDatumCount; i++)
809  {
810  /* Get next input datum from the field */
811 
812  FieldOffset += ObjDesc->CommonField.AccessByteWidth;
814  ObjDesc, FieldOffset, &RawDatum, ACPI_READ);
815  if (ACPI_FAILURE (Status))
816  {
818  }
819 
820  /*
821  * Merge with previous datum if necessary.
822  *
823  * Note: Before the shift, check if the shift value will be larger than
824  * the integer size. If so, there is no need to perform the operation.
825  * This avoids the differences in behavior between different compilers
826  * concerning shift values larger than the target data width.
827  */
828  if (AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset <
830  {
831  MergedDatum |= RawDatum <<
832  (AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset);
833  }
834 
835  if (i == DatumCount)
836  {
837  break;
838  }
839 
840  /* Write merged datum to target buffer */
841 
842  memcpy (((char *) Buffer) + BufferOffset, &MergedDatum,
843  ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
844  BufferLength - BufferOffset));
845 
846  BufferOffset += ObjDesc->CommonField.AccessByteWidth;
847  MergedDatum = RawDatum >> ObjDesc->CommonField.StartFieldBitOffset;
848  }
849 
850  /* Mask off any extra bits in the last datum */
851 
852  BufferTailBits = ObjDesc->CommonField.BitLength % AccessBitWidth;
853  if (BufferTailBits)
854  {
855  MergedDatum &= ACPI_MASK_BITS_ABOVE (BufferTailBits);
856  }
857 
858  /* Write the last datum to the buffer */
859 
860  memcpy (((char *) Buffer) + BufferOffset, &MergedDatum,
861  ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
862  BufferLength - BufferOffset));
863 
865 }
#define ACPI_READ
Definition: actypes.h:742
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
ACPI_OBJECT_FIELD_COMMON CommonField
Definition: acobject.h:530
#define ACPI_MUL_8(a)
Definition: acmacros.h:215
UINT32 ACPI_STATUS
Definition: actypes.h:460
static ACPI_STATUS AcpiExFieldDatumIo(ACPI_OPERAND_OBJECT *ObjDesc, UINT32 FieldDatumByteOffset, UINT64 *Value, UINT32 ReadWrite)
Definition: exfldio.c:402
#define ACPI_MIN(a, b)
Definition: actypes.h:535
#define ACPI_INTEGER_BIT_SIZE
Definition: actypes.h:490
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define AE_BUFFER_OVERFLOW
Definition: acexcep.h:119
unsigned int UINT32
_In_ ULONG BufferLength
Definition: usbdlib.h:225
#define AE_INFO
Definition: acoutput.h:230
#define ACPI_MASK_BITS_ABOVE(position)
Definition: acmacros.h:344
Definition: bufpool.h:45
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Status
Definition: gdiplustypes.h:24
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_ROUND_UP_TO(value, boundary)
Definition: acmacros.h:263
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define ACPI_ROUND_BITS_UP_TO_BYTES(a)
Definition: acmacros.h:256
unsigned long long UINT64
#define memset(x, y, z)
Definition: compat.h:39
#define AE_OK
Definition: acexcep.h:97

Referenced by AcpiExFieldDatumIo(), and AcpiExReadDataFromField().

◆ AcpiExFieldDatumIo()

static ACPI_STATUS AcpiExFieldDatumIo ( ACPI_OPERAND_OBJECT ObjDesc,
UINT32  FieldDatumByteOffset,
UINT64 Value,
UINT32  ReadWrite 
)
static

Definition at line 402 of file exfldio.c.

407 {
409  UINT64 LocalValue;
410 
411 
412  ACPI_FUNCTION_TRACE_U32 (ExFieldDatumIo, FieldDatumByteOffset);
413 
414 
415  if (ReadWrite == ACPI_READ)
416  {
417  if (!Value)
418  {
419  LocalValue = 0;
420 
421  /* To support reads without saving return value */
422  Value = &LocalValue;
423  }
424 
425  /* Clear the entire return buffer first, [Very Important!] */
426 
427  *Value = 0;
428  }
429 
430  /*
431  * The four types of fields are:
432  *
433  * BufferField - Read/write from/to a Buffer
434  * RegionField - Read/write from/to a Operation Region.
435  * BankField - Write to a Bank Register, then read/write from/to an
436  * OperationRegion
437  * IndexField - Write to an Index Register, then read/write from/to a
438  * Data Register
439  */
440  switch (ObjDesc->Common.Type)
441  {
443  /*
444  * If the BufferField arguments have not been previously evaluated,
445  * evaluate them now and save the results.
446  */
447  if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
448  {
450  if (ACPI_FAILURE (Status))
451  {
453  }
454  }
455 
456  if (ReadWrite == ACPI_READ)
457  {
458  /*
459  * Copy the data from the source buffer.
460  * Length is the field width in bytes.
461  */
462  memcpy (Value,
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  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 
484  /*
485  * Ensure that the BankValue is not beyond the capacity of
486  * the register
487  */
489  (UINT64) ObjDesc->BankField.Value))
490  {
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  */
499  &ObjDesc->BankField.Value,
500  sizeof (ObjDesc->BankField.Value));
501  if (ACPI_FAILURE (Status))
502  {
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 
514  /*
515  * For simple RegionFields, we just directly access the owning
516  * Operation Region.
517  */
519  ObjDesc, FieldDatumByteOffset, Value, ReadWrite);
520  break;
521 
523  /*
524  * Ensure that the IndexValue is not beyond the capacity of
525  * the register
526  */
528  (UINT64) ObjDesc->IndexField.Value))
529  {
531  }
532 
533  /* Write the index value to the IndexRegister (itself a RegionField) */
534 
535  FieldDatumByteOffset += ObjDesc->IndexField.Value;
536 
538  "Write to Index Register: Value %8.8X\n",
539  FieldDatumByteOffset));
540 
542  &FieldDatumByteOffset, sizeof (FieldDatumByteOffset));
543  if (ACPI_FAILURE (Status))
544  {
546  }
547 
548  if (ReadWrite == ACPI_READ)
549  {
550  /* Read the datum from the DataRegister */
551 
553  "Read from Data Register\n"));
554 
556  ObjDesc->IndexField.DataObj, Value, sizeof (UINT64));
557  }
558  else
559  {
560  /* Write the datum to the DataRegister */
561 
563  "Write to Data Register: Value %8.8X%8.8X\n",
565 
567  ObjDesc->IndexField.DataObj, Value, sizeof (UINT64));
568  }
569  break;
570 
571  default:
572 
573  ACPI_ERROR ((AE_INFO, "Wrong object type in field I/O %u",
574  ObjDesc->Common.Type));
576  break;
577  }
578 
579  if (ACPI_SUCCESS (Status))
580  {
581  if (ReadWrite == ACPI_READ)
582  {
584  "Value Read %8.8X%8.8X, Width %u\n",
586  ObjDesc->CommonField.AccessByteWidth));
587  }
588  else
589  {
591  "Value Written %8.8X%8.8X, Width %u\n",
593  ObjDesc->CommonField.AccessByteWidth));
594  }
595  }
596 
598 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define ACPI_DB_BFIELD
Definition: acoutput.h:168
ACPI_STATUS AcpiDsGetBufferFieldArguments(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: dsargs.c:196
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
#define ACPI_READ
Definition: actypes.h:742
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
ACPI_OBJECT_FIELD_COMMON CommonField
Definition: acobject.h:530
#define AE_AML_INTERNAL
Definition: acexcep.h:194
UINT32 ACPI_STATUS
Definition: actypes.h:460
union acpi_operand_object * BankObj
Definition: acobject.h:358
#define ACPI_FUNCTION_TRACE_U32(a, b)
Definition: acoutput.h:482
#define ACPI_TYPE_LOCAL_INDEX_FIELD
Definition: actypes.h:709
#define AE_AML_REGISTER_LIMIT
Definition: acexcep.h:204
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
ACPI_OBJECT_BANK_FIELD BankField
Definition: acobject.h:533
#define AE_INFO
Definition: acoutput.h:230
ACPI_STATUS AcpiExExtractFromField(ACPI_OPERAND_OBJECT *ObjDesc, void *Buffer, UINT32 BufferLength)
Definition: exfldio.c:723
union acpi_operand_object * DataObj
Definition: acobject.h:373
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
ACPI_OBJECT_INDEX_FIELD IndexField
Definition: acobject.h:534
#define ACPI_TYPE_LOCAL_REGION_FIELD
Definition: actypes.h:707
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Status
Definition: gdiplustypes.h:24
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FORMAT_UINT64(i)
Definition: acmacros.h:71
#define ACPI_TYPE_BUFFER_FIELD
Definition: actypes.h:692
ACPI_OBJECT_COMMON Common
Definition: acobject.h:516
ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object * IndexObj
Definition: acobject.h:372
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define AOPOBJ_DATA_VALID
Definition: acobject.h:96
#define ACPI_TYPE_LOCAL_BANK_FIELD
Definition: actypes.h:708
ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object * BufferObj
Definition: acobject.h:384
DRIVER_DISPATCH ReadWrite
Definition: readwrite.h:29
ACPI_STATUS AcpiExInsertIntoField(ACPI_OPERAND_OBJECT *ObjDesc, void *Buffer, UINT32 BufferLength)
Definition: exfldio.c:883
ACPI_OBJECT_BUFFER_FIELD BufferField
Definition: acobject.h:532
unsigned long long UINT64
ACPI_STATUS AcpiExAccessRegion(ACPI_OPERAND_OBJECT *ObjDesc, UINT32 FieldDatumByteOffset, UINT64 *Value, UINT32 Function)
Definition: exfldio.c:249
#define AE_OK
Definition: acexcep.h:97
static BOOLEAN AcpiExRegisterOverflow(ACPI_OPERAND_OBJECT *ObjDesc, UINT64 Value)
Definition: exfldio.c:349

Referenced by AcpiExExtractFromField(), and AcpiExWriteWithUpdateRule().

◆ AcpiExInsertIntoField()

ACPI_STATUS AcpiExInsertIntoField ( ACPI_OPERAND_OBJECT ObjDesc,
void Buffer,
UINT32  BufferLength 
)

Definition at line 883 of file exfldio.c.

887 {
888  void *NewBuffer;
890  UINT64 Mask;
891  UINT64 WidthMask;
892  UINT64 MergedDatum;
893  UINT64 RawDatum = 0;
894  UINT32 FieldOffset = 0;
895  UINT32 BufferOffset = 0;
896  UINT32 BufferTailBits;
897  UINT32 DatumCount;
898  UINT32 FieldDatumCount;
899  UINT32 AccessBitWidth;
901  UINT32 i;
902 
903 
904  ACPI_FUNCTION_TRACE (ExInsertIntoField);
905 
906 
907  /* Validate input buffer */
908 
909  NewBuffer = NULL;
911  ObjDesc->CommonField.BitLength);
912 
913  /*
914  * We must have a buffer that is at least as long as the field
915  * we are writing to. This is because individual fields are
916  * indivisible and partial writes are not supported -- as per
917  * the ACPI specification.
918  */
920  {
921  /* We need to create a new buffer */
922 
923  NewBuffer = ACPI_ALLOCATE_ZEROED (RequiredLength);
924  if (!NewBuffer)
925  {
927  }
928 
929  /*
930  * Copy the original data to the new buffer, starting
931  * at Byte zero. All unused (upper) bytes of the
932  * buffer will be 0.
933  */
934  memcpy ((char *) NewBuffer, (char *) Buffer, BufferLength);
935  Buffer = NewBuffer;
937  }
938 
939 /* TBD: Move to common setup code */
940 
941  /* Algo is limited to sizeof(UINT64), so cut the AccessByteWidth */
942  if (ObjDesc->CommonField.AccessByteWidth > sizeof (UINT64))
943  {
944  ObjDesc->CommonField.AccessByteWidth = sizeof (UINT64);
945  }
946 
947  AccessBitWidth = ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth);
948 
949  /* Create the bitmasks used for bit insertion */
950 
951  WidthMask = ACPI_MASK_BITS_ABOVE_64 (AccessBitWidth);
952  Mask = WidthMask &
953  ACPI_MASK_BITS_BELOW (ObjDesc->CommonField.StartFieldBitOffset);
954 
955  /* Compute the number of datums (access width data items) */
956 
957  DatumCount = ACPI_ROUND_UP_TO (ObjDesc->CommonField.BitLength,
958  AccessBitWidth);
959 
960  FieldDatumCount = ACPI_ROUND_UP_TO (ObjDesc->CommonField.BitLength +
961  ObjDesc->CommonField.StartFieldBitOffset,
962  AccessBitWidth);
963 
964  /* Get initial Datum from the input buffer */
965 
966  memcpy (&RawDatum, Buffer,
967  ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
968  BufferLength - BufferOffset));
969 
970  MergedDatum = RawDatum << ObjDesc->CommonField.StartFieldBitOffset;
971 
972  /* Write the entire field */
973 
974  for (i = 1; i < FieldDatumCount; i++)
975  {
976  /* Write merged datum to the target field */
977 
978  MergedDatum &= Mask;
980  ObjDesc, Mask, MergedDatum, FieldOffset);
981  if (ACPI_FAILURE (Status))
982  {
983  goto Exit;
984  }
985 
986  FieldOffset += ObjDesc->CommonField.AccessByteWidth;
987 
988  /*
989  * Start new output datum by merging with previous input datum
990  * if necessary.
991  *
992  * Note: Before the shift, check if the shift value will be larger than
993  * the integer size. If so, there is no need to perform the operation.
994  * This avoids the differences in behavior between different compilers
995  * concerning shift values larger than the target data width.
996  */
997  if ((AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset) <
999  {
1000  MergedDatum = RawDatum >>
1001  (AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset);
1002  }
1003  else
1004  {
1005  MergedDatum = 0;
1006  }
1007 
1008  Mask = WidthMask;
1009 
1010  if (i == DatumCount)
1011  {
1012  break;
1013  }
1014 
1015  /* Get the next input datum from the buffer */
1016 
1017  BufferOffset += ObjDesc->CommonField.AccessByteWidth;
1018  memcpy (&RawDatum, ((char *) Buffer) + BufferOffset,
1019  ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
1020  BufferLength - BufferOffset));
1021 
1022  MergedDatum |= RawDatum << ObjDesc->CommonField.StartFieldBitOffset;
1023  }
1024 
1025  /* Mask off any extra bits in the last datum */
1026 
1027  BufferTailBits = (ObjDesc->CommonField.BitLength +
1028  ObjDesc->CommonField.StartFieldBitOffset) % AccessBitWidth;
1029  if (BufferTailBits)
1030  {
1031  Mask &= ACPI_MASK_BITS_ABOVE (BufferTailBits);
1032  }
1033 
1034  /* Write the last datum to the field */
1035 
1036  MergedDatum &= Mask;
1038  ObjDesc, Mask, MergedDatum, FieldOffset);
1039 
1040 Exit:
1041  /* Free temporary buffer if we used one */
1042 
1043  if (NewBuffer)
1044  {
1045  ACPI_FREE (NewBuffer);
1046  }
1048 }
#define ACPI_FREE(a)
Definition: actypes.h:386
#define ACPI_ALLOCATE_ZEROED(a)
Definition: actypes.h:385
#define AE_NO_MEMORY
Definition: acexcep.h:112
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
ACPI_OBJECT_FIELD_COMMON CommonField
Definition: acobject.h:530
#define ACPI_MUL_8(a)
Definition: acmacros.h:215
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_MASK_BITS_ABOVE_64(width)
Definition: acmacros.h:348
#define ACPI_MIN(a, b)
Definition: actypes.h:535
#define ACPI_INTEGER_BIT_SIZE
Definition: actypes.h:490
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int UINT32
_In_ ULONG BufferLength
Definition: usbdlib.h:225
smooth NULL
Definition: ftsmooth.c:416
#define ACPI_MASK_BITS_ABOVE(position)
Definition: acmacros.h:344
Definition: bufpool.h:45
#define ACPI_MASK_BITS_BELOW(position)
Definition: acmacros.h:345
static void Exit(void)
Definition: sock.c:1331
ACPI_STATUS AcpiExWriteWithUpdateRule(ACPI_OPERAND_OBJECT *ObjDesc, UINT64 Mask, UINT64 FieldValue, UINT32 FieldDatumByteOffset)
Definition: exfldio.c:617
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Status
Definition: gdiplustypes.h:24
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:29
#define ACPI_ROUND_UP_TO(value, boundary)
Definition: acmacros.h:263
#define ACPI_ROUND_BITS_UP_TO_BYTES(a)
Definition: acmacros.h:256
unsigned long long UINT64

Referenced by AcpiExFieldDatumIo(), and AcpiExWriteDataToField().

◆ AcpiExRegisterOverflow()

static BOOLEAN AcpiExRegisterOverflow ( ACPI_OPERAND_OBJECT ObjDesc,
UINT64  Value 
)
static

Definition at line 349 of file exfldio.c.

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  */
370  "Index value 0x%8.8X%8.8X overflows field width 0x%X",
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 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define TRUE
Definition: types.h:120
ACPI_OBJECT_FIELD_COMMON CommonField
Definition: acobject.h:530
#define ACPI_INTEGER_BIT_SIZE
Definition: actypes.h:490
#define AE_INFO
Definition: acoutput.h:230
#define ACPI_FORMAT_UINT64(i)
Definition: acmacros.h:71
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
unsigned long long UINT64

Referenced by AcpiExFieldDatumIo().

◆ AcpiExSetupRegion()

static ACPI_STATUS AcpiExSetupRegion ( ACPI_OPERAND_OBJECT ObjDesc,
UINT32  FieldDatumByteOffset 
)
static

Definition at line 92 of file exfldio.c.

95 {
97  ACPI_OPERAND_OBJECT *RgnDesc;
98  UINT8 SpaceId;
99 
100 
101  ACPI_FUNCTION_TRACE_U32 (ExSetupRegion, FieldDatumByteOffset);
102 
103 
104  RgnDesc = ObjDesc->CommonField.RegionObj;
105 
106  /* We must have a valid region */
107 
108  if (RgnDesc->Common.Type != ACPI_TYPE_REGION)
109  {
110  ACPI_ERROR ((AE_INFO, "Needed Region, found type 0x%X (%s)",
111  RgnDesc->Common.Type,
112  AcpiUtGetObjectTypeName (RgnDesc)));
113 
115  }
116 
117  SpaceId = RgnDesc->Region.SpaceId;
118 
119  /* Validate the Space ID */
120 
122  {
124  "Invalid/unknown Address Space ID: 0x%2.2X", SpaceId));
126  }
127 
128  /*
129  * If the Region Address and Length have not been previously evaluated,
130  * evaluate them now and save the results.
131  */
132  if (!(RgnDesc->Common.Flags & AOPOBJ_DATA_VALID))
133  {
134  Status = AcpiDsGetRegionArguments (RgnDesc);
135  if (ACPI_FAILURE (Status))
136  {
138  }
139  }
140 
141  /*
142  * Exit now for SMBus, GSBus or IPMI address space, it has a non-linear
143  * address space and the request cannot be directly validated
144  */
145  if (SpaceId == ACPI_ADR_SPACE_SMBUS ||
148  {
149  /* SMBus or IPMI has a non-linear address space */
150 
152  }
153 
154 #ifdef ACPI_UNDER_DEVELOPMENT
155  /*
156  * If the Field access is AnyAcc, we can now compute the optimal
157  * access (because we know know the length of the parent region)
158  */
159  if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
160  {
161  if (ACPI_FAILURE (Status))
162  {
164  }
165  }
166 #endif
167 
168  /*
169  * Validate the request. The entire request from the byte offset for a
170  * length of one field datum (access width) must fit within the region.
171  * (Region length is specified in bytes)
172  */
173  if (RgnDesc->Region.Length <
174  (ObjDesc->CommonField.BaseByteOffset + FieldDatumByteOffset +
175  ObjDesc->CommonField.AccessByteWidth))
176  {
177  if (AcpiGbl_EnableInterpreterSlack)
178  {
179  /*
180  * Slack mode only: We will go ahead and allow access to this
181  * field if it is within the region length rounded up to the next
182  * access width boundary. ACPI_SIZE cast for 64-bit compile.
183  */
184  if (ACPI_ROUND_UP (RgnDesc->Region.Length,
185  ObjDesc->CommonField.AccessByteWidth) >=
186  ((ACPI_SIZE) ObjDesc->CommonField.BaseByteOffset +
187  ObjDesc->CommonField.AccessByteWidth +
188  FieldDatumByteOffset))
189  {
191  }
192  }
193 
194  if (RgnDesc->Region.Length < ObjDesc->CommonField.AccessByteWidth)
195  {
196  /*
197  * This is the case where the AccessType (AccWord, etc.) is wider
198  * than the region itself. For example, a region of length one
199  * byte, and a field with Dword access specified.
200  */
202  "Field [%4.4s] access width (%u bytes) "
203  "too large for region [%4.4s] (length %u)",
204  AcpiUtGetNodeName (ObjDesc->CommonField.Node),
205  ObjDesc->CommonField.AccessByteWidth,
206  AcpiUtGetNodeName (RgnDesc->Region.Node),
207  RgnDesc->Region.Length));
208  }
209 
210  /*
211  * Offset rounded up to next multiple of field width
212  * exceeds region length, indicate an error
213  */
215  "Field [%4.4s] Base+Offset+Width %u+%u+%u "
216  "is beyond end of region [%4.4s] (length %u)",
217  AcpiUtGetNodeName (ObjDesc->CommonField.Node),
218  ObjDesc->CommonField.BaseByteOffset,
219  FieldDatumByteOffset, ObjDesc->CommonField.AccessByteWidth,
220  AcpiUtGetNodeName (RgnDesc->Region.Node),
221  RgnDesc->Region.Length));
222 
224  }
225 
227 }
#define AE_AML_REGION_LIMIT
Definition: acexcep.h:188
ACPI_NAMESPACE_NODE * Node
Definition: acobject.h:203
BOOLEAN AcpiIsValidSpaceId(UINT8 SpaceId)
Definition: exutils.c:494
ACPI_OBJECT_FIELD_COMMON CommonField
Definition: acobject.h:530
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_FUNCTION_TRACE_U32(a, b)
Definition: acoutput.h:482
ACPI_OBJECT_COMMON_HEADER UINT8 SpaceId
Definition: acobject.h:202
#define AE_AML_OPERAND_TYPE
Definition: acexcep.h:182
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE ACPI_HANDLE ACPI_HANDLE *OutHandle ACPI_HANDLE *OutHandle void *Context void *Context ACPI_EVENT_HANDLER Handler UINT32 UINT32 ACPI_GPE_HANDLER void *Context UINT32 ACPI_NOTIFY_HANDLER void *Context ACPI_ADR_SPACE_TYPE SpaceId
Definition: acpixf.h:822
ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object * RegionObj
Definition: acobject.h:335
#define AE_AML_INVALID_SPACE_ID
Definition: acexcep.h:195
#define AE_INFO
Definition: acoutput.h:230
ACPI_OBJECT_REGION Region
Definition: acobject.h:524
#define ACPI_ROUND_UP(value, boundary)
Definition: acmacros.h:242
#define ACPI_ADR_SPACE_IPMI
Definition: actypes.h:858
#define ACPI_ADR_SPACE_GSBUS
Definition: actypes.h:860
Status
Definition: gdiplustypes.h:24
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
ACPI_STATUS AcpiDsGetRegionArguments(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: dsargs.c:395
ACPI_OBJECT_COMMON Common
Definition: acobject.h:516
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
const char * AcpiUtGetNodeName(void *Object)
Definition: utdecode.c:305
#define AOPOBJ_DATA_VALID
Definition: acobject.h:96
#define ACPI_TYPE_REGION
Definition: actypes.h:688
#define ACPI_ADR_SPACE_SMBUS
Definition: actypes.h:855
unsigned char UINT8
const char * AcpiUtGetObjectTypeName(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: utdecode.c:263
#define AE_OK
Definition: acexcep.h:97

Referenced by AcpiExAccessRegion().

◆ AcpiExWriteWithUpdateRule()

ACPI_STATUS AcpiExWriteWithUpdateRule ( ACPI_OPERAND_OBJECT ObjDesc,
UINT64  Mask,
UINT64  FieldValue,
UINT32  FieldDatumByteOffset 
)

Definition at line 617 of file exfldio.c.

622 {
624  UINT64 MergedValue;
625  UINT64 CurrentValue;
626 
627 
628  ACPI_FUNCTION_TRACE_U32 (ExWriteWithUpdateRule, Mask);
629 
630 
631  /* Start with the new bits */
632 
633  MergedValue = FieldValue;
634 
635  /* If the mask is all ones, we don't need to worry about the update rule */
636 
637  if (Mask != ACPI_UINT64_MAX)
638  {
639  /* Decode the update rule */
640 
641  switch (ObjDesc->CommonField.FieldFlags & AML_FIELD_UPDATE_RULE_MASK)
642  {
644  /*
645  * Check if update rule needs to be applied (not if mask is all
646  * ones) The left shift drops the bits we want to ignore.
647  */
648  if ((~Mask << (ACPI_MUL_8 (sizeof (Mask)) -
649  ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth))) != 0)
650  {
651  /*
652  * Read the current contents of the byte/word/dword containing
653  * the field, and merge with the new field value.
654  */
656  ObjDesc, FieldDatumByteOffset, &CurrentValue, ACPI_READ);
657  if (ACPI_FAILURE (Status))
658  {
660  }
661 
662  MergedValue |= (CurrentValue & ~Mask);
663  }
664  break;
665 
667 
668  /* Set positions outside the field to all ones */
669 
670  MergedValue |= ~Mask;
671  break;
672 
674 
675  /* Set positions outside the field to all zeros */
676 
677  MergedValue &= Mask;
678  break;
679 
680  default:
681 
683  "Unknown UpdateRule value: 0x%X",
684  (ObjDesc->CommonField.FieldFlags &
687  }
688  }
689 
691  "Mask %8.8X%8.8X, DatumOffset %X, Width %X, "
692  "Value %8.8X%8.8X, MergedValue %8.8X%8.8X\n",
693  ACPI_FORMAT_UINT64 (Mask),
694  FieldDatumByteOffset,
695  ObjDesc->CommonField.AccessByteWidth,
696  ACPI_FORMAT_UINT64 (FieldValue),
697  ACPI_FORMAT_UINT64 (MergedValue)));
698 
699  /* Write the merged value */
700 
702  ObjDesc, FieldDatumByteOffset, &MergedValue, ACPI_WRITE);
703 
705 }
#define ACPI_DB_BFIELD
Definition: acoutput.h:168
#define ACPI_READ
Definition: actypes.h:742
#define AE_AML_OPERAND_VALUE
Definition: acexcep.h:183
ACPI_OBJECT_FIELD_COMMON CommonField
Definition: acobject.h:530
#define ACPI_MUL_8(a)
Definition: acmacros.h:215
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_FUNCTION_TRACE_U32(a, b)
Definition: acoutput.h:482
static ACPI_STATUS AcpiExFieldDatumIo(ACPI_OPERAND_OBJECT *ObjDesc, UINT32 FieldDatumByteOffset, UINT64 *Value, UINT32 ReadWrite)
Definition: exfldio.c:402
#define AML_FIELD_UPDATE_RULE_MASK
Definition: amlcode.h:444
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define AE_INFO
Definition: acoutput.h:230
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
Status
Definition: gdiplustypes.h:24
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FORMAT_UINT64(i)
Definition: acmacros.h:71
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define ACPI_UINT64_MAX
Definition: actypes.h:67
unsigned long long UINT64
#define AE_OK
Definition: acexcep.h:97
#define ACPI_WRITE
Definition: actypes.h:743

Referenced by AcpiExInsertIntoField().