cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

exprep.c (18188B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: exprep - ACPI AML field prep utilities
      5 *
      6 * Copyright (C) 2000 - 2022, Intel Corp.
      7 *
      8 *****************************************************************************/
      9
     10#include <acpi/acpi.h>
     11#include "accommon.h"
     12#include "acinterp.h"
     13#include "amlcode.h"
     14#include "acnamesp.h"
     15#include "acdispat.h"
     16
     17#define _COMPONENT          ACPI_EXECUTER
     18ACPI_MODULE_NAME("exprep")
     19
     20/* Local prototypes */
     21static u32
     22acpi_ex_decode_field_access(union acpi_operand_object *obj_desc,
     23			    u8 field_flags, u32 * return_byte_alignment);
     24
     25#ifdef ACPI_UNDER_DEVELOPMENT
     26
     27static u32
     28acpi_ex_generate_access(u32 field_bit_offset,
     29			u32 field_bit_length, u32 region_length);
     30
     31/*******************************************************************************
     32 *
     33 * FUNCTION:    acpi_ex_generate_access
     34 *
     35 * PARAMETERS:  field_bit_offset    - Start of field within parent region/buffer
     36 *              field_bit_length    - Length of field in bits
     37 *              region_length       - Length of parent in bytes
     38 *
     39 * RETURN:      Field granularity (8, 16, 32 or 64) and
     40 *              byte_alignment (1, 2, 3, or 4)
     41 *
     42 * DESCRIPTION: Generate an optimal access width for fields defined with the
     43 *              any_acc keyword.
     44 *
     45 * NOTE: Need to have the region_length in order to check for boundary
     46 *       conditions (end-of-region). However, the region_length is a deferred
     47 *       operation. Therefore, to complete this implementation, the generation
     48 *       of this access width must be deferred until the region length has
     49 *       been evaluated.
     50 *
     51 ******************************************************************************/
     52
     53static u32
     54acpi_ex_generate_access(u32 field_bit_offset,
     55			u32 field_bit_length, u32 region_length)
     56{
     57	u32 field_byte_length;
     58	u32 field_byte_offset;
     59	u32 field_byte_end_offset;
     60	u32 access_byte_width;
     61	u32 field_start_offset;
     62	u32 field_end_offset;
     63	u32 minimum_access_width = 0xFFFFFFFF;
     64	u32 minimum_accesses = 0xFFFFFFFF;
     65	u32 accesses;
     66
     67	ACPI_FUNCTION_TRACE(ex_generate_access);
     68
     69	/* Round Field start offset and length to "minimal" byte boundaries */
     70
     71	field_byte_offset = ACPI_DIV_8(ACPI_ROUND_DOWN(field_bit_offset, 8));
     72
     73	field_byte_end_offset =
     74	    ACPI_DIV_8(ACPI_ROUND_UP(field_bit_length + field_bit_offset, 8));
     75
     76	field_byte_length = field_byte_end_offset - field_byte_offset;
     77
     78	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
     79			  "Bit length %u, Bit offset %u\n",
     80			  field_bit_length, field_bit_offset));
     81
     82	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
     83			  "Byte Length %u, Byte Offset %u, End Offset %u\n",
     84			  field_byte_length, field_byte_offset,
     85			  field_byte_end_offset));
     86
     87	/*
     88	 * Iterative search for the maximum access width that is both aligned
     89	 * and does not go beyond the end of the region
     90	 *
     91	 * Start at byte_acc and work upwards to qword_acc max. (1,2,4,8 bytes)
     92	 */
     93	for (access_byte_width = 1; access_byte_width <= 8;
     94	     access_byte_width <<= 1) {
     95		/*
     96		 * 1) Round end offset up to next access boundary and make sure that
     97		 *    this does not go beyond the end of the parent region.
     98		 * 2) When the Access width is greater than the field_byte_length, we
     99		 *    are done. (This does not optimize for the perfectly aligned
    100		 *    case yet).
    101		 */
    102		if (ACPI_ROUND_UP(field_byte_end_offset, access_byte_width) <=
    103		    region_length) {
    104			field_start_offset =
    105			    ACPI_ROUND_DOWN(field_byte_offset,
    106					    access_byte_width) /
    107			    access_byte_width;
    108
    109			field_end_offset =
    110			    ACPI_ROUND_UP((field_byte_length +
    111					   field_byte_offset),
    112					  access_byte_width) /
    113			    access_byte_width;
    114
    115			accesses = field_end_offset - field_start_offset;
    116
    117			ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
    118					  "AccessWidth %u end is within region\n",
    119					  access_byte_width));
    120
    121			ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
    122					  "Field Start %u, Field End %u -- requires %u accesses\n",
    123					  field_start_offset, field_end_offset,
    124					  accesses));
    125
    126			/* Single access is optimal */
    127
    128			if (accesses <= 1) {
    129				ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
    130						  "Entire field can be accessed "
    131						  "with one operation of size %u\n",
    132						  access_byte_width));
    133				return_VALUE(access_byte_width);
    134			}
    135
    136			/*
    137			 * Fits in the region, but requires more than one read/write.
    138			 * try the next wider access on next iteration
    139			 */
    140			if (accesses < minimum_accesses) {
    141				minimum_accesses = accesses;
    142				minimum_access_width = access_byte_width;
    143			}
    144		} else {
    145			ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
    146					  "AccessWidth %u end is NOT within region\n",
    147					  access_byte_width));
    148			if (access_byte_width == 1) {
    149				ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
    150						  "Field goes beyond end-of-region!\n"));
    151
    152				/* Field does not fit in the region at all */
    153
    154				return_VALUE(0);
    155			}
    156
    157			/*
    158			 * This width goes beyond the end-of-region, back off to
    159			 * previous access
    160			 */
    161			ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
    162					  "Backing off to previous optimal access width of %u\n",
    163					  minimum_access_width));
    164			return_VALUE(minimum_access_width);
    165		}
    166	}
    167
    168	/*
    169	 * Could not read/write field with one operation,
    170	 * just use max access width
    171	 */
    172	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
    173			  "Cannot access field in one operation, using width 8\n"));
    174
    175	return_VALUE(8);
    176}
    177#endif				/* ACPI_UNDER_DEVELOPMENT */
    178
    179/*******************************************************************************
    180 *
    181 * FUNCTION:    acpi_ex_decode_field_access
    182 *
    183 * PARAMETERS:  obj_desc            - Field object
    184 *              field_flags         - Encoded fieldflags (contains access bits)
    185 *              return_byte_alignment - Where the byte alignment is returned
    186 *
    187 * RETURN:      Field granularity (8, 16, 32 or 64) and
    188 *              byte_alignment (1, 2, 3, or 4)
    189 *
    190 * DESCRIPTION: Decode the access_type bits of a field definition.
    191 *
    192 ******************************************************************************/
    193
    194static u32
    195acpi_ex_decode_field_access(union acpi_operand_object *obj_desc,
    196			    u8 field_flags, u32 * return_byte_alignment)
    197{
    198	u32 access;
    199	u32 byte_alignment;
    200	u32 bit_length;
    201
    202	ACPI_FUNCTION_TRACE(ex_decode_field_access);
    203
    204	access = (field_flags & AML_FIELD_ACCESS_TYPE_MASK);
    205
    206	switch (access) {
    207	case AML_FIELD_ACCESS_ANY:
    208
    209#ifdef ACPI_UNDER_DEVELOPMENT
    210		byte_alignment =
    211		    acpi_ex_generate_access(obj_desc->common_field.
    212					    start_field_bit_offset,
    213					    obj_desc->common_field.bit_length,
    214					    0xFFFFFFFF
    215					    /* Temp until we pass region_length as parameter */
    216		    );
    217		bit_length = byte_alignment * 8;
    218#endif
    219
    220		byte_alignment = 1;
    221		bit_length = 8;
    222		break;
    223
    224	case AML_FIELD_ACCESS_BYTE:
    225	case AML_FIELD_ACCESS_BUFFER:	/* ACPI 2.0 (SMBus Buffer) */
    226
    227		byte_alignment = 1;
    228		bit_length = 8;
    229		break;
    230
    231	case AML_FIELD_ACCESS_WORD:
    232
    233		byte_alignment = 2;
    234		bit_length = 16;
    235		break;
    236
    237	case AML_FIELD_ACCESS_DWORD:
    238
    239		byte_alignment = 4;
    240		bit_length = 32;
    241		break;
    242
    243	case AML_FIELD_ACCESS_QWORD:	/* ACPI 2.0 */
    244
    245		byte_alignment = 8;
    246		bit_length = 64;
    247		break;
    248
    249	default:
    250
    251		/* Invalid field access type */
    252
    253		ACPI_ERROR((AE_INFO, "Unknown field access type 0x%X", access));
    254
    255		return_UINT32(0);
    256	}
    257
    258	if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
    259		/*
    260		 * buffer_field access can be on any byte boundary, so the
    261		 * byte_alignment is always 1 byte -- regardless of any byte_alignment
    262		 * implied by the field access type.
    263		 */
    264		byte_alignment = 1;
    265	}
    266
    267	*return_byte_alignment = byte_alignment;
    268	return_UINT32(bit_length);
    269}
    270
    271/*******************************************************************************
    272 *
    273 * FUNCTION:    acpi_ex_prep_common_field_object
    274 *
    275 * PARAMETERS:  obj_desc            - The field object
    276 *              field_flags         - Access, lock_rule, and update_rule.
    277 *                                    The format of a field_flag is described
    278 *                                    in the ACPI specification
    279 *              field_attribute     - Special attributes (not used)
    280 *              field_bit_position  - Field start position
    281 *              field_bit_length    - Field length in number of bits
    282 *
    283 * RETURN:      Status
    284 *
    285 * DESCRIPTION: Initialize the areas of the field object that are common
    286 *              to the various types of fields. Note: This is very "sensitive"
    287 *              code because we are solving the general case for field
    288 *              alignment.
    289 *
    290 ******************************************************************************/
    291
    292acpi_status
    293acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc,
    294				 u8 field_flags,
    295				 u8 field_attribute,
    296				 u32 field_bit_position, u32 field_bit_length)
    297{
    298	u32 access_bit_width;
    299	u32 byte_alignment;
    300	u32 nearest_byte_address;
    301
    302	ACPI_FUNCTION_TRACE(ex_prep_common_field_object);
    303
    304	/*
    305	 * Note: the structure being initialized is the
    306	 * ACPI_COMMON_FIELD_INFO;  No structure fields outside of the common
    307	 * area are initialized by this procedure.
    308	 */
    309	obj_desc->common_field.field_flags = field_flags;
    310	obj_desc->common_field.attribute = field_attribute;
    311	obj_desc->common_field.bit_length = field_bit_length;
    312
    313	/*
    314	 * Decode the access type so we can compute offsets. The access type gives
    315	 * two pieces of information - the width of each field access and the
    316	 * necessary byte_alignment (address granularity) of the access.
    317	 *
    318	 * For any_acc, the access_bit_width is the largest width that is both
    319	 * necessary and possible in an attempt to access the whole field in one
    320	 * I/O operation. However, for any_acc, the byte_alignment is always one
    321	 * byte.
    322	 *
    323	 * For all Buffer Fields, the byte_alignment is always one byte.
    324	 *
    325	 * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is
    326	 * the same (equivalent) as the byte_alignment.
    327	 */
    328	access_bit_width =
    329	    acpi_ex_decode_field_access(obj_desc, field_flags, &byte_alignment);
    330	if (!access_bit_width) {
    331		return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
    332	}
    333
    334	/* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */
    335
    336	obj_desc->common_field.access_byte_width = (u8)
    337	    ACPI_DIV_8(access_bit_width);
    338
    339	/*
    340	 * base_byte_offset is the address of the start of the field within the
    341	 * region. It is the byte address of the first *datum* (field-width data
    342	 * unit) of the field. (i.e., the first datum that contains at least the
    343	 * first *bit* of the field.)
    344	 *
    345	 * Note: byte_alignment is always either equal to the access_bit_width or 8
    346	 * (Byte access), and it defines the addressing granularity of the parent
    347	 * region or buffer.
    348	 */
    349	nearest_byte_address =
    350	    ACPI_ROUND_BITS_DOWN_TO_BYTES(field_bit_position);
    351	obj_desc->common_field.base_byte_offset = (u32)
    352	    ACPI_ROUND_DOWN(nearest_byte_address, byte_alignment);
    353
    354	/*
    355	 * start_field_bit_offset is the offset of the first bit of the field within
    356	 * a field datum.
    357	 */
    358	obj_desc->common_field.start_field_bit_offset = (u8)
    359	    (field_bit_position -
    360	     ACPI_MUL_8(obj_desc->common_field.base_byte_offset));
    361
    362	return_ACPI_STATUS(AE_OK);
    363}
    364
    365/*******************************************************************************
    366 *
    367 * FUNCTION:    acpi_ex_prep_field_value
    368 *
    369 * PARAMETERS:  info    - Contains all field creation info
    370 *
    371 * RETURN:      Status
    372 *
    373 * DESCRIPTION: Construct an object of type union acpi_operand_object with a
    374 *              subtype of def_field and connect it to the parent Node.
    375 *
    376 ******************************************************************************/
    377
    378acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
    379{
    380	union acpi_operand_object *obj_desc;
    381	union acpi_operand_object *second_desc = NULL;
    382	acpi_status status;
    383	u32 access_byte_width;
    384	u32 type;
    385
    386	ACPI_FUNCTION_TRACE(ex_prep_field_value);
    387
    388	/* Parameter validation */
    389
    390	if (info->field_type != ACPI_TYPE_LOCAL_INDEX_FIELD) {
    391		if (!info->region_node) {
    392			ACPI_ERROR((AE_INFO, "Null RegionNode"));
    393			return_ACPI_STATUS(AE_AML_NO_OPERAND);
    394		}
    395
    396		type = acpi_ns_get_type(info->region_node);
    397		if (type != ACPI_TYPE_REGION) {
    398			ACPI_ERROR((AE_INFO,
    399				    "Needed Region, found type 0x%X (%s)", type,
    400				    acpi_ut_get_type_name(type)));
    401
    402			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
    403		}
    404	}
    405
    406	/* Allocate a new field object */
    407
    408	obj_desc = acpi_ut_create_internal_object(info->field_type);
    409	if (!obj_desc) {
    410		return_ACPI_STATUS(AE_NO_MEMORY);
    411	}
    412
    413	/* Initialize areas of the object that are common to all fields */
    414
    415	obj_desc->common_field.node = info->field_node;
    416	status = acpi_ex_prep_common_field_object(obj_desc,
    417						  info->field_flags,
    418						  info->attribute,
    419						  info->field_bit_position,
    420						  info->field_bit_length);
    421	if (ACPI_FAILURE(status)) {
    422		acpi_ut_delete_object_desc(obj_desc);
    423		return_ACPI_STATUS(status);
    424	}
    425
    426	/* Initialize areas of the object that are specific to the field type */
    427
    428	switch (info->field_type) {
    429	case ACPI_TYPE_LOCAL_REGION_FIELD:
    430
    431		obj_desc->field.region_obj =
    432		    acpi_ns_get_attached_object(info->region_node);
    433
    434		/* Fields specific to generic_serial_bus fields */
    435
    436		obj_desc->field.access_length = info->access_length;
    437
    438		if (info->connection_node) {
    439			second_desc = info->connection_node->object;
    440			if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) {
    441				status =
    442				    acpi_ds_get_buffer_arguments(second_desc);
    443				if (ACPI_FAILURE(status)) {
    444					acpi_ut_delete_object_desc(obj_desc);
    445					return_ACPI_STATUS(status);
    446				}
    447			}
    448
    449			obj_desc->field.resource_buffer =
    450			    second_desc->buffer.pointer;
    451			obj_desc->field.resource_length =
    452			    (u16)second_desc->buffer.length;
    453		} else if (info->resource_buffer) {
    454			obj_desc->field.resource_buffer = info->resource_buffer;
    455			obj_desc->field.resource_length = info->resource_length;
    456		}
    457
    458		obj_desc->field.pin_number_index = info->pin_number_index;
    459
    460		/* Allow full data read from EC address space */
    461
    462		if ((obj_desc->field.region_obj->region.space_id ==
    463		     ACPI_ADR_SPACE_EC)
    464		    && (obj_desc->common_field.bit_length > 8)) {
    465			access_byte_width =
    466			    ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.
    467							bit_length);
    468
    469			/* Maximum byte width supported is 255 */
    470
    471			if (access_byte_width < 256) {
    472				obj_desc->common_field.access_byte_width =
    473				    (u8)access_byte_width;
    474			}
    475		}
    476		ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
    477				  "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
    478				  obj_desc->field.start_field_bit_offset,
    479				  obj_desc->field.base_byte_offset,
    480				  obj_desc->field.access_byte_width,
    481				  obj_desc->field.region_obj));
    482		break;
    483
    484	case ACPI_TYPE_LOCAL_BANK_FIELD:
    485
    486		obj_desc->bank_field.value = info->bank_value;
    487		obj_desc->bank_field.region_obj =
    488		    acpi_ns_get_attached_object(info->region_node);
    489		obj_desc->bank_field.bank_obj =
    490		    acpi_ns_get_attached_object(info->register_node);
    491
    492		/* An additional reference for the attached objects */
    493
    494		acpi_ut_add_reference(obj_desc->bank_field.region_obj);
    495		acpi_ut_add_reference(obj_desc->bank_field.bank_obj);
    496
    497		ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
    498				  "Bank Field: BitOff %X, Off %X, Gran %X, Region %p, BankReg %p\n",
    499				  obj_desc->bank_field.start_field_bit_offset,
    500				  obj_desc->bank_field.base_byte_offset,
    501				  obj_desc->field.access_byte_width,
    502				  obj_desc->bank_field.region_obj,
    503				  obj_desc->bank_field.bank_obj));
    504
    505		/*
    506		 * Remember location in AML stream of the field unit
    507		 * opcode and operands -- since the bank_value
    508		 * operands must be evaluated.
    509		 */
    510		second_desc = obj_desc->common.next_object;
    511		second_desc->extra.aml_start =
    512		    ACPI_CAST_PTR(union acpi_parse_object,
    513				  info->data_register_node)->named.data;
    514		second_desc->extra.aml_length =
    515		    ACPI_CAST_PTR(union acpi_parse_object,
    516				  info->data_register_node)->named.length;
    517
    518		break;
    519
    520	case ACPI_TYPE_LOCAL_INDEX_FIELD:
    521
    522		/* Get the Index and Data registers */
    523
    524		obj_desc->index_field.index_obj =
    525		    acpi_ns_get_attached_object(info->register_node);
    526		obj_desc->index_field.data_obj =
    527		    acpi_ns_get_attached_object(info->data_register_node);
    528
    529		if (!obj_desc->index_field.data_obj
    530		    || !obj_desc->index_field.index_obj) {
    531			ACPI_ERROR((AE_INFO,
    532				    "Null Index Object during field prep"));
    533			acpi_ut_delete_object_desc(obj_desc);
    534			return_ACPI_STATUS(AE_AML_INTERNAL);
    535		}
    536
    537		/* An additional reference for the attached objects */
    538
    539		acpi_ut_add_reference(obj_desc->index_field.data_obj);
    540		acpi_ut_add_reference(obj_desc->index_field.index_obj);
    541
    542		/*
    543		 * April 2006: Changed to match MS behavior
    544		 *
    545		 * The value written to the Index register is the byte offset of the
    546		 * target field in units of the granularity of the index_field
    547		 *
    548		 * Previously, the value was calculated as an index in terms of the
    549		 * width of the Data register, as below:
    550		 *
    551		 *      obj_desc->index_field.Value = (u32)
    552		 *          (Info->field_bit_position / ACPI_MUL_8 (
    553		 *              obj_desc->Field.access_byte_width));
    554		 *
    555		 * February 2006: Tried value as a byte offset:
    556		 *      obj_desc->index_field.Value = (u32)
    557		 *          ACPI_DIV_8 (Info->field_bit_position);
    558		 */
    559		obj_desc->index_field.value =
    560		    (u32) ACPI_ROUND_DOWN(ACPI_DIV_8(info->field_bit_position),
    561					  obj_desc->index_field.
    562					  access_byte_width);
    563
    564		ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
    565				  "IndexField: BitOff %X, Off %X, Value %X, "
    566				  "Gran %X, Index %p, Data %p\n",
    567				  obj_desc->index_field.start_field_bit_offset,
    568				  obj_desc->index_field.base_byte_offset,
    569				  obj_desc->index_field.value,
    570				  obj_desc->field.access_byte_width,
    571				  obj_desc->index_field.index_obj,
    572				  obj_desc->index_field.data_obj));
    573		break;
    574
    575	default:
    576
    577		/* No other types should get here */
    578
    579		break;
    580	}
    581
    582	/*
    583	 * Store the constructed descriptor (obj_desc) into the parent Node,
    584	 * preserving the current type of that named_obj.
    585	 */
    586	status =
    587	    acpi_ns_attach_object(info->field_node, obj_desc,
    588				  acpi_ns_get_type(info->field_node));
    589
    590	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
    591			  "Set NamedObj %p [%4.4s], ObjDesc %p\n",
    592			  info->field_node,
    593			  acpi_ut_get_node_name(info->field_node), obj_desc));
    594
    595	/* Remove local reference to the object */
    596
    597	acpi_ut_remove_reference(obj_desc);
    598	return_ACPI_STATUS(status);
    599}