mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-26 04:30:56 +07:00
ACPICA: Revert "Revert "Enable multi-byte EC transfers
This reverts commit f23b9c7(http://git.moblin.org/cgit.cgi/acpica/commit/?id=f23b9c7) The problem with this change was determined to be a problem with the FreeBSD host OSL (OS services layer), not with this patch itself. Therefore, re-introducing this change into the main ACPICA code. See ACPICA bugzilla 863. http://www.acpica.org/bugzilla/show_bug.cgi?id=863 Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
parent
c5f0231ee6
commit
09387b4315
@ -248,7 +248,7 @@ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO};
|
|||||||
u32 base_byte_offset; /* Byte offset within containing object */\
|
u32 base_byte_offset; /* Byte offset within containing object */\
|
||||||
u32 value; /* Value to store into the Bank or Index register */\
|
u32 value; /* Value to store into the Bank or Index register */\
|
||||||
u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\
|
u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\
|
||||||
u8 access_bit_width; /* Read/Write size in bits (8-64) */
|
|
||||||
|
|
||||||
struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */
|
struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */
|
||||||
ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Parent Operation Region object (REGION/BANK fields only) */
|
ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Parent Operation Region object (REGION/BANK fields only) */
|
||||||
|
@ -119,8 +119,8 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exit now for SMBus or IPMI address space, it has a non-linear address space
|
* Exit now for SMBus or IPMI address space, it has a non-linear
|
||||||
* and the request cannot be directly validated
|
* address space and the request cannot be directly validated
|
||||||
*/
|
*/
|
||||||
if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS ||
|
if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS ||
|
||||||
rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) {
|
rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) {
|
||||||
@ -147,8 +147,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
|
|||||||
* (Region length is specified in bytes)
|
* (Region length is specified in bytes)
|
||||||
*/
|
*/
|
||||||
if (rgn_desc->region.length <
|
if (rgn_desc->region.length <
|
||||||
(obj_desc->common_field.base_byte_offset +
|
(obj_desc->common_field.base_byte_offset + field_datum_byte_offset +
|
||||||
field_datum_byte_offset +
|
|
||||||
obj_desc->common_field.access_byte_width)) {
|
obj_desc->common_field.access_byte_width)) {
|
||||||
if (acpi_gbl_enable_interpreter_slack) {
|
if (acpi_gbl_enable_interpreter_slack) {
|
||||||
/*
|
/*
|
||||||
@ -680,6 +679,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
|
|||||||
u32 buffer_tail_bits;
|
u32 buffer_tail_bits;
|
||||||
u32 datum_count;
|
u32 datum_count;
|
||||||
u32 field_datum_count;
|
u32 field_datum_count;
|
||||||
|
u32 access_bit_width;
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ex_extract_from_field);
|
ACPI_FUNCTION_TRACE(ex_extract_from_field);
|
||||||
@ -694,16 +694,36 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
|
|||||||
|
|
||||||
return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
|
return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
ACPI_MEMSET(buffer, 0, buffer_length);
|
ACPI_MEMSET(buffer, 0, buffer_length);
|
||||||
|
access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width);
|
||||||
|
|
||||||
|
/* Handle the simple case here */
|
||||||
|
|
||||||
|
if ((obj_desc->common_field.start_field_bit_offset == 0) &&
|
||||||
|
(obj_desc->common_field.bit_length == access_bit_width)) {
|
||||||
|
status = acpi_ex_field_datum_io(obj_desc, 0, buffer, ACPI_READ);
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TBD: Move to common setup code */
|
||||||
|
|
||||||
|
/* Field algorithm is limited to sizeof(u64), truncate if needed */
|
||||||
|
|
||||||
|
if (obj_desc->common_field.access_byte_width > sizeof(u64)) {
|
||||||
|
obj_desc->common_field.access_byte_width = sizeof(u64);
|
||||||
|
access_bit_width = sizeof(u64) * 8;
|
||||||
|
}
|
||||||
|
|
||||||
/* Compute the number of datums (access width data items) */
|
/* Compute the number of datums (access width data items) */
|
||||||
|
|
||||||
datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
|
datum_count =
|
||||||
obj_desc->common_field.access_bit_width);
|
ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
|
||||||
|
access_bit_width);
|
||||||
|
|
||||||
field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
|
field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
|
||||||
obj_desc->common_field.
|
obj_desc->common_field.
|
||||||
start_field_bit_offset,
|
start_field_bit_offset,
|
||||||
obj_desc->common_field.
|
|
||||||
access_bit_width);
|
access_bit_width);
|
||||||
|
|
||||||
/* Priming read from the field */
|
/* Priming read from the field */
|
||||||
@ -738,12 +758,11 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
|
|||||||
* This avoids the differences in behavior between different compilers
|
* This avoids the differences in behavior between different compilers
|
||||||
* concerning shift values larger than the target data width.
|
* concerning shift values larger than the target data width.
|
||||||
*/
|
*/
|
||||||
if ((obj_desc->common_field.access_bit_width -
|
if (access_bit_width -
|
||||||
obj_desc->common_field.start_field_bit_offset) <
|
obj_desc->common_field.start_field_bit_offset <
|
||||||
ACPI_INTEGER_BIT_SIZE) {
|
ACPI_INTEGER_BIT_SIZE) {
|
||||||
merged_datum |=
|
merged_datum |=
|
||||||
raw_datum << (obj_desc->common_field.
|
raw_datum << (access_bit_width -
|
||||||
access_bit_width -
|
|
||||||
obj_desc->common_field.
|
obj_desc->common_field.
|
||||||
start_field_bit_offset);
|
start_field_bit_offset);
|
||||||
}
|
}
|
||||||
@ -765,8 +784,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
|
|||||||
|
|
||||||
/* Mask off any extra bits in the last datum */
|
/* Mask off any extra bits in the last datum */
|
||||||
|
|
||||||
buffer_tail_bits = obj_desc->common_field.bit_length %
|
buffer_tail_bits = obj_desc->common_field.bit_length % access_bit_width;
|
||||||
obj_desc->common_field.access_bit_width;
|
|
||||||
if (buffer_tail_bits) {
|
if (buffer_tail_bits) {
|
||||||
merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
|
merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
|
||||||
}
|
}
|
||||||
@ -798,6 +816,7 @@ acpi_status
|
|||||||
acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
||||||
void *buffer, u32 buffer_length)
|
void *buffer, u32 buffer_length)
|
||||||
{
|
{
|
||||||
|
void *new_buffer;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
u64 mask;
|
u64 mask;
|
||||||
u64 width_mask;
|
u64 width_mask;
|
||||||
@ -808,9 +827,9 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
|||||||
u32 buffer_tail_bits;
|
u32 buffer_tail_bits;
|
||||||
u32 datum_count;
|
u32 datum_count;
|
||||||
u32 field_datum_count;
|
u32 field_datum_count;
|
||||||
u32 i;
|
u32 access_bit_width;
|
||||||
u32 required_length;
|
u32 required_length;
|
||||||
void *new_buffer;
|
u32 i;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ex_insert_into_field);
|
ACPI_FUNCTION_TRACE(ex_insert_into_field);
|
||||||
|
|
||||||
@ -844,17 +863,24 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
|||||||
buffer_length = required_length;
|
buffer_length = required_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TBD: Move to common setup code */
|
||||||
|
|
||||||
|
/* Algo is limited to sizeof(u64), so cut the access_byte_width */
|
||||||
|
if (obj_desc->common_field.access_byte_width > sizeof(u64)) {
|
||||||
|
obj_desc->common_field.access_byte_width = sizeof(u64);
|
||||||
|
}
|
||||||
|
|
||||||
|
access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the bitmasks used for bit insertion.
|
* Create the bitmasks used for bit insertion.
|
||||||
* Note: This if/else is used to bypass compiler differences with the
|
* Note: This if/else is used to bypass compiler differences with the
|
||||||
* shift operator
|
* shift operator
|
||||||
*/
|
*/
|
||||||
if (obj_desc->common_field.access_bit_width == ACPI_INTEGER_BIT_SIZE) {
|
if (access_bit_width == ACPI_INTEGER_BIT_SIZE) {
|
||||||
width_mask = ACPI_UINT64_MAX;
|
width_mask = ACPI_UINT64_MAX;
|
||||||
} else {
|
} else {
|
||||||
width_mask =
|
width_mask = ACPI_MASK_BITS_ABOVE(access_bit_width);
|
||||||
ACPI_MASK_BITS_ABOVE(obj_desc->common_field.
|
|
||||||
access_bit_width);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mask = width_mask &
|
mask = width_mask &
|
||||||
@ -863,12 +889,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
|||||||
/* Compute the number of datums (access width data items) */
|
/* Compute the number of datums (access width data items) */
|
||||||
|
|
||||||
datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
|
datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
|
||||||
obj_desc->common_field.access_bit_width);
|
access_bit_width);
|
||||||
|
|
||||||
field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
|
field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
|
||||||
obj_desc->common_field.
|
obj_desc->common_field.
|
||||||
start_field_bit_offset,
|
start_field_bit_offset,
|
||||||
obj_desc->common_field.
|
|
||||||
access_bit_width);
|
access_bit_width);
|
||||||
|
|
||||||
/* Get initial Datum from the input buffer */
|
/* Get initial Datum from the input buffer */
|
||||||
@ -905,12 +930,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
|||||||
* This avoids the differences in behavior between different compilers
|
* This avoids the differences in behavior between different compilers
|
||||||
* concerning shift values larger than the target data width.
|
* concerning shift values larger than the target data width.
|
||||||
*/
|
*/
|
||||||
if ((obj_desc->common_field.access_bit_width -
|
if ((access_bit_width -
|
||||||
obj_desc->common_field.start_field_bit_offset) <
|
obj_desc->common_field.start_field_bit_offset) <
|
||||||
ACPI_INTEGER_BIT_SIZE) {
|
ACPI_INTEGER_BIT_SIZE) {
|
||||||
merged_datum =
|
merged_datum =
|
||||||
raw_datum >> (obj_desc->common_field.
|
raw_datum >> (access_bit_width -
|
||||||
access_bit_width -
|
|
||||||
obj_desc->common_field.
|
obj_desc->common_field.
|
||||||
start_field_bit_offset);
|
start_field_bit_offset);
|
||||||
} else {
|
} else {
|
||||||
@ -929,6 +953,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
|||||||
ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset,
|
ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset,
|
||||||
ACPI_MIN(obj_desc->common_field.access_byte_width,
|
ACPI_MIN(obj_desc->common_field.access_byte_width,
|
||||||
buffer_length - buffer_offset));
|
buffer_length - buffer_offset));
|
||||||
|
|
||||||
merged_datum |=
|
merged_datum |=
|
||||||
raw_datum << obj_desc->common_field.start_field_bit_offset;
|
raw_datum << obj_desc->common_field.start_field_bit_offset;
|
||||||
}
|
}
|
||||||
@ -937,7 +962,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
|||||||
|
|
||||||
buffer_tail_bits = (obj_desc->common_field.bit_length +
|
buffer_tail_bits = (obj_desc->common_field.bit_length +
|
||||||
obj_desc->common_field.start_field_bit_offset) %
|
obj_desc->common_field.start_field_bit_offset) %
|
||||||
obj_desc->common_field.access_bit_width;
|
access_bit_width;
|
||||||
if (buffer_tail_bits) {
|
if (buffer_tail_bits) {
|
||||||
mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
|
mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
|
||||||
}
|
}
|
||||||
|
@ -355,12 +355,10 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc,
|
|||||||
return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
|
return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup width (access granularity) fields */
|
/* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */
|
||||||
|
|
||||||
obj_desc->common_field.access_byte_width = (u8)
|
obj_desc->common_field.access_byte_width = (u8)
|
||||||
ACPI_DIV_8(access_bit_width); /* 1, 2, 4, 8 */
|
ACPI_DIV_8(access_bit_width);
|
||||||
|
|
||||||
obj_desc->common_field.access_bit_width = (u8) access_bit_width;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* base_byte_offset is the address of the start of the field within the
|
* base_byte_offset is the address of the start of the field within the
|
||||||
@ -405,8 +403,9 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
|
|||||||
{
|
{
|
||||||
union acpi_operand_object *obj_desc;
|
union acpi_operand_object *obj_desc;
|
||||||
union acpi_operand_object *second_desc = NULL;
|
union acpi_operand_object *second_desc = NULL;
|
||||||
u32 type;
|
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
|
u32 access_byte_width;
|
||||||
|
u32 type;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ex_prep_field_value);
|
ACPI_FUNCTION_TRACE(ex_prep_field_value);
|
||||||
|
|
||||||
@ -421,8 +420,8 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
|
|||||||
type = acpi_ns_get_type(info->region_node);
|
type = acpi_ns_get_type(info->region_node);
|
||||||
if (type != ACPI_TYPE_REGION) {
|
if (type != ACPI_TYPE_REGION) {
|
||||||
ACPI_ERROR((AE_INFO,
|
ACPI_ERROR((AE_INFO,
|
||||||
"Needed Region, found type 0x%X (%s)",
|
"Needed Region, found type 0x%X (%s)", type,
|
||||||
type, acpi_ut_get_type_name(type)));
|
acpi_ut_get_type_name(type)));
|
||||||
|
|
||||||
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
|
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
|
||||||
}
|
}
|
||||||
@ -438,7 +437,8 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
|
|||||||
/* Initialize areas of the object that are common to all fields */
|
/* Initialize areas of the object that are common to all fields */
|
||||||
|
|
||||||
obj_desc->common_field.node = info->field_node;
|
obj_desc->common_field.node = info->field_node;
|
||||||
status = acpi_ex_prep_common_field_object(obj_desc, info->field_flags,
|
status = acpi_ex_prep_common_field_object(obj_desc,
|
||||||
|
info->field_flags,
|
||||||
info->attribute,
|
info->attribute,
|
||||||
info->field_bit_position,
|
info->field_bit_position,
|
||||||
info->field_bit_length);
|
info->field_bit_length);
|
||||||
@ -455,27 +455,26 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
|
|||||||
obj_desc->field.region_obj =
|
obj_desc->field.region_obj =
|
||||||
acpi_ns_get_attached_object(info->region_node);
|
acpi_ns_get_attached_object(info->region_node);
|
||||||
|
|
||||||
|
/* Allow full data read from EC address space */
|
||||||
|
|
||||||
|
if ((obj_desc->field.region_obj->region.space_id ==
|
||||||
|
ACPI_ADR_SPACE_EC)
|
||||||
|
&& (obj_desc->common_field.bit_length > 8)) {
|
||||||
|
access_byte_width =
|
||||||
|
ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.
|
||||||
|
bit_length);
|
||||||
|
|
||||||
|
/* Maximum byte width supported is 255 */
|
||||||
|
|
||||||
|
if (access_byte_width < 256) {
|
||||||
|
obj_desc->common_field.access_byte_width =
|
||||||
|
(u8)access_byte_width;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* An additional reference for the container */
|
/* An additional reference for the container */
|
||||||
|
|
||||||
acpi_ut_add_reference(obj_desc->field.region_obj);
|
acpi_ut_add_reference(obj_desc->field.region_obj);
|
||||||
|
|
||||||
/* allow full data read from EC address space */
|
|
||||||
if (obj_desc->field.region_obj->region.space_id ==
|
|
||||||
ACPI_ADR_SPACE_EC) {
|
|
||||||
if (obj_desc->common_field.bit_length > 8) {
|
|
||||||
unsigned width =
|
|
||||||
ACPI_ROUND_BITS_UP_TO_BYTES(
|
|
||||||
obj_desc->common_field.bit_length);
|
|
||||||
// access_bit_width is u8, don't overflow it
|
|
||||||
if (width > 8)
|
|
||||||
width = 8;
|
|
||||||
obj_desc->common_field.access_byte_width =
|
|
||||||
width;
|
|
||||||
obj_desc->common_field.access_bit_width =
|
|
||||||
8 * width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
|
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
|
||||||
"RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
|
"RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
|
||||||
obj_desc->field.start_field_bit_offset,
|
obj_desc->field.start_field_bit_offset,
|
||||||
|
Loading…
Reference in New Issue
Block a user