RE: [PATCH 08/15] ACPICA: ACPI 6.3: add PCC operation region support for AML interpreter

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



+Sudeep

I forgot to put you as CC. This is the linuxized patch of PCC operation region

> -----Original Message-----
> From: Schmauss, Erik
> Sent: Friday, February 15, 2019 1:36 PM
> To: rjw@xxxxxxxxxxxxx; linux-acpi@xxxxxxxxxxxxxxx
> Cc: Schmauss, Erik <erik.schmauss@xxxxxxxxx>; Moore, Robert
> <robert.moore@xxxxxxxxx>
> Subject: [PATCH 08/15] ACPICA: ACPI 6.3: add PCC operation region
> support for AML interpreter
> 
> ACPICA commit a4849944e80f97970e99843f4975850753584a4e
> 
> This change adds PCC operation region support in the AML interpreter
> and a default handler for acpiexec. According to the specification, the
> PCC operation region performs a transaction when the COMD field is
> written. This allows ASL to write data to other fields before sending the
> data.
> 
> In order to accommodate this protocol, a temorary buffer is added to
> the regionfield object to accumulate writes. If any offset that spans
> COMD is written, the temporary buffer is sent to the PCC operation
> region handler to be processed.
> 
> This change also renames the PCC keyword to
> platform_comm_channel.
> 
> Link: https://github.com/acpica/acpica/commit/a4849944
> Signed-off-by: Erik Schmauss <erik.schmauss@xxxxxxxxx>
> Signed-off-by: Bob Moore <robert.moore@xxxxxxxxx>
> ---
>  drivers/acpi/acpica/acobject.h |  1 +
>  drivers/acpi/acpica/dsfield.c  |  6 +++  drivers/acpi/acpica/exfield.c  |
> 68 ++++++++++++++++++++++++++++++++++
>  drivers/acpi/acpica/utdelete.c |  4 ++
>  4 files changed, 79 insertions(+)
> 
> diff --git a/drivers/acpi/acpica/acobject.h
> b/drivers/acpi/acpica/acobject.h index 0edf8fca7567..b2ef703d7df8
> 100644
> --- a/drivers/acpi/acpica/acobject.h
> +++ b/drivers/acpi/acpica/acobject.h
> @@ -239,6 +239,7 @@ struct acpi_object_region_field {
>  	union acpi_operand_object *region_obj;	/* Containing
> op_region object */
>  	u8 *resource_buffer;	/* resource_template for serial
> regions/fields */
>  	u16 pin_number_index;	/* Index relative to previous
> Connection/Template */
> +	u8 *internal_pcc_buffer;	/* Internal buffer for fields
> associated with PCC */
>  };
> 
>  struct acpi_object_bank_field {
> diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c
> index d51216c9d891..3a7298b58a90 100644
> --- a/drivers/acpi/acpica/dsfield.c
> +++ b/drivers/acpi/acpica/dsfield.c
> @@ -518,6 +518,12 @@ acpi_ds_create_field(union acpi_parse_object
> *op,
>  	info.region_node = region_node;
> 
>  	status = acpi_ds_get_field_names(&info, walk_state, arg-
> >common.next);
> +	if (info.region_node->type ==
> ACPI_ADR_SPACE_PLATFORM_COMM &&
> +	    !(region_node->object->field.internal_pcc_buffer
> +	      =
> +	      ACPI_ALLOCATE_ZEROED(info.region_node->object-
> >region.length))) {
> +		return_ACPI_STATUS(AE_NO_MEMORY);
> +	}
>  	return_ACPI_STATUS(status);
>  }
> 
> diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
> index 7dcdde094582..3760f96b19f9 100644
> --- a/drivers/acpi/acpica/exfield.c
> +++ b/drivers/acpi/acpica/exfield.c
> @@ -41,6 +41,17 @@ const u8 acpi_protocol_lengths[] = {
>  	0xFF			/* F - ATTRIB_RAW_PROCESS_BYTES */
>  };
> 
> +#define PCC_MASTER_SUBSPACE	3
> +
> +/*
> + * The following macros determine a given offset is a COMD field.
> + * According to the specification, generic subspaces (types 0-2)
> +contains a
> + * 2-byte COMD field at offset 4 and master subspaces (type 3)
> contains
> +a 4-byte
> + * COMD field starting at offset 12.
> + */
> +#define GENERIC_SUBSPACE_COMMAND(a)	(4 == a || a == 5)
> +#define MASTER_SUBSPACE_COMMAND(a)	(12 <= a && a <= 15)
> +
> 
> /*****************************************************
> **************************
>   *
>   * FUNCTION:    acpi_ex_get_protocol_buffer_length
> @@ -177,6 +188,25 @@ acpi_ex_read_data_from_field(struct
> acpi_walk_state *walk_state,
> 
>  		status = acpi_ex_read_gpio(obj_desc, buffer);
>  		goto exit;
> +	} else if ((obj_desc->common.type ==
> ACPI_TYPE_LOCAL_REGION_FIELD) &&
> +		   (obj_desc->field.region_obj->region.space_id ==
> +		    ACPI_ADR_SPACE_PLATFORM_COMM)) {
> +		/*
> +		 * Reading from a PCC field unit does not require the
> handler because
> +		 * it only requires reading from the
> internal_pcc_buffer.
> +		 */
> +		ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
> +				  "PCC FieldRead bits %u\n",
> +				  obj_desc->field.bit_length));
> +
> +		memcpy(buffer,
> +		       obj_desc->field.region_obj-
> >field.internal_pcc_buffer +
> +		       obj_desc->field.base_byte_offset,
> +
> (acpi_size)ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->field.
> +							      bit_length));
> +
> +		*ret_buffer_desc = buffer_desc;
> +		return AE_OK;
>  	}
> 
>  	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
> @@ -229,6 +259,7 @@ acpi_ex_write_data_to_field(union
> acpi_operand_object *source_desc,  {
>  	acpi_status status;
>  	u32 buffer_length;
> +	u32 data_length;
>  	void *buffer;
> 
>  	ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field,
> obj_desc); @@ -272,6 +303,43 @@
> acpi_ex_write_data_to_field(union acpi_operand_object
> *source_desc,
>  		    acpi_ex_write_serial_bus(source_desc, obj_desc,
>  					     result_desc);
>  		return_ACPI_STATUS(status);
> +	} else if ((obj_desc->common.type ==
> ACPI_TYPE_LOCAL_REGION_FIELD) &&
> +		   (obj_desc->field.region_obj->region.space_id ==
> +		    ACPI_ADR_SPACE_PLATFORM_COMM)) {
> +		/*
> +		 * According to the spec a write to the COMD field will
> invoke the
> +		 * region handler. Otherwise, write to the pcc_internal
> buffer. This
> +		 * implementation will use the offsets specified rather
> than the name
> +		 * of the field. This is considered safer because some
> firmware tools
> +		 * are known to obfiscate named objects.
> +		 */
> +		data_length =
> +
> (acpi_size)ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->field.
> +							   bit_length);
> +		memcpy(obj_desc->field.region_obj-
> >field.internal_pcc_buffer +
> +		       obj_desc->field.base_byte_offset,
> +		       source_desc->buffer.pointer, data_length);
> +		if ((obj_desc->field.region_obj->region.address ==
> +		     PCC_MASTER_SUBSPACE
> +		     && MASTER_SUBSPACE_COMMAND(obj_desc-
> >field.
> +						base_byte_offset))
> +		    || GENERIC_SUBSPACE_COMMAND(obj_desc-
> >field.
> +						base_byte_offset)) {
> +
> +			/* Perform the write */
> +
> +			ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
> +					  "PCC COMD field has been
> written. Invoking PCC handler
> +now.\n"));
> +
> +			status =
> +			    acpi_ex_access_region(obj_desc, 0,
> +						  (u64 *)obj_desc-
> >field.
> +						  region_obj->field.
> +						  internal_pcc_buffer,
> +						  ACPI_WRITE);
> +			return_ACPI_STATUS(status);
> +		}
> +		return (AE_OK);
>  	}
> 
>  	/* Get a pointer to the data to be written */ diff --git
> a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c
> index 8cc4392c61f3..eee263cb7beb 100644
> --- a/drivers/acpi/acpica/utdelete.c
> +++ b/drivers/acpi/acpica/utdelete.c
> @@ -257,6 +257,10 @@ static void acpi_ut_delete_internal_obj(union
> acpi_operand_object *object)
> 
>  			acpi_ut_delete_object_desc(second_desc);
>  		}
> +		if (object->field.internal_pcc_buffer) {
> +			ACPI_FREE(object->field.internal_pcc_buffer);
> +		}
> +
>  		break;
> 
>  	case ACPI_TYPE_BUFFER_FIELD:
> --
> 2.17.1




[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux