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

exconvrt.c (16956B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: exconvrt - Object conversion routines
      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
     15#define _COMPONENT          ACPI_EXECUTER
     16ACPI_MODULE_NAME("exconvrt")
     17
     18/* Local prototypes */
     19static u32
     20acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 max_length);
     21
     22/*******************************************************************************
     23 *
     24 * FUNCTION:    acpi_ex_convert_to_integer
     25 *
     26 * PARAMETERS:  obj_desc            - Object to be converted. Must be an
     27 *                                    Integer, Buffer, or String
     28 *              result_desc         - Where the new Integer object is returned
     29 *              implicit_conversion - Used for string conversion
     30 *
     31 * RETURN:      Status
     32 *
     33 * DESCRIPTION: Convert an ACPI Object to an integer.
     34 *
     35 ******************************************************************************/
     36
     37acpi_status
     38acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
     39			   union acpi_operand_object **result_desc,
     40			   u32 implicit_conversion)
     41{
     42	union acpi_operand_object *return_desc;
     43	u8 *pointer;
     44	u64 result;
     45	u32 i;
     46	u32 count;
     47
     48	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc);
     49
     50	switch (obj_desc->common.type) {
     51	case ACPI_TYPE_INTEGER:
     52
     53		/* No conversion necessary */
     54
     55		*result_desc = obj_desc;
     56		return_ACPI_STATUS(AE_OK);
     57
     58	case ACPI_TYPE_BUFFER:
     59	case ACPI_TYPE_STRING:
     60
     61		/* Note: Takes advantage of common buffer/string fields */
     62
     63		pointer = obj_desc->buffer.pointer;
     64		count = obj_desc->buffer.length;
     65		break;
     66
     67	default:
     68
     69		return_ACPI_STATUS(AE_TYPE);
     70	}
     71
     72	/*
     73	 * Convert the buffer/string to an integer. Note that both buffers and
     74	 * strings are treated as raw data - we don't convert ascii to hex for
     75	 * strings.
     76	 *
     77	 * There are two terminating conditions for the loop:
     78	 * 1) The size of an integer has been reached, or
     79	 * 2) The end of the buffer or string has been reached
     80	 */
     81	result = 0;
     82
     83	/* String conversion is different than Buffer conversion */
     84
     85	switch (obj_desc->common.type) {
     86	case ACPI_TYPE_STRING:
     87		/*
     88		 * Convert string to an integer - for most cases, the string must be
     89		 * hexadecimal as per the ACPI specification. The only exception (as
     90		 * of ACPI 3.0) is that the to_integer() operator allows both decimal
     91		 * and hexadecimal strings (hex prefixed with "0x").
     92		 *
     93		 * Explicit conversion is used only by to_integer.
     94		 * All other string-to-integer conversions are implicit conversions.
     95		 */
     96		if (implicit_conversion) {
     97			result =
     98			    acpi_ut_implicit_strtoul64(ACPI_CAST_PTR
     99						       (char, pointer));
    100		} else {
    101			result =
    102			    acpi_ut_explicit_strtoul64(ACPI_CAST_PTR
    103						       (char, pointer));
    104		}
    105		break;
    106
    107	case ACPI_TYPE_BUFFER:
    108
    109		/* Check for zero-length buffer */
    110
    111		if (!count) {
    112			return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
    113		}
    114
    115		/* Transfer no more than an integer's worth of data */
    116
    117		if (count > acpi_gbl_integer_byte_width) {
    118			count = acpi_gbl_integer_byte_width;
    119		}
    120
    121		/*
    122		 * Convert buffer to an integer - we simply grab enough raw data
    123		 * from the buffer to fill an integer
    124		 */
    125		for (i = 0; i < count; i++) {
    126			/*
    127			 * Get next byte and shift it into the Result.
    128			 * Little endian is used, meaning that the first byte of the buffer
    129			 * is the LSB of the integer
    130			 */
    131			result |= (((u64) pointer[i]) << (i * 8));
    132		}
    133		break;
    134
    135	default:
    136
    137		/* No other types can get here */
    138
    139		break;
    140	}
    141
    142	/* Create a new integer */
    143
    144	return_desc = acpi_ut_create_integer_object(result);
    145	if (!return_desc) {
    146		return_ACPI_STATUS(AE_NO_MEMORY);
    147	}
    148
    149	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
    150			  ACPI_FORMAT_UINT64(result)));
    151
    152	/* Save the Result */
    153
    154	(void)acpi_ex_truncate_for32bit_table(return_desc);
    155	*result_desc = return_desc;
    156	return_ACPI_STATUS(AE_OK);
    157}
    158
    159/*******************************************************************************
    160 *
    161 * FUNCTION:    acpi_ex_convert_to_buffer
    162 *
    163 * PARAMETERS:  obj_desc        - Object to be converted. Must be an
    164 *                                Integer, Buffer, or String
    165 *              result_desc     - Where the new buffer object is returned
    166 *
    167 * RETURN:      Status
    168 *
    169 * DESCRIPTION: Convert an ACPI Object to a Buffer
    170 *
    171 ******************************************************************************/
    172
    173acpi_status
    174acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc,
    175			  union acpi_operand_object **result_desc)
    176{
    177	union acpi_operand_object *return_desc;
    178	u8 *new_buf;
    179
    180	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc);
    181
    182	switch (obj_desc->common.type) {
    183	case ACPI_TYPE_BUFFER:
    184
    185		/* No conversion necessary */
    186
    187		*result_desc = obj_desc;
    188		return_ACPI_STATUS(AE_OK);
    189
    190	case ACPI_TYPE_INTEGER:
    191		/*
    192		 * Create a new Buffer object.
    193		 * Need enough space for one integer
    194		 */
    195		return_desc =
    196		    acpi_ut_create_buffer_object(acpi_gbl_integer_byte_width);
    197		if (!return_desc) {
    198			return_ACPI_STATUS(AE_NO_MEMORY);
    199		}
    200
    201		/* Copy the integer to the buffer, LSB first */
    202
    203		new_buf = return_desc->buffer.pointer;
    204		memcpy(new_buf, &obj_desc->integer.value,
    205		       acpi_gbl_integer_byte_width);
    206		break;
    207
    208	case ACPI_TYPE_STRING:
    209		/*
    210		 * Create a new Buffer object
    211		 * Size will be the string length
    212		 *
    213		 * NOTE: Add one to the string length to include the null terminator.
    214		 * The ACPI spec is unclear on this subject, but there is existing
    215		 * ASL/AML code that depends on the null being transferred to the new
    216		 * buffer.
    217		 */
    218		return_desc = acpi_ut_create_buffer_object((acpi_size)
    219							   obj_desc->string.
    220							   length + 1);
    221		if (!return_desc) {
    222			return_ACPI_STATUS(AE_NO_MEMORY);
    223		}
    224
    225		/* Copy the string to the buffer */
    226
    227		new_buf = return_desc->buffer.pointer;
    228		strncpy((char *)new_buf, (char *)obj_desc->string.pointer,
    229			obj_desc->string.length);
    230		break;
    231
    232	default:
    233
    234		return_ACPI_STATUS(AE_TYPE);
    235	}
    236
    237	/* Mark buffer initialized */
    238
    239	return_desc->common.flags |= AOPOBJ_DATA_VALID;
    240	*result_desc = return_desc;
    241	return_ACPI_STATUS(AE_OK);
    242}
    243
    244/*******************************************************************************
    245 *
    246 * FUNCTION:    acpi_ex_convert_to_ascii
    247 *
    248 * PARAMETERS:  integer         - Value to be converted
    249 *              base            - ACPI_STRING_DECIMAL or ACPI_STRING_HEX
    250 *              string          - Where the string is returned
    251 *              data_width      - Size of data item to be converted, in bytes
    252 *
    253 * RETURN:      Actual string length
    254 *
    255 * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string
    256 *
    257 ******************************************************************************/
    258
    259static u32
    260acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 data_width)
    261{
    262	u64 digit;
    263	u32 i;
    264	u32 j;
    265	u32 k = 0;
    266	u32 hex_length;
    267	u32 decimal_length;
    268	u32 remainder;
    269	u8 supress_zeros;
    270
    271	ACPI_FUNCTION_ENTRY();
    272
    273	switch (base) {
    274	case 10:
    275
    276		/* Setup max length for the decimal number */
    277
    278		switch (data_width) {
    279		case 1:
    280
    281			decimal_length = ACPI_MAX8_DECIMAL_DIGITS;
    282			break;
    283
    284		case 4:
    285
    286			decimal_length = ACPI_MAX32_DECIMAL_DIGITS;
    287			break;
    288
    289		case 8:
    290		default:
    291
    292			decimal_length = ACPI_MAX64_DECIMAL_DIGITS;
    293			break;
    294		}
    295
    296		supress_zeros = TRUE;	/* No leading zeros */
    297		remainder = 0;
    298
    299		for (i = decimal_length; i > 0; i--) {
    300
    301			/* Divide by nth factor of 10 */
    302
    303			digit = integer;
    304			for (j = 0; j < i; j++) {
    305				(void)acpi_ut_short_divide(digit, 10, &digit,
    306							   &remainder);
    307			}
    308
    309			/* Handle leading zeros */
    310
    311			if (remainder != 0) {
    312				supress_zeros = FALSE;
    313			}
    314
    315			if (!supress_zeros) {
    316				string[k] = (u8) (ACPI_ASCII_ZERO + remainder);
    317				k++;
    318			}
    319		}
    320		break;
    321
    322	case 16:
    323
    324		/* hex_length: 2 ascii hex chars per data byte */
    325
    326		hex_length = (data_width * 2);
    327		for (i = 0, j = (hex_length - 1); i < hex_length; i++, j--) {
    328
    329			/* Get one hex digit, most significant digits first */
    330
    331			string[k] = (u8)
    332			    acpi_ut_hex_to_ascii_char(integer, ACPI_MUL_4(j));
    333			k++;
    334		}
    335		break;
    336
    337	default:
    338		return (0);
    339	}
    340
    341	/*
    342	 * Since leading zeros are suppressed, we must check for the case where
    343	 * the integer equals 0
    344	 *
    345	 * Finally, null terminate the string and return the length
    346	 */
    347	if (!k) {
    348		string[0] = ACPI_ASCII_ZERO;
    349		k = 1;
    350	}
    351
    352	string[k] = 0;
    353	return ((u32) k);
    354}
    355
    356/*******************************************************************************
    357 *
    358 * FUNCTION:    acpi_ex_convert_to_string
    359 *
    360 * PARAMETERS:  obj_desc        - Object to be converted. Must be an
    361 *                                Integer, Buffer, or String
    362 *              result_desc     - Where the string object is returned
    363 *              type            - String flags (base and conversion type)
    364 *
    365 * RETURN:      Status
    366 *
    367 * DESCRIPTION: Convert an ACPI Object to a string. Supports both implicit
    368 *              and explicit conversions and related rules.
    369 *
    370 ******************************************************************************/
    371
    372acpi_status
    373acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
    374			  union acpi_operand_object ** result_desc, u32 type)
    375{
    376	union acpi_operand_object *return_desc;
    377	u8 *new_buf;
    378	u32 i;
    379	u32 string_length = 0;
    380	u16 base = 16;
    381	u8 separator = ',';
    382
    383	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc);
    384
    385	switch (obj_desc->common.type) {
    386	case ACPI_TYPE_STRING:
    387
    388		/* No conversion necessary */
    389
    390		*result_desc = obj_desc;
    391		return_ACPI_STATUS(AE_OK);
    392
    393	case ACPI_TYPE_INTEGER:
    394
    395		switch (type) {
    396		case ACPI_EXPLICIT_CONVERT_DECIMAL:
    397			/*
    398			 * From to_decimal_string, integer source.
    399			 *
    400			 * Make room for the maximum decimal number size
    401			 */
    402			string_length = ACPI_MAX_DECIMAL_DIGITS;
    403			base = 10;
    404			break;
    405
    406		default:
    407
    408			/* Two hex string characters for each integer byte */
    409
    410			string_length = ACPI_MUL_2(acpi_gbl_integer_byte_width);
    411			break;
    412		}
    413
    414		/*
    415		 * Create a new String
    416		 * Need enough space for one ASCII integer (plus null terminator)
    417		 */
    418		return_desc =
    419		    acpi_ut_create_string_object((acpi_size)string_length);
    420		if (!return_desc) {
    421			return_ACPI_STATUS(AE_NO_MEMORY);
    422		}
    423
    424		new_buf = return_desc->buffer.pointer;
    425
    426		/* Convert integer to string */
    427
    428		string_length =
    429		    acpi_ex_convert_to_ascii(obj_desc->integer.value, base,
    430					     new_buf,
    431					     acpi_gbl_integer_byte_width);
    432
    433		/* Null terminate at the correct place */
    434
    435		return_desc->string.length = string_length;
    436		new_buf[string_length] = 0;
    437		break;
    438
    439	case ACPI_TYPE_BUFFER:
    440
    441		/* Setup string length, base, and separator */
    442
    443		switch (type) {
    444		case ACPI_EXPLICIT_CONVERT_DECIMAL:	/* Used by to_decimal_string */
    445			/*
    446			 * Explicit conversion from the to_decimal_string ASL operator.
    447			 *
    448			 * From ACPI: "If the input is a buffer, it is converted to a
    449			 * a string of decimal values separated by commas."
    450			 */
    451			base = 10;
    452
    453			/*
    454			 * Calculate the final string length. Individual string values
    455			 * are variable length (include separator for each)
    456			 */
    457			for (i = 0; i < obj_desc->buffer.length; i++) {
    458				if (obj_desc->buffer.pointer[i] >= 100) {
    459					string_length += 4;
    460				} else if (obj_desc->buffer.pointer[i] >= 10) {
    461					string_length += 3;
    462				} else {
    463					string_length += 2;
    464				}
    465			}
    466			break;
    467
    468		case ACPI_IMPLICIT_CONVERT_HEX:
    469			/*
    470			 * Implicit buffer-to-string conversion
    471			 *
    472			 * From the ACPI spec:
    473			 * "The entire contents of the buffer are converted to a string of
    474			 * two-character hexadecimal numbers, each separated by a space."
    475			 *
    476			 * Each hex number is prefixed with 0x (11/2018)
    477			 */
    478			separator = ' ';
    479			string_length = (obj_desc->buffer.length * 5);
    480			break;
    481
    482		case ACPI_EXPLICIT_CONVERT_HEX:
    483			/*
    484			 * Explicit conversion from the to_hex_string ASL operator.
    485			 *
    486			 * From ACPI: "If Data is a buffer, it is converted to a string of
    487			 * hexadecimal values separated by commas."
    488			 *
    489			 * Each hex number is prefixed with 0x (11/2018)
    490			 */
    491			separator = ',';
    492			string_length = (obj_desc->buffer.length * 5);
    493			break;
    494
    495		default:
    496			return_ACPI_STATUS(AE_BAD_PARAMETER);
    497		}
    498
    499		/*
    500		 * Create a new string object and string buffer
    501		 * (-1 because of extra separator included in string_length from above)
    502		 * Allow creation of zero-length strings from zero-length buffers.
    503		 */
    504		if (string_length) {
    505			string_length--;
    506		}
    507
    508		return_desc =
    509		    acpi_ut_create_string_object((acpi_size)string_length);
    510		if (!return_desc) {
    511			return_ACPI_STATUS(AE_NO_MEMORY);
    512		}
    513
    514		new_buf = return_desc->buffer.pointer;
    515
    516		/*
    517		 * Convert buffer bytes to hex or decimal values
    518		 * (separated by commas or spaces)
    519		 */
    520		for (i = 0; i < obj_desc->buffer.length; i++) {
    521			if (base == 16) {
    522
    523				/* Emit 0x prefix for explicit/implicit hex conversion */
    524
    525				*new_buf++ = '0';
    526				*new_buf++ = 'x';
    527			}
    528
    529			new_buf += acpi_ex_convert_to_ascii((u64) obj_desc->
    530							    buffer.pointer[i],
    531							    base, new_buf, 1);
    532
    533			/* Each digit is separated by either a comma or space */
    534
    535			*new_buf++ = separator;
    536		}
    537
    538		/*
    539		 * Null terminate the string
    540		 * (overwrites final comma/space from above)
    541		 */
    542		if (obj_desc->buffer.length) {
    543			new_buf--;
    544		}
    545		*new_buf = 0;
    546		break;
    547
    548	default:
    549
    550		return_ACPI_STATUS(AE_TYPE);
    551	}
    552
    553	*result_desc = return_desc;
    554	return_ACPI_STATUS(AE_OK);
    555}
    556
    557/*******************************************************************************
    558 *
    559 * FUNCTION:    acpi_ex_convert_to_target_type
    560 *
    561 * PARAMETERS:  destination_type    - Current type of the destination
    562 *              source_desc         - Source object to be converted.
    563 *              result_desc         - Where the converted object is returned
    564 *              walk_state          - Current method state
    565 *
    566 * RETURN:      Status
    567 *
    568 * DESCRIPTION: Implements "implicit conversion" rules for storing an object.
    569 *
    570 ******************************************************************************/
    571
    572acpi_status
    573acpi_ex_convert_to_target_type(acpi_object_type destination_type,
    574			       union acpi_operand_object *source_desc,
    575			       union acpi_operand_object **result_desc,
    576			       struct acpi_walk_state *walk_state)
    577{
    578	acpi_status status = AE_OK;
    579
    580	ACPI_FUNCTION_TRACE(ex_convert_to_target_type);
    581
    582	/* Default behavior */
    583
    584	*result_desc = source_desc;
    585
    586	/*
    587	 * If required by the target,
    588	 * perform implicit conversion on the source before we store it.
    589	 */
    590	switch (GET_CURRENT_ARG_TYPE(walk_state->op_info->runtime_args)) {
    591	case ARGI_SIMPLE_TARGET:
    592	case ARGI_FIXED_TARGET:
    593	case ARGI_INTEGER_REF:	/* Handles Increment, Decrement cases */
    594
    595		switch (destination_type) {
    596		case ACPI_TYPE_LOCAL_REGION_FIELD:
    597			/*
    598			 * Named field can always handle conversions
    599			 */
    600			break;
    601
    602		default:
    603
    604			/* No conversion allowed for these types */
    605
    606			if (destination_type != source_desc->common.type) {
    607				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
    608						  "Explicit operator, will store (%s) over existing type (%s)\n",
    609						  acpi_ut_get_object_type_name
    610						  (source_desc),
    611						  acpi_ut_get_type_name
    612						  (destination_type)));
    613				status = AE_TYPE;
    614			}
    615		}
    616		break;
    617
    618	case ARGI_TARGETREF:
    619	case ARGI_STORE_TARGET:
    620
    621		switch (destination_type) {
    622		case ACPI_TYPE_INTEGER:
    623		case ACPI_TYPE_BUFFER_FIELD:
    624		case ACPI_TYPE_LOCAL_BANK_FIELD:
    625		case ACPI_TYPE_LOCAL_INDEX_FIELD:
    626			/*
    627			 * These types require an Integer operand. We can convert
    628			 * a Buffer or a String to an Integer if necessary.
    629			 */
    630			status =
    631			    acpi_ex_convert_to_integer(source_desc, result_desc,
    632						       ACPI_IMPLICIT_CONVERSION);
    633			break;
    634
    635		case ACPI_TYPE_STRING:
    636			/*
    637			 * The operand must be a String. We can convert an
    638			 * Integer or Buffer if necessary
    639			 */
    640			status =
    641			    acpi_ex_convert_to_string(source_desc, result_desc,
    642						      ACPI_IMPLICIT_CONVERT_HEX);
    643			break;
    644
    645		case ACPI_TYPE_BUFFER:
    646			/*
    647			 * The operand must be a Buffer. We can convert an
    648			 * Integer or String if necessary
    649			 */
    650			status =
    651			    acpi_ex_convert_to_buffer(source_desc, result_desc);
    652			break;
    653
    654		default:
    655
    656			ACPI_ERROR((AE_INFO,
    657				    "Bad destination type during conversion: 0x%X",
    658				    destination_type));
    659			status = AE_AML_INTERNAL;
    660			break;
    661		}
    662		break;
    663
    664	case ARGI_REFERENCE:
    665		/*
    666		 * create_xxxx_field cases - we are storing the field object into the name
    667		 */
    668		break;
    669
    670	default:
    671
    672		ACPI_ERROR((AE_INFO,
    673			    "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s",
    674			    GET_CURRENT_ARG_TYPE(walk_state->op_info->
    675						 runtime_args),
    676			    walk_state->opcode,
    677			    acpi_ut_get_type_name(destination_type)));
    678		status = AE_AML_INTERNAL;
    679	}
    680
    681	/*
    682	 * Source-to-Target conversion semantics:
    683	 *
    684	 * If conversion to the target type cannot be performed, then simply
    685	 * overwrite the target with the new object and type.
    686	 */
    687	if (status == AE_TYPE) {
    688		status = AE_OK;
    689	}
    690
    691	return_ACPI_STATUS(status);
    692}