// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/******************************************************************************
*
* Module Name : nsconvert - Object conversions for objects returned by
* predefined methods
*
* Copyright ( C ) 2000 - 2025 , Intel Corp .
*
*****************************************************************************/
#include <acpi/acpi.h>
#include "accommon.h"
#include "acnamesp.h"
#include "acinterp.h"
#include "acpredef.h"
#include "amlresrc.h"
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME("nsconvert" )
/*******************************************************************************
*
* FUNCTION : acpi_ns_convert_to_integer
*
* PARAMETERS : original_object - Object to be converted
* return_object - Where the new converted object is returned
*
* RETURN : Status . AE_OK if conversion was successful .
*
* DESCRIPTION : Attempt to convert a String / Buffer object to an Integer .
*
******************************************************************************/
acpi_status
acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
union acpi_operand_object **return_object)
{
union acpi_operand_object *new_object;
acpi_status status;
u64 value = 0 ;
u32 i;
switch (original_object->common.type) {
case ACPI_TYPE_STRING:
/* String-to-Integer conversion */
status =
acpi_ut_strtoul64(original_object->string.pointer, &value);
if (ACPI_FAILURE(status)) {
return (status);
}
break ;
case ACPI_TYPE_BUFFER:
/* Buffer-to-Integer conversion. Max buffer size is 64 bits. */
if (original_object->buffer.length > 8 ) {
return (AE_AML_OPERAND_TYPE);
}
/* Extract each buffer byte to create the integer */
for (i = 0 ; i < original_object->buffer.length; i++) {
value |= ((u64)
original_object->buffer.pointer[i] << (i *
8 ));
}
break ;
default :
return (AE_AML_OPERAND_TYPE);
}
new_object = acpi_ut_create_integer_object(value);
if (!new_object) {
return (AE_NO_MEMORY);
}
*return_object = new_object;
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION : acpi_ns_convert_to_string
*
* PARAMETERS : original_object - Object to be converted
* return_object - Where the new converted object is returned
*
* RETURN : Status . AE_OK if conversion was successful .
*
* DESCRIPTION : Attempt to convert a Integer / Buffer object to a String .
*
******************************************************************************/
acpi_status
acpi_ns_convert_to_string(union acpi_operand_object *original_object,
union acpi_operand_object **return_object)
{
union acpi_operand_object *new_object;
acpi_size length;
acpi_status status;
switch (original_object->common.type) {
case ACPI_TYPE_INTEGER:
/*
* Integer - to - String conversion . Commonly , convert
* an integer of value 0 to a NULL string . The last element of
* _ BIF and _ BIX packages occasionally need this fix .
*/
if (original_object->integer.value == 0 ) {
/* Allocate a new NULL string object */
new_object = acpi_ut_create_string_object(0 );
if (!new_object) {
return (AE_NO_MEMORY);
}
} else {
status = acpi_ex_convert_to_string(original_object,
&new_object,
ACPI_IMPLICIT_CONVERT_HEX);
if (ACPI_FAILURE(status)) {
return (status);
}
}
break ;
case ACPI_TYPE_BUFFER:
/*
* Buffer - to - String conversion . Use a to_string
* conversion , no transform performed on the buffer data . The best
* example of this is the _ BIF method , where the string data from
* the battery is often ( incorrectly ) returned as buffer object ( s ) .
*/
length = 0 ;
while ((length < original_object->buffer.length) &&
(original_object->buffer.pointer[length])) {
length++;
}
/* Allocate a new string object */
new_object = acpi_ut_create_string_object(length);
if (!new_object) {
return (AE_NO_MEMORY);
}
/*
* Copy the raw buffer data with no transform . String is already NULL
* terminated at Length + 1 .
*/
memcpy(new_object->string.pointer,
original_object->buffer.pointer, length);
break ;
default :
return (AE_AML_OPERAND_TYPE);
}
*return_object = new_object;
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION : acpi_ns_convert_to_buffer
*
* PARAMETERS : original_object - Object to be converted
* return_object - Where the new converted object is returned
*
* RETURN : Status . AE_OK if conversion was successful .
*
* DESCRIPTION : Attempt to convert a Integer / String / Package object to a Buffer .
*
******************************************************************************/
acpi_status
acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
union acpi_operand_object **return_object)
{
union acpi_operand_object *new_object;
acpi_status status;
union acpi_operand_object **elements;
u32 *dword_buffer;
u32 count;
u32 i;
switch (original_object->common.type) {
case ACPI_TYPE_INTEGER:
/*
* Integer - to - Buffer conversion .
* Convert the Integer to a packed - byte buffer . _ MAT and other
* objects need this sometimes , if a read has been performed on a
* Field object that is less than or equal to the global integer
* size ( 32 or 64 bits ) .
*/
status =
acpi_ex_convert_to_buffer(original_object, &new_object);
if (ACPI_FAILURE(status)) {
return (status);
}
break ;
case ACPI_TYPE_STRING:
/* String-to-Buffer conversion. Simple data copy */
new_object = acpi_ut_create_buffer_object
(original_object->string.length);
if (!new_object) {
return (AE_NO_MEMORY);
}
memcpy(new_object->buffer.pointer,
original_object->string.pointer,
original_object->string.length);
break ;
case ACPI_TYPE_PACKAGE:
/*
* This case is often seen for predefined names that must return a
* Buffer object with multiple DWORD integers within . For example ,
* _ FDE and _ GTM . The Package can be converted to a Buffer .
*/
/* All elements of the Package must be integers */
elements = original_object->package.elements;
count = original_object->package.count;
for (i = 0 ; i < count; i++) {
if ((!*elements) ||
((*elements)->common.type != ACPI_TYPE_INTEGER)) {
return (AE_AML_OPERAND_TYPE);
}
elements++;
}
/* Create the new buffer object to replace the Package */
new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count));
if (!new_object) {
return (AE_NO_MEMORY);
}
/* Copy the package elements (integers) to the buffer as DWORDs */
elements = original_object->package.elements;
dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer);
for (i = 0 ; i < count; i++) {
*dword_buffer = (u32)(*elements)->integer.value;
dword_buffer++;
elements++;
}
break ;
default :
return (AE_AML_OPERAND_TYPE);
}
*return_object = new_object;
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION : acpi_ns_convert_to_unicode
*
* PARAMETERS : scope - Namespace node for the method / object
* original_object - ASCII String Object to be converted
* return_object - Where the new converted object is returned
*
* RETURN : Status . AE_OK if conversion was successful .
*
* DESCRIPTION : Attempt to convert a String object to a Unicode string Buffer .
*
******************************************************************************/
acpi_status
acpi_ns_convert_to_unicode(struct acpi_namespace_node *scope,
union acpi_operand_object *original_object,
union acpi_operand_object **return_object)
{
union acpi_operand_object *new_object;
char *ascii_string;
u16 *unicode_buffer;
u32 unicode_length;
u32 i;
if (!original_object) {
return (AE_OK);
}
/* If a Buffer was returned, it must be at least two bytes long */
if (original_object->common.type == ACPI_TYPE_BUFFER) {
if (original_object->buffer.length < 2 ) {
return (AE_AML_OPERAND_VALUE);
}
*return_object = NULL;
return (AE_OK);
}
/*
* The original object is an ASCII string . Convert this string to
* a unicode buffer .
*/
ascii_string = original_object->string.pointer;
unicode_length = (original_object->string.length * 2 ) + 2 ;
/* Create a new buffer object for the Unicode data */
new_object = acpi_ut_create_buffer_object(unicode_length);
if (!new_object) {
return (AE_NO_MEMORY);
}
unicode_buffer = ACPI_CAST_PTR(u16, new_object->buffer.pointer);
/* Convert ASCII to Unicode */
for (i = 0 ; i < original_object->string.length; i++) {
unicode_buffer[i] = (u16)ascii_string[i];
}
*return_object = new_object;
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION : acpi_ns_convert_to_resource
*
* PARAMETERS : scope - Namespace node for the method / object
* original_object - Object to be converted
* return_object - Where the new converted object is returned
*
* RETURN : Status . AE_OK if conversion was successful
*
* DESCRIPTION : Attempt to convert a Integer object to a resource_template
* Buffer .
*
******************************************************************************/
acpi_status
acpi_ns_convert_to_resource(struct acpi_namespace_node *scope,
union acpi_operand_object *original_object,
union acpi_operand_object **return_object)
{
union acpi_operand_object *new_object;
u8 *buffer;
/*
* We can fix the following cases for an expected resource template :
* 1 . No return value ( interpreter slack mode is disabled )
* 2 . A " Return ( Zero ) " statement
* 3 . A " Return empty buffer " statement
*
* We will return a buffer containing a single end_tag
* resource descriptor .
*/
if (original_object) {
switch (original_object->common.type) {
case ACPI_TYPE_INTEGER:
/* We can only repair an Integer==0 */
if (original_object->integer.value) {
return (AE_AML_OPERAND_TYPE);
}
break ;
case ACPI_TYPE_BUFFER:
if (original_object->buffer.length) {
/* Additional checks can be added in the future */
*return_object = NULL;
return (AE_OK);
}
break ;
case ACPI_TYPE_STRING:
default :
return (AE_AML_OPERAND_TYPE);
}
}
/* Create the new buffer object for the resource descriptor */
new_object = acpi_ut_create_buffer_object(2 );
if (!new_object) {
return (AE_NO_MEMORY);
}
buffer = ACPI_CAST_PTR(u8, new_object->buffer.pointer);
/* Initialize the Buffer with a single end_tag descriptor */
buffer[0 ] = (ACPI_RESOURCE_NAME_END_TAG | ASL_RDESC_END_TAG_SIZE);
buffer[1 ] = 0 x00;
*return_object = new_object;
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION : acpi_ns_convert_to_reference
*
* PARAMETERS : scope - Namespace node for the method / object
* original_object - Object to be converted
* return_object - Where the new converted object is returned
*
* RETURN : Status . AE_OK if conversion was successful
*
* DESCRIPTION : Attempt to convert a Integer object to a object_reference .
* Buffer .
*
******************************************************************************/
acpi_status
acpi_ns_convert_to_reference(struct acpi_namespace_node *scope,
union acpi_operand_object *original_object,
union acpi_operand_object **return_object)
{
union acpi_operand_object *new_object = NULL;
acpi_status status;
struct acpi_namespace_node *node;
union acpi_generic_state scope_info;
char *name;
ACPI_FUNCTION_NAME(ns_convert_to_reference);
/* Convert path into internal presentation */
status =
acpi_ns_internalize_name(original_object->string.pointer, &name);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Find the namespace node */
scope_info.scope.node =
ACPI_CAST_PTR(struct acpi_namespace_node, scope);
status =
acpi_ns_lookup(&scope_info, name, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
NULL, &node);
if (ACPI_FAILURE(status)) {
/* Check if we are resolving a named reference within a package */
ACPI_ERROR_NAMESPACE(&scope_info,
original_object->string.pointer, status);
goto error_exit;
}
/* Create and init a new internal ACPI object */
new_object = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE);
if (!new_object) {
status = AE_NO_MEMORY;
goto error_exit;
}
new_object->reference.node = node;
new_object->reference.object = node->object;
new_object->reference.class = ACPI_REFCLASS_NAME;
/*
* Increase reference of the object if needed ( the object is likely a
* null for device nodes ) .
*/
acpi_ut_add_reference(node->object);
error_exit:
ACPI_FREE(name);
*return_object = new_object;
return (status);
}
Messung V0.5 in Prozent C=93 H=88 G=90
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-10-11)
¤
*© Formatika GbR, Deutschland