162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 262306a36Sopenharmony_ci/******************************************************************************* 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Module Name: rsutils - Utilities for the resource manager 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci ******************************************************************************/ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <acpi/acpi.h> 962306a36Sopenharmony_ci#include "accommon.h" 1062306a36Sopenharmony_ci#include "acnamesp.h" 1162306a36Sopenharmony_ci#include "acresrc.h" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#define _COMPONENT ACPI_RESOURCES 1462306a36Sopenharmony_ciACPI_MODULE_NAME("rsutils") 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci/******************************************************************************* 1762306a36Sopenharmony_ci * 1862306a36Sopenharmony_ci * FUNCTION: acpi_rs_decode_bitmask 1962306a36Sopenharmony_ci * 2062306a36Sopenharmony_ci * PARAMETERS: mask - Bitmask to decode 2162306a36Sopenharmony_ci * list - Where the converted list is returned 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci * RETURN: Count of bits set (length of list) 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * DESCRIPTION: Convert a bit mask into a list of values 2662306a36Sopenharmony_ci * 2762306a36Sopenharmony_ci ******************************************************************************/ 2862306a36Sopenharmony_ciu8 acpi_rs_decode_bitmask(u16 mask, u8 * list) 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci u8 i; 3162306a36Sopenharmony_ci u8 bit_count; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci ACPI_FUNCTION_ENTRY(); 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci /* Decode the mask bits */ 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci for (i = 0, bit_count = 0; mask; i++) { 3862306a36Sopenharmony_ci if (mask & 0x0001) { 3962306a36Sopenharmony_ci list[bit_count] = i; 4062306a36Sopenharmony_ci bit_count++; 4162306a36Sopenharmony_ci } 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci mask >>= 1; 4462306a36Sopenharmony_ci } 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci return (bit_count); 4762306a36Sopenharmony_ci} 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci/******************************************************************************* 5062306a36Sopenharmony_ci * 5162306a36Sopenharmony_ci * FUNCTION: acpi_rs_encode_bitmask 5262306a36Sopenharmony_ci * 5362306a36Sopenharmony_ci * PARAMETERS: list - List of values to encode 5462306a36Sopenharmony_ci * count - Length of list 5562306a36Sopenharmony_ci * 5662306a36Sopenharmony_ci * RETURN: Encoded bitmask 5762306a36Sopenharmony_ci * 5862306a36Sopenharmony_ci * DESCRIPTION: Convert a list of values to an encoded bitmask 5962306a36Sopenharmony_ci * 6062306a36Sopenharmony_ci ******************************************************************************/ 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ciu16 acpi_rs_encode_bitmask(u8 * list, u8 count) 6362306a36Sopenharmony_ci{ 6462306a36Sopenharmony_ci u32 i; 6562306a36Sopenharmony_ci u16 mask; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci ACPI_FUNCTION_ENTRY(); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci /* Encode the list into a single bitmask */ 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci for (i = 0, mask = 0; i < count; i++) { 7262306a36Sopenharmony_ci mask |= (0x1 << list[i]); 7362306a36Sopenharmony_ci } 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci return (mask); 7662306a36Sopenharmony_ci} 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci/******************************************************************************* 7962306a36Sopenharmony_ci * 8062306a36Sopenharmony_ci * FUNCTION: acpi_rs_move_data 8162306a36Sopenharmony_ci * 8262306a36Sopenharmony_ci * PARAMETERS: destination - Pointer to the destination descriptor 8362306a36Sopenharmony_ci * source - Pointer to the source descriptor 8462306a36Sopenharmony_ci * item_count - How many items to move 8562306a36Sopenharmony_ci * move_type - Byte width 8662306a36Sopenharmony_ci * 8762306a36Sopenharmony_ci * RETURN: None 8862306a36Sopenharmony_ci * 8962306a36Sopenharmony_ci * DESCRIPTION: Move multiple data items from one descriptor to another. Handles 9062306a36Sopenharmony_ci * alignment issues and endian issues if necessary, as configured 9162306a36Sopenharmony_ci * via the ACPI_MOVE_* macros. (This is why a memcpy is not used) 9262306a36Sopenharmony_ci * 9362306a36Sopenharmony_ci ******************************************************************************/ 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_civoid 9662306a36Sopenharmony_ciacpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) 9762306a36Sopenharmony_ci{ 9862306a36Sopenharmony_ci u32 i; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci ACPI_FUNCTION_ENTRY(); 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci /* One move per item */ 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci for (i = 0; i < item_count; i++) { 10562306a36Sopenharmony_ci switch (move_type) { 10662306a36Sopenharmony_ci /* 10762306a36Sopenharmony_ci * For the 8-bit case, we can perform the move all at once 10862306a36Sopenharmony_ci * since there are no alignment or endian issues 10962306a36Sopenharmony_ci */ 11062306a36Sopenharmony_ci case ACPI_RSC_MOVE8: 11162306a36Sopenharmony_ci case ACPI_RSC_MOVE_GPIO_RES: 11262306a36Sopenharmony_ci case ACPI_RSC_MOVE_SERIAL_VEN: 11362306a36Sopenharmony_ci case ACPI_RSC_MOVE_SERIAL_RES: 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci memcpy(destination, source, item_count); 11662306a36Sopenharmony_ci return; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci /* 11962306a36Sopenharmony_ci * 16-, 32-, and 64-bit cases must use the move macros that perform 12062306a36Sopenharmony_ci * endian conversion and/or accommodate hardware that cannot perform 12162306a36Sopenharmony_ci * misaligned memory transfers 12262306a36Sopenharmony_ci */ 12362306a36Sopenharmony_ci case ACPI_RSC_MOVE16: 12462306a36Sopenharmony_ci case ACPI_RSC_MOVE_GPIO_PIN: 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i], 12762306a36Sopenharmony_ci &ACPI_CAST_PTR(u16, source)[i]); 12862306a36Sopenharmony_ci break; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci case ACPI_RSC_MOVE32: 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci ACPI_MOVE_32_TO_32(&ACPI_CAST_PTR(u32, destination)[i], 13362306a36Sopenharmony_ci &ACPI_CAST_PTR(u32, source)[i]); 13462306a36Sopenharmony_ci break; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci case ACPI_RSC_MOVE64: 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci ACPI_MOVE_64_TO_64(&ACPI_CAST_PTR(u64, destination)[i], 13962306a36Sopenharmony_ci &ACPI_CAST_PTR(u64, source)[i]); 14062306a36Sopenharmony_ci break; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci default: 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci return; 14562306a36Sopenharmony_ci } 14662306a36Sopenharmony_ci } 14762306a36Sopenharmony_ci} 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci/******************************************************************************* 15062306a36Sopenharmony_ci * 15162306a36Sopenharmony_ci * FUNCTION: acpi_rs_set_resource_length 15262306a36Sopenharmony_ci * 15362306a36Sopenharmony_ci * PARAMETERS: total_length - Length of the AML descriptor, including 15462306a36Sopenharmony_ci * the header and length fields. 15562306a36Sopenharmony_ci * aml - Pointer to the raw AML descriptor 15662306a36Sopenharmony_ci * 15762306a36Sopenharmony_ci * RETURN: None 15862306a36Sopenharmony_ci * 15962306a36Sopenharmony_ci * DESCRIPTION: Set the resource_length field of an AML 16062306a36Sopenharmony_ci * resource descriptor, both Large and Small descriptors are 16162306a36Sopenharmony_ci * supported automatically. Note: Descriptor Type field must 16262306a36Sopenharmony_ci * be valid. 16362306a36Sopenharmony_ci * 16462306a36Sopenharmony_ci ******************************************************************************/ 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_civoid 16762306a36Sopenharmony_ciacpi_rs_set_resource_length(acpi_rsdesc_size total_length, 16862306a36Sopenharmony_ci union aml_resource *aml) 16962306a36Sopenharmony_ci{ 17062306a36Sopenharmony_ci acpi_rs_length resource_length; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci ACPI_FUNCTION_ENTRY(); 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci /* Length is the total descriptor length minus the header length */ 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci resource_length = (acpi_rs_length) 17762306a36Sopenharmony_ci (total_length - acpi_ut_get_resource_header_length(aml)); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci /* Length is stored differently for large and small descriptors */ 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci /* Large descriptor -- bytes 1-2 contain the 16-bit length */ 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci ACPI_MOVE_16_TO_16(&aml->large_header.resource_length, 18662306a36Sopenharmony_ci &resource_length); 18762306a36Sopenharmony_ci } else { 18862306a36Sopenharmony_ci /* 18962306a36Sopenharmony_ci * Small descriptor -- bits 2:0 of byte 0 contain the length 19062306a36Sopenharmony_ci * Clear any existing length, preserving descriptor type bits 19162306a36Sopenharmony_ci */ 19262306a36Sopenharmony_ci aml->small_header.descriptor_type = (u8) 19362306a36Sopenharmony_ci ((aml->small_header.descriptor_type & 19462306a36Sopenharmony_ci ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK) 19562306a36Sopenharmony_ci | resource_length); 19662306a36Sopenharmony_ci } 19762306a36Sopenharmony_ci} 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci/******************************************************************************* 20062306a36Sopenharmony_ci * 20162306a36Sopenharmony_ci * FUNCTION: acpi_rs_set_resource_header 20262306a36Sopenharmony_ci * 20362306a36Sopenharmony_ci * PARAMETERS: descriptor_type - Byte to be inserted as the type 20462306a36Sopenharmony_ci * total_length - Length of the AML descriptor, including 20562306a36Sopenharmony_ci * the header and length fields. 20662306a36Sopenharmony_ci * aml - Pointer to the raw AML descriptor 20762306a36Sopenharmony_ci * 20862306a36Sopenharmony_ci * RETURN: None 20962306a36Sopenharmony_ci * 21062306a36Sopenharmony_ci * DESCRIPTION: Set the descriptor_type and resource_length fields of an AML 21162306a36Sopenharmony_ci * resource descriptor, both Large and Small descriptors are 21262306a36Sopenharmony_ci * supported automatically 21362306a36Sopenharmony_ci * 21462306a36Sopenharmony_ci ******************************************************************************/ 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_civoid 21762306a36Sopenharmony_ciacpi_rs_set_resource_header(u8 descriptor_type, 21862306a36Sopenharmony_ci acpi_rsdesc_size total_length, 21962306a36Sopenharmony_ci union aml_resource *aml) 22062306a36Sopenharmony_ci{ 22162306a36Sopenharmony_ci ACPI_FUNCTION_ENTRY(); 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci /* Set the Resource Type */ 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci aml->small_header.descriptor_type = descriptor_type; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci /* Set the Resource Length */ 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci acpi_rs_set_resource_length(total_length, aml); 23062306a36Sopenharmony_ci} 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci/******************************************************************************* 23362306a36Sopenharmony_ci * 23462306a36Sopenharmony_ci * FUNCTION: acpi_rs_strcpy 23562306a36Sopenharmony_ci * 23662306a36Sopenharmony_ci * PARAMETERS: destination - Pointer to the destination string 23762306a36Sopenharmony_ci * source - Pointer to the source string 23862306a36Sopenharmony_ci * 23962306a36Sopenharmony_ci * RETURN: String length, including NULL terminator 24062306a36Sopenharmony_ci * 24162306a36Sopenharmony_ci * DESCRIPTION: Local string copy that returns the string length, saving a 24262306a36Sopenharmony_ci * strcpy followed by a strlen. 24362306a36Sopenharmony_ci * 24462306a36Sopenharmony_ci ******************************************************************************/ 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_cistatic u16 acpi_rs_strcpy(char *destination, char *source) 24762306a36Sopenharmony_ci{ 24862306a36Sopenharmony_ci u16 i; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci ACPI_FUNCTION_ENTRY(); 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci for (i = 0; source[i]; i++) { 25362306a36Sopenharmony_ci destination[i] = source[i]; 25462306a36Sopenharmony_ci } 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci destination[i] = 0; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci /* Return string length including the NULL terminator */ 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci return ((u16) (i + 1)); 26162306a36Sopenharmony_ci} 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci/******************************************************************************* 26462306a36Sopenharmony_ci * 26562306a36Sopenharmony_ci * FUNCTION: acpi_rs_get_resource_source 26662306a36Sopenharmony_ci * 26762306a36Sopenharmony_ci * PARAMETERS: resource_length - Length field of the descriptor 26862306a36Sopenharmony_ci * minimum_length - Minimum length of the descriptor (minus 26962306a36Sopenharmony_ci * any optional fields) 27062306a36Sopenharmony_ci * resource_source - Where the resource_source is returned 27162306a36Sopenharmony_ci * aml - Pointer to the raw AML descriptor 27262306a36Sopenharmony_ci * string_ptr - (optional) where to store the actual 27362306a36Sopenharmony_ci * resource_source string 27462306a36Sopenharmony_ci * 27562306a36Sopenharmony_ci * RETURN: Length of the string plus NULL terminator, rounded up to native 27662306a36Sopenharmony_ci * word boundary 27762306a36Sopenharmony_ci * 27862306a36Sopenharmony_ci * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor 27962306a36Sopenharmony_ci * to an internal resource descriptor 28062306a36Sopenharmony_ci * 28162306a36Sopenharmony_ci ******************************************************************************/ 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ciacpi_rs_length 28462306a36Sopenharmony_ciacpi_rs_get_resource_source(acpi_rs_length resource_length, 28562306a36Sopenharmony_ci acpi_rs_length minimum_length, 28662306a36Sopenharmony_ci struct acpi_resource_source * resource_source, 28762306a36Sopenharmony_ci union aml_resource * aml, char *string_ptr) 28862306a36Sopenharmony_ci{ 28962306a36Sopenharmony_ci acpi_rsdesc_size total_length; 29062306a36Sopenharmony_ci u8 *aml_resource_source; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci ACPI_FUNCTION_ENTRY(); 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci total_length = 29562306a36Sopenharmony_ci resource_length + sizeof(struct aml_resource_large_header); 29662306a36Sopenharmony_ci aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length); 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci /* 29962306a36Sopenharmony_ci * resource_source is present if the length of the descriptor is longer 30062306a36Sopenharmony_ci * than the minimum length. 30162306a36Sopenharmony_ci * 30262306a36Sopenharmony_ci * Note: Some resource descriptors will have an additional null, so 30362306a36Sopenharmony_ci * we add 1 to the minimum length. 30462306a36Sopenharmony_ci */ 30562306a36Sopenharmony_ci if (total_length > (acpi_rsdesc_size)(minimum_length + 1)) { 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci /* Get the resource_source_index */ 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci resource_source->index = aml_resource_source[0]; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci resource_source->string_ptr = string_ptr; 31262306a36Sopenharmony_ci if (!string_ptr) { 31362306a36Sopenharmony_ci /* 31462306a36Sopenharmony_ci * String destination pointer is not specified; Set the String 31562306a36Sopenharmony_ci * pointer to the end of the current resource_source structure. 31662306a36Sopenharmony_ci */ 31762306a36Sopenharmony_ci resource_source->string_ptr = 31862306a36Sopenharmony_ci ACPI_ADD_PTR(char, resource_source, 31962306a36Sopenharmony_ci sizeof(struct acpi_resource_source)); 32062306a36Sopenharmony_ci } 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci /* 32362306a36Sopenharmony_ci * In order for the Resource length to be a multiple of the native 32462306a36Sopenharmony_ci * word, calculate the length of the string (+1 for NULL terminator) 32562306a36Sopenharmony_ci * and expand to the next word multiple. 32662306a36Sopenharmony_ci * 32762306a36Sopenharmony_ci * Zero the entire area of the buffer. 32862306a36Sopenharmony_ci */ 32962306a36Sopenharmony_ci total_length = 33062306a36Sopenharmony_ci (u32)strlen(ACPI_CAST_PTR(char, &aml_resource_source[1])) + 33162306a36Sopenharmony_ci 1; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci total_length = (u32)ACPI_ROUND_UP_TO_NATIVE_WORD(total_length); 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci memset(resource_source->string_ptr, 0, total_length); 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci /* Copy the resource_source string to the destination */ 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci resource_source->string_length = 34062306a36Sopenharmony_ci acpi_rs_strcpy(resource_source->string_ptr, 34162306a36Sopenharmony_ci ACPI_CAST_PTR(char, 34262306a36Sopenharmony_ci &aml_resource_source[1])); 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci return ((acpi_rs_length)total_length); 34562306a36Sopenharmony_ci } 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci /* resource_source is not present */ 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci resource_source->index = 0; 35062306a36Sopenharmony_ci resource_source->string_length = 0; 35162306a36Sopenharmony_ci resource_source->string_ptr = NULL; 35262306a36Sopenharmony_ci return (0); 35362306a36Sopenharmony_ci} 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci/******************************************************************************* 35662306a36Sopenharmony_ci * 35762306a36Sopenharmony_ci * FUNCTION: acpi_rs_set_resource_source 35862306a36Sopenharmony_ci * 35962306a36Sopenharmony_ci * PARAMETERS: aml - Pointer to the raw AML descriptor 36062306a36Sopenharmony_ci * minimum_length - Minimum length of the descriptor (minus 36162306a36Sopenharmony_ci * any optional fields) 36262306a36Sopenharmony_ci * resource_source - Internal resource_source 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci * 36562306a36Sopenharmony_ci * RETURN: Total length of the AML descriptor 36662306a36Sopenharmony_ci * 36762306a36Sopenharmony_ci * DESCRIPTION: Convert an optional resource_source from internal format to a 36862306a36Sopenharmony_ci * raw AML resource descriptor 36962306a36Sopenharmony_ci * 37062306a36Sopenharmony_ci ******************************************************************************/ 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ciacpi_rsdesc_size 37362306a36Sopenharmony_ciacpi_rs_set_resource_source(union aml_resource *aml, 37462306a36Sopenharmony_ci acpi_rs_length minimum_length, 37562306a36Sopenharmony_ci struct acpi_resource_source *resource_source) 37662306a36Sopenharmony_ci{ 37762306a36Sopenharmony_ci u8 *aml_resource_source; 37862306a36Sopenharmony_ci acpi_rsdesc_size descriptor_length; 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci ACPI_FUNCTION_ENTRY(); 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci descriptor_length = minimum_length; 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci /* Non-zero string length indicates presence of a resource_source */ 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci if (resource_source->string_length) { 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci /* Point to the end of the AML descriptor */ 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length); 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci /* Copy the resource_source_index */ 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci aml_resource_source[0] = (u8) resource_source->index; 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci /* Copy the resource_source string */ 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci strcpy(ACPI_CAST_PTR(char, &aml_resource_source[1]), 39962306a36Sopenharmony_ci resource_source->string_ptr); 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci /* 40262306a36Sopenharmony_ci * Add the length of the string (+ 1 for null terminator) to the 40362306a36Sopenharmony_ci * final descriptor length 40462306a36Sopenharmony_ci */ 40562306a36Sopenharmony_ci descriptor_length += ((acpi_rsdesc_size) 40662306a36Sopenharmony_ci resource_source->string_length + 1); 40762306a36Sopenharmony_ci } 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci /* Return the new total length of the AML descriptor */ 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci return (descriptor_length); 41262306a36Sopenharmony_ci} 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci/******************************************************************************* 41562306a36Sopenharmony_ci * 41662306a36Sopenharmony_ci * FUNCTION: acpi_rs_get_prt_method_data 41762306a36Sopenharmony_ci * 41862306a36Sopenharmony_ci * PARAMETERS: node - Device node 41962306a36Sopenharmony_ci * ret_buffer - Pointer to a buffer structure for the 42062306a36Sopenharmony_ci * results 42162306a36Sopenharmony_ci * 42262306a36Sopenharmony_ci * RETURN: Status 42362306a36Sopenharmony_ci * 42462306a36Sopenharmony_ci * DESCRIPTION: This function is called to get the _PRT value of an object 42562306a36Sopenharmony_ci * contained in an object specified by the handle passed in 42662306a36Sopenharmony_ci * 42762306a36Sopenharmony_ci * If the function fails an appropriate status will be returned 42862306a36Sopenharmony_ci * and the contents of the callers buffer is undefined. 42962306a36Sopenharmony_ci * 43062306a36Sopenharmony_ci ******************************************************************************/ 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ciacpi_status 43362306a36Sopenharmony_ciacpi_rs_get_prt_method_data(struct acpi_namespace_node *node, 43462306a36Sopenharmony_ci struct acpi_buffer *ret_buffer) 43562306a36Sopenharmony_ci{ 43662306a36Sopenharmony_ci union acpi_operand_object *obj_desc; 43762306a36Sopenharmony_ci acpi_status status; 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(rs_get_prt_method_data); 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci /* Parameters guaranteed valid by caller */ 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci /* Execute the method, no parameters */ 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ci status = 44662306a36Sopenharmony_ci acpi_ut_evaluate_object(node, METHOD_NAME__PRT, ACPI_BTYPE_PACKAGE, 44762306a36Sopenharmony_ci &obj_desc); 44862306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 44962306a36Sopenharmony_ci return_ACPI_STATUS(status); 45062306a36Sopenharmony_ci } 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci /* 45362306a36Sopenharmony_ci * Create a resource linked list from the byte stream buffer that comes 45462306a36Sopenharmony_ci * back from the _CRS method execution. 45562306a36Sopenharmony_ci */ 45662306a36Sopenharmony_ci status = acpi_rs_create_pci_routing_table(obj_desc, ret_buffer); 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci /* On exit, we must delete the object returned by evaluate_object */ 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci acpi_ut_remove_reference(obj_desc); 46162306a36Sopenharmony_ci return_ACPI_STATUS(status); 46262306a36Sopenharmony_ci} 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci/******************************************************************************* 46562306a36Sopenharmony_ci * 46662306a36Sopenharmony_ci * FUNCTION: acpi_rs_get_crs_method_data 46762306a36Sopenharmony_ci * 46862306a36Sopenharmony_ci * PARAMETERS: node - Device node 46962306a36Sopenharmony_ci * ret_buffer - Pointer to a buffer structure for the 47062306a36Sopenharmony_ci * results 47162306a36Sopenharmony_ci * 47262306a36Sopenharmony_ci * RETURN: Status 47362306a36Sopenharmony_ci * 47462306a36Sopenharmony_ci * DESCRIPTION: This function is called to get the _CRS value of an object 47562306a36Sopenharmony_ci * contained in an object specified by the handle passed in 47662306a36Sopenharmony_ci * 47762306a36Sopenharmony_ci * If the function fails an appropriate status will be returned 47862306a36Sopenharmony_ci * and the contents of the callers buffer is undefined. 47962306a36Sopenharmony_ci * 48062306a36Sopenharmony_ci ******************************************************************************/ 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_ciacpi_status 48362306a36Sopenharmony_ciacpi_rs_get_crs_method_data(struct acpi_namespace_node *node, 48462306a36Sopenharmony_ci struct acpi_buffer *ret_buffer) 48562306a36Sopenharmony_ci{ 48662306a36Sopenharmony_ci union acpi_operand_object *obj_desc; 48762306a36Sopenharmony_ci acpi_status status; 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(rs_get_crs_method_data); 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci /* Parameters guaranteed valid by caller */ 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_ci /* Execute the method, no parameters */ 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci status = 49662306a36Sopenharmony_ci acpi_ut_evaluate_object(node, METHOD_NAME__CRS, ACPI_BTYPE_BUFFER, 49762306a36Sopenharmony_ci &obj_desc); 49862306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 49962306a36Sopenharmony_ci return_ACPI_STATUS(status); 50062306a36Sopenharmony_ci } 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci /* 50362306a36Sopenharmony_ci * Make the call to create a resource linked list from the 50462306a36Sopenharmony_ci * byte stream buffer that comes back from the _CRS method 50562306a36Sopenharmony_ci * execution. 50662306a36Sopenharmony_ci */ 50762306a36Sopenharmony_ci status = acpi_rs_create_resource_list(obj_desc, ret_buffer); 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci /* On exit, we must delete the object returned by evaluateObject */ 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci acpi_ut_remove_reference(obj_desc); 51262306a36Sopenharmony_ci return_ACPI_STATUS(status); 51362306a36Sopenharmony_ci} 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci/******************************************************************************* 51662306a36Sopenharmony_ci * 51762306a36Sopenharmony_ci * FUNCTION: acpi_rs_get_prs_method_data 51862306a36Sopenharmony_ci * 51962306a36Sopenharmony_ci * PARAMETERS: node - Device node 52062306a36Sopenharmony_ci * ret_buffer - Pointer to a buffer structure for the 52162306a36Sopenharmony_ci * results 52262306a36Sopenharmony_ci * 52362306a36Sopenharmony_ci * RETURN: Status 52462306a36Sopenharmony_ci * 52562306a36Sopenharmony_ci * DESCRIPTION: This function is called to get the _PRS value of an object 52662306a36Sopenharmony_ci * contained in an object specified by the handle passed in 52762306a36Sopenharmony_ci * 52862306a36Sopenharmony_ci * If the function fails an appropriate status will be returned 52962306a36Sopenharmony_ci * and the contents of the callers buffer is undefined. 53062306a36Sopenharmony_ci * 53162306a36Sopenharmony_ci ******************************************************************************/ 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ciacpi_status 53462306a36Sopenharmony_ciacpi_rs_get_prs_method_data(struct acpi_namespace_node *node, 53562306a36Sopenharmony_ci struct acpi_buffer *ret_buffer) 53662306a36Sopenharmony_ci{ 53762306a36Sopenharmony_ci union acpi_operand_object *obj_desc; 53862306a36Sopenharmony_ci acpi_status status; 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(rs_get_prs_method_data); 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci /* Parameters guaranteed valid by caller */ 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci /* Execute the method, no parameters */ 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_ci status = 54762306a36Sopenharmony_ci acpi_ut_evaluate_object(node, METHOD_NAME__PRS, ACPI_BTYPE_BUFFER, 54862306a36Sopenharmony_ci &obj_desc); 54962306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 55062306a36Sopenharmony_ci return_ACPI_STATUS(status); 55162306a36Sopenharmony_ci } 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci /* 55462306a36Sopenharmony_ci * Make the call to create a resource linked list from the 55562306a36Sopenharmony_ci * byte stream buffer that comes back from the _CRS method 55662306a36Sopenharmony_ci * execution. 55762306a36Sopenharmony_ci */ 55862306a36Sopenharmony_ci status = acpi_rs_create_resource_list(obj_desc, ret_buffer); 55962306a36Sopenharmony_ci 56062306a36Sopenharmony_ci /* On exit, we must delete the object returned by evaluateObject */ 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci acpi_ut_remove_reference(obj_desc); 56362306a36Sopenharmony_ci return_ACPI_STATUS(status); 56462306a36Sopenharmony_ci} 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci/******************************************************************************* 56762306a36Sopenharmony_ci * 56862306a36Sopenharmony_ci * FUNCTION: acpi_rs_get_aei_method_data 56962306a36Sopenharmony_ci * 57062306a36Sopenharmony_ci * PARAMETERS: node - Device node 57162306a36Sopenharmony_ci * ret_buffer - Pointer to a buffer structure for the 57262306a36Sopenharmony_ci * results 57362306a36Sopenharmony_ci * 57462306a36Sopenharmony_ci * RETURN: Status 57562306a36Sopenharmony_ci * 57662306a36Sopenharmony_ci * DESCRIPTION: This function is called to get the _AEI value of an object 57762306a36Sopenharmony_ci * contained in an object specified by the handle passed in 57862306a36Sopenharmony_ci * 57962306a36Sopenharmony_ci * If the function fails an appropriate status will be returned 58062306a36Sopenharmony_ci * and the contents of the callers buffer is undefined. 58162306a36Sopenharmony_ci * 58262306a36Sopenharmony_ci ******************************************************************************/ 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ciacpi_status 58562306a36Sopenharmony_ciacpi_rs_get_aei_method_data(struct acpi_namespace_node *node, 58662306a36Sopenharmony_ci struct acpi_buffer *ret_buffer) 58762306a36Sopenharmony_ci{ 58862306a36Sopenharmony_ci union acpi_operand_object *obj_desc; 58962306a36Sopenharmony_ci acpi_status status; 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(rs_get_aei_method_data); 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci /* Parameters guaranteed valid by caller */ 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_ci /* Execute the method, no parameters */ 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci status = 59862306a36Sopenharmony_ci acpi_ut_evaluate_object(node, METHOD_NAME__AEI, ACPI_BTYPE_BUFFER, 59962306a36Sopenharmony_ci &obj_desc); 60062306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 60162306a36Sopenharmony_ci return_ACPI_STATUS(status); 60262306a36Sopenharmony_ci } 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ci /* 60562306a36Sopenharmony_ci * Make the call to create a resource linked list from the 60662306a36Sopenharmony_ci * byte stream buffer that comes back from the _CRS method 60762306a36Sopenharmony_ci * execution. 60862306a36Sopenharmony_ci */ 60962306a36Sopenharmony_ci status = acpi_rs_create_resource_list(obj_desc, ret_buffer); 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci /* On exit, we must delete the object returned by evaluateObject */ 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci acpi_ut_remove_reference(obj_desc); 61462306a36Sopenharmony_ci return_ACPI_STATUS(status); 61562306a36Sopenharmony_ci} 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_ci/******************************************************************************* 61862306a36Sopenharmony_ci * 61962306a36Sopenharmony_ci * FUNCTION: acpi_rs_get_method_data 62062306a36Sopenharmony_ci * 62162306a36Sopenharmony_ci * PARAMETERS: handle - Handle to the containing object 62262306a36Sopenharmony_ci * path - Path to method, relative to Handle 62362306a36Sopenharmony_ci * ret_buffer - Pointer to a buffer structure for the 62462306a36Sopenharmony_ci * results 62562306a36Sopenharmony_ci * 62662306a36Sopenharmony_ci * RETURN: Status 62762306a36Sopenharmony_ci * 62862306a36Sopenharmony_ci * DESCRIPTION: This function is called to get the _CRS or _PRS value of an 62962306a36Sopenharmony_ci * object contained in an object specified by the handle passed in 63062306a36Sopenharmony_ci * 63162306a36Sopenharmony_ci * If the function fails an appropriate status will be returned 63262306a36Sopenharmony_ci * and the contents of the callers buffer is undefined. 63362306a36Sopenharmony_ci * 63462306a36Sopenharmony_ci ******************************************************************************/ 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_ciacpi_status 63762306a36Sopenharmony_ciacpi_rs_get_method_data(acpi_handle handle, 63862306a36Sopenharmony_ci const char *path, struct acpi_buffer *ret_buffer) 63962306a36Sopenharmony_ci{ 64062306a36Sopenharmony_ci union acpi_operand_object *obj_desc; 64162306a36Sopenharmony_ci acpi_status status; 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(rs_get_method_data); 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci /* Parameters guaranteed valid by caller */ 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_ci /* Execute the method, no parameters */ 64862306a36Sopenharmony_ci 64962306a36Sopenharmony_ci status = 65062306a36Sopenharmony_ci acpi_ut_evaluate_object(ACPI_CAST_PTR 65162306a36Sopenharmony_ci (struct acpi_namespace_node, handle), path, 65262306a36Sopenharmony_ci ACPI_BTYPE_BUFFER, &obj_desc); 65362306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 65462306a36Sopenharmony_ci return_ACPI_STATUS(status); 65562306a36Sopenharmony_ci } 65662306a36Sopenharmony_ci 65762306a36Sopenharmony_ci /* 65862306a36Sopenharmony_ci * Make the call to create a resource linked list from the 65962306a36Sopenharmony_ci * byte stream buffer that comes back from the method 66062306a36Sopenharmony_ci * execution. 66162306a36Sopenharmony_ci */ 66262306a36Sopenharmony_ci status = acpi_rs_create_resource_list(obj_desc, ret_buffer); 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci /* On exit, we must delete the object returned by evaluate_object */ 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_ci acpi_ut_remove_reference(obj_desc); 66762306a36Sopenharmony_ci return_ACPI_STATUS(status); 66862306a36Sopenharmony_ci} 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_ci/******************************************************************************* 67162306a36Sopenharmony_ci * 67262306a36Sopenharmony_ci * FUNCTION: acpi_rs_set_srs_method_data 67362306a36Sopenharmony_ci * 67462306a36Sopenharmony_ci * PARAMETERS: node - Device node 67562306a36Sopenharmony_ci * in_buffer - Pointer to a buffer structure of the 67662306a36Sopenharmony_ci * parameter 67762306a36Sopenharmony_ci * 67862306a36Sopenharmony_ci * RETURN: Status 67962306a36Sopenharmony_ci * 68062306a36Sopenharmony_ci * DESCRIPTION: This function is called to set the _SRS of an object contained 68162306a36Sopenharmony_ci * in an object specified by the handle passed in 68262306a36Sopenharmony_ci * 68362306a36Sopenharmony_ci * If the function fails an appropriate status will be returned 68462306a36Sopenharmony_ci * and the contents of the callers buffer is undefined. 68562306a36Sopenharmony_ci * 68662306a36Sopenharmony_ci * Note: Parameters guaranteed valid by caller 68762306a36Sopenharmony_ci * 68862306a36Sopenharmony_ci ******************************************************************************/ 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ciacpi_status 69162306a36Sopenharmony_ciacpi_rs_set_srs_method_data(struct acpi_namespace_node *node, 69262306a36Sopenharmony_ci struct acpi_buffer *in_buffer) 69362306a36Sopenharmony_ci{ 69462306a36Sopenharmony_ci struct acpi_evaluate_info *info; 69562306a36Sopenharmony_ci union acpi_operand_object *args[2]; 69662306a36Sopenharmony_ci acpi_status status; 69762306a36Sopenharmony_ci struct acpi_buffer buffer; 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(rs_set_srs_method_data); 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_ci /* Allocate and initialize the evaluation information block */ 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); 70462306a36Sopenharmony_ci if (!info) { 70562306a36Sopenharmony_ci return_ACPI_STATUS(AE_NO_MEMORY); 70662306a36Sopenharmony_ci } 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci info->prefix_node = node; 70962306a36Sopenharmony_ci info->relative_pathname = METHOD_NAME__SRS; 71062306a36Sopenharmony_ci info->parameters = args; 71162306a36Sopenharmony_ci info->flags = ACPI_IGNORE_RETURN_VALUE; 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci /* 71462306a36Sopenharmony_ci * The in_buffer parameter will point to a linked list of 71562306a36Sopenharmony_ci * resource parameters. It needs to be formatted into a 71662306a36Sopenharmony_ci * byte stream to be sent in as an input parameter to _SRS 71762306a36Sopenharmony_ci * 71862306a36Sopenharmony_ci * Convert the linked list into a byte stream 71962306a36Sopenharmony_ci */ 72062306a36Sopenharmony_ci buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; 72162306a36Sopenharmony_ci status = acpi_rs_create_aml_resources(in_buffer, &buffer); 72262306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 72362306a36Sopenharmony_ci goto cleanup; 72462306a36Sopenharmony_ci } 72562306a36Sopenharmony_ci 72662306a36Sopenharmony_ci /* Create and initialize the method parameter object */ 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_ci args[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER); 72962306a36Sopenharmony_ci if (!args[0]) { 73062306a36Sopenharmony_ci /* 73162306a36Sopenharmony_ci * Must free the buffer allocated above (otherwise it is freed 73262306a36Sopenharmony_ci * later) 73362306a36Sopenharmony_ci */ 73462306a36Sopenharmony_ci ACPI_FREE(buffer.pointer); 73562306a36Sopenharmony_ci status = AE_NO_MEMORY; 73662306a36Sopenharmony_ci goto cleanup; 73762306a36Sopenharmony_ci } 73862306a36Sopenharmony_ci 73962306a36Sopenharmony_ci args[0]->buffer.length = (u32) buffer.length; 74062306a36Sopenharmony_ci args[0]->buffer.pointer = buffer.pointer; 74162306a36Sopenharmony_ci args[0]->common.flags = AOPOBJ_DATA_VALID; 74262306a36Sopenharmony_ci args[1] = NULL; 74362306a36Sopenharmony_ci 74462306a36Sopenharmony_ci /* Execute the method, no return value is expected */ 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_ci status = acpi_ns_evaluate(info); 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ci /* Clean up and return the status from acpi_ns_evaluate */ 74962306a36Sopenharmony_ci 75062306a36Sopenharmony_ci acpi_ut_remove_reference(args[0]); 75162306a36Sopenharmony_ci 75262306a36Sopenharmony_cicleanup: 75362306a36Sopenharmony_ci ACPI_FREE(info); 75462306a36Sopenharmony_ci return_ACPI_STATUS(status); 75562306a36Sopenharmony_ci} 756