mirror of
https://github.com/acpica/acpica/
synced 2024-12-29 05:39:57 +03:00
Enable multi-byte EC transfers.
Previously, the maximum data size passed to the EC operation region handler was a single byte. Since there are often larger datums that need to be transfered, and the EC would like to lock these as a single transaction, this change enables transfers larger than a single byte. This may require changes to the host-OS Embedded Controller driver to enable 16/32/64 bit tranfers in addition to 8-bit transfers. Alexey Starikovskiy, Lin Ming
This commit is contained in:
parent
14aafc8b1b
commit
df3d422671
@ -202,8 +202,8 @@ AcpiExSetupRegion (
|
||||
}
|
||||
|
||||
/*
|
||||
* Exit now for SMBus or IPMI address space, it has a non-linear address space
|
||||
* and the request cannot be directly validated
|
||||
* Exit now for SMBus or IPMI address space, it has a non-linear
|
||||
* address space and the request cannot be directly validated
|
||||
*/
|
||||
if (RgnDesc->Region.SpaceId == ACPI_ADR_SPACE_SMBUS ||
|
||||
RgnDesc->Region.SpaceId == ACPI_ADR_SPACE_IPMI)
|
||||
@ -233,8 +233,7 @@ AcpiExSetupRegion (
|
||||
* (Region length is specified in bytes)
|
||||
*/
|
||||
if (RgnDesc->Region.Length <
|
||||
(ObjDesc->CommonField.BaseByteOffset +
|
||||
FieldDatumByteOffset +
|
||||
(ObjDesc->CommonField.BaseByteOffset + FieldDatumByteOffset +
|
||||
ObjDesc->CommonField.AccessByteWidth))
|
||||
{
|
||||
if (AcpiGbl_EnableInterpreterSlack)
|
||||
@ -794,6 +793,7 @@ AcpiExExtractFromField (
|
||||
UINT32 BufferTailBits;
|
||||
UINT32 DatumCount;
|
||||
UINT32 FieldDatumCount;
|
||||
UINT32 AccessBitWidth;
|
||||
UINT32 i;
|
||||
|
||||
|
||||
@ -811,17 +811,37 @@ AcpiExExtractFromField (
|
||||
|
||||
return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
|
||||
}
|
||||
|
||||
ACPI_MEMSET (Buffer, 0, BufferLength);
|
||||
AccessBitWidth = ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth);
|
||||
|
||||
/* Handle the simple case here */
|
||||
|
||||
if ((ObjDesc->CommonField.StartFieldBitOffset == 0) &&
|
||||
(ObjDesc->CommonField.BitLength == AccessBitWidth))
|
||||
{
|
||||
Status = AcpiExFieldDatumIo (ObjDesc, 0, Buffer, ACPI_READ);
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
|
||||
/* TBD: Move to common setup code */
|
||||
|
||||
/* Field algorithm is limited to sizeof(UINT64), truncate if needed */
|
||||
|
||||
if (ObjDesc->CommonField.AccessByteWidth > sizeof (UINT64))
|
||||
{
|
||||
ObjDesc->CommonField.AccessByteWidth = sizeof (UINT64);
|
||||
AccessBitWidth = sizeof (UINT64) * 8;
|
||||
}
|
||||
|
||||
/* Compute the number of datums (access width data items) */
|
||||
|
||||
DatumCount = ACPI_ROUND_UP_TO (
|
||||
ObjDesc->CommonField.BitLength,
|
||||
ObjDesc->CommonField.AccessBitWidth);
|
||||
ObjDesc->CommonField.BitLength, AccessBitWidth);
|
||||
|
||||
FieldDatumCount = ACPI_ROUND_UP_TO (
|
||||
ObjDesc->CommonField.BitLength +
|
||||
ObjDesc->CommonField.StartFieldBitOffset,
|
||||
ObjDesc->CommonField.AccessBitWidth);
|
||||
ObjDesc->CommonField.StartFieldBitOffset, AccessBitWidth);
|
||||
|
||||
/* Priming read from the field */
|
||||
|
||||
@ -854,12 +874,11 @@ AcpiExExtractFromField (
|
||||
* This avoids the differences in behavior between different compilers
|
||||
* concerning shift values larger than the target data width.
|
||||
*/
|
||||
if ((ObjDesc->CommonField.AccessBitWidth -
|
||||
ObjDesc->CommonField.StartFieldBitOffset) < ACPI_INTEGER_BIT_SIZE)
|
||||
if (AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset <
|
||||
ACPI_INTEGER_BIT_SIZE)
|
||||
{
|
||||
MergedDatum |= RawDatum <<
|
||||
(ObjDesc->CommonField.AccessBitWidth -
|
||||
ObjDesc->CommonField.StartFieldBitOffset);
|
||||
(AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset);
|
||||
}
|
||||
|
||||
if (i == DatumCount)
|
||||
@ -879,8 +898,7 @@ AcpiExExtractFromField (
|
||||
|
||||
/* Mask off any extra bits in the last datum */
|
||||
|
||||
BufferTailBits = ObjDesc->CommonField.BitLength %
|
||||
ObjDesc->CommonField.AccessBitWidth;
|
||||
BufferTailBits = ObjDesc->CommonField.BitLength % AccessBitWidth;
|
||||
if (BufferTailBits)
|
||||
{
|
||||
MergedDatum &= ACPI_MASK_BITS_ABOVE (BufferTailBits);
|
||||
@ -916,6 +934,7 @@ AcpiExInsertIntoField (
|
||||
void *Buffer,
|
||||
UINT32 BufferLength)
|
||||
{
|
||||
void *NewBuffer;
|
||||
ACPI_STATUS Status;
|
||||
UINT64 Mask;
|
||||
UINT64 WidthMask;
|
||||
@ -926,9 +945,9 @@ AcpiExInsertIntoField (
|
||||
UINT32 BufferTailBits;
|
||||
UINT32 DatumCount;
|
||||
UINT32 FieldDatumCount;
|
||||
UINT32 i;
|
||||
UINT32 AccessBitWidth;
|
||||
UINT32 RequiredLength;
|
||||
void *NewBuffer;
|
||||
UINT32 i;
|
||||
|
||||
|
||||
ACPI_FUNCTION_TRACE (ExInsertIntoField);
|
||||
@ -965,18 +984,28 @@ AcpiExInsertIntoField (
|
||||
BufferLength = RequiredLength;
|
||||
}
|
||||
|
||||
/* TBD: Move to common setup code */
|
||||
|
||||
/* Algo is limited to sizeof(UINT64), so cut the AccessByteWidth */
|
||||
if (ObjDesc->CommonField.AccessByteWidth > sizeof (UINT64))
|
||||
{
|
||||
ObjDesc->CommonField.AccessByteWidth = sizeof (UINT64);
|
||||
}
|
||||
|
||||
AccessBitWidth = ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth);
|
||||
|
||||
/*
|
||||
* Create the bitmasks used for bit insertion.
|
||||
* Note: This if/else is used to bypass compiler differences with the
|
||||
* shift operator
|
||||
*/
|
||||
if (ObjDesc->CommonField.AccessBitWidth == ACPI_INTEGER_BIT_SIZE)
|
||||
if (AccessBitWidth == ACPI_INTEGER_BIT_SIZE)
|
||||
{
|
||||
WidthMask = ACPI_UINT64_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
WidthMask = ACPI_MASK_BITS_ABOVE (ObjDesc->CommonField.AccessBitWidth);
|
||||
WidthMask = ACPI_MASK_BITS_ABOVE (AccessBitWidth);
|
||||
}
|
||||
|
||||
Mask = WidthMask &
|
||||
@ -985,11 +1014,11 @@ AcpiExInsertIntoField (
|
||||
/* Compute the number of datums (access width data items) */
|
||||
|
||||
DatumCount = ACPI_ROUND_UP_TO (ObjDesc->CommonField.BitLength,
|
||||
ObjDesc->CommonField.AccessBitWidth);
|
||||
AccessBitWidth);
|
||||
|
||||
FieldDatumCount = ACPI_ROUND_UP_TO (ObjDesc->CommonField.BitLength +
|
||||
ObjDesc->CommonField.StartFieldBitOffset,
|
||||
ObjDesc->CommonField.AccessBitWidth);
|
||||
AccessBitWidth);
|
||||
|
||||
/* Get initial Datum from the input buffer */
|
||||
|
||||
@ -1024,12 +1053,11 @@ AcpiExInsertIntoField (
|
||||
* This avoids the differences in behavior between different compilers
|
||||
* concerning shift values larger than the target data width.
|
||||
*/
|
||||
if ((ObjDesc->CommonField.AccessBitWidth -
|
||||
ObjDesc->CommonField.StartFieldBitOffset) < ACPI_INTEGER_BIT_SIZE)
|
||||
if ((AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset) <
|
||||
ACPI_INTEGER_BIT_SIZE)
|
||||
{
|
||||
MergedDatum = RawDatum >>
|
||||
(ObjDesc->CommonField.AccessBitWidth -
|
||||
ObjDesc->CommonField.StartFieldBitOffset);
|
||||
(AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1049,14 +1077,14 @@ AcpiExInsertIntoField (
|
||||
ACPI_MEMCPY (&RawDatum, ((char *) Buffer) + BufferOffset,
|
||||
ACPI_MIN(ObjDesc->CommonField.AccessByteWidth,
|
||||
BufferLength - BufferOffset));
|
||||
|
||||
MergedDatum |= RawDatum << ObjDesc->CommonField.StartFieldBitOffset;
|
||||
}
|
||||
|
||||
/* Mask off any extra bits in the last datum */
|
||||
|
||||
BufferTailBits = (ObjDesc->CommonField.BitLength +
|
||||
ObjDesc->CommonField.StartFieldBitOffset) %
|
||||
ObjDesc->CommonField.AccessBitWidth;
|
||||
ObjDesc->CommonField.StartFieldBitOffset) % AccessBitWidth;
|
||||
if (BufferTailBits)
|
||||
{
|
||||
Mask &= ACPI_MASK_BITS_ABOVE (BufferTailBits);
|
||||
|
@ -450,12 +450,10 @@ AcpiExPrepCommonFieldObject (
|
||||
return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
|
||||
}
|
||||
|
||||
/* Setup width (access granularity) fields */
|
||||
/* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */
|
||||
|
||||
ObjDesc->CommonField.AccessByteWidth = (UINT8)
|
||||
ACPI_DIV_8 (AccessBitWidth); /* 1, 2, 4, 8 */
|
||||
|
||||
ObjDesc->CommonField.AccessBitWidth = (UINT8) AccessBitWidth;
|
||||
ACPI_DIV_8 (AccessBitWidth);
|
||||
|
||||
/*
|
||||
* BaseByteOffset is the address of the start of the field within the
|
||||
@ -502,8 +500,9 @@ AcpiExPrepFieldValue (
|
||||
{
|
||||
ACPI_OPERAND_OBJECT *ObjDesc;
|
||||
ACPI_OPERAND_OBJECT *SecondDesc = NULL;
|
||||
UINT32 Type;
|
||||
ACPI_STATUS Status;
|
||||
UINT32 AccessByteWidth;
|
||||
UINT32 Type;
|
||||
|
||||
|
||||
ACPI_FUNCTION_TRACE (ExPrepFieldValue);
|
||||
@ -522,8 +521,7 @@ AcpiExPrepFieldValue (
|
||||
Type = AcpiNsGetType (Info->RegionNode);
|
||||
if (Type != ACPI_TYPE_REGION)
|
||||
{
|
||||
ACPI_ERROR ((AE_INFO,
|
||||
"Needed Region, found type 0x%X (%s)",
|
||||
ACPI_ERROR ((AE_INFO, "Needed Region, found type 0x%X (%s)",
|
||||
Type, AcpiUtGetTypeName (Type)));
|
||||
|
||||
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
|
||||
@ -541,8 +539,9 @@ AcpiExPrepFieldValue (
|
||||
/* Initialize areas of the object that are common to all fields */
|
||||
|
||||
ObjDesc->CommonField.Node = Info->FieldNode;
|
||||
Status = AcpiExPrepCommonFieldObject (ObjDesc, Info->FieldFlags,
|
||||
Info->Attribute, Info->FieldBitPosition, Info->FieldBitLength);
|
||||
Status = AcpiExPrepCommonFieldObject (ObjDesc,
|
||||
Info->FieldFlags, Info->Attribute,
|
||||
Info->FieldBitPosition, Info->FieldBitLength);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
AcpiUtDeleteObjectDesc (ObjDesc);
|
||||
@ -557,6 +556,22 @@ AcpiExPrepFieldValue (
|
||||
|
||||
ObjDesc->Field.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode);
|
||||
|
||||
/* Allow full data read from EC address space */
|
||||
|
||||
if ((ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_EC) &&
|
||||
(ObjDesc->CommonField.BitLength > 8))
|
||||
{
|
||||
AccessByteWidth = ACPI_ROUND_BITS_UP_TO_BYTES (
|
||||
ObjDesc->CommonField.BitLength);
|
||||
|
||||
/* Maximum byte width supported is 255 */
|
||||
|
||||
if (AccessByteWidth < 256)
|
||||
{
|
||||
ObjDesc->CommonField.AccessByteWidth = (UINT8) AccessByteWidth;
|
||||
}
|
||||
}
|
||||
|
||||
/* An additional reference for the container */
|
||||
|
||||
AcpiUtAddReference (ObjDesc->Field.RegionObj);
|
||||
@ -571,10 +586,10 @@ AcpiExPrepFieldValue (
|
||||
case ACPI_TYPE_LOCAL_BANK_FIELD:
|
||||
|
||||
ObjDesc->BankField.Value = Info->BankValue;
|
||||
ObjDesc->BankField.RegionObj = AcpiNsGetAttachedObject (
|
||||
Info->RegionNode);
|
||||
ObjDesc->BankField.BankObj = AcpiNsGetAttachedObject (
|
||||
Info->RegisterNode);
|
||||
ObjDesc->BankField.RegionObj =
|
||||
AcpiNsGetAttachedObject (Info->RegionNode);
|
||||
ObjDesc->BankField.BankObj =
|
||||
AcpiNsGetAttachedObject (Info->RegisterNode);
|
||||
|
||||
/* An additional reference for the attached objects */
|
||||
|
||||
@ -595,8 +610,10 @@ AcpiExPrepFieldValue (
|
||||
* operands must be evaluated.
|
||||
*/
|
||||
SecondDesc = ObjDesc->Common.NextObject;
|
||||
SecondDesc->Extra.AmlStart = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Info->DataRegisterNode)->Named.Data;
|
||||
SecondDesc->Extra.AmlLength = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Info->DataRegisterNode)->Named.Length;
|
||||
SecondDesc->Extra.AmlStart = ACPI_CAST_PTR (ACPI_PARSE_OBJECT,
|
||||
Info->DataRegisterNode)->Named.Data;
|
||||
SecondDesc->Extra.AmlLength = ACPI_CAST_PTR (ACPI_PARSE_OBJECT,
|
||||
Info->DataRegisterNode)->Named.Length;
|
||||
|
||||
break;
|
||||
|
||||
@ -605,10 +622,10 @@ AcpiExPrepFieldValue (
|
||||
|
||||
/* Get the Index and Data registers */
|
||||
|
||||
ObjDesc->IndexField.IndexObj = AcpiNsGetAttachedObject (
|
||||
Info->RegisterNode);
|
||||
ObjDesc->IndexField.DataObj = AcpiNsGetAttachedObject (
|
||||
Info->DataRegisterNode);
|
||||
ObjDesc->IndexField.IndexObj =
|
||||
AcpiNsGetAttachedObject (Info->RegisterNode);
|
||||
ObjDesc->IndexField.DataObj =
|
||||
AcpiNsGetAttachedObject (Info->DataRegisterNode);
|
||||
|
||||
if (!ObjDesc->IndexField.DataObj || !ObjDesc->IndexField.IndexObj)
|
||||
{
|
||||
|
@ -386,7 +386,6 @@ typedef struct acpi_object_thermal_zone
|
||||
UINT32 BaseByteOffset; /* Byte offset within containing object */\
|
||||
UINT32 Value; /* Value to store into the Bank or Index register */\
|
||||
UINT8 StartFieldBitOffset;/* Bit offset within first field datum (0-63) */\
|
||||
UINT8 AccessBitWidth; /* Read/Write size in bits (8-64) */
|
||||
|
||||
|
||||
typedef struct acpi_object_field_common /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */
|
||||
|
Loading…
Reference in New Issue
Block a user