Skip to content

Commit

Permalink
Utility: Add support to resolve external object references
Browse files Browse the repository at this point in the history
This patch adds support to resolve internal NameString objects into
external ObjectReference so that when ACPICA is tuned to be compliant to
the other ACPI implementations, external users (OSPM drivers) won't be
affected. Reported by Peter Wu, fixed by Robert Moore, Lv Zheng.

Link: https://bugs.acpica.org/show_bug.cgi?id=1333
Link: Bumblebee-Project/bbswitch#142
Reported-by: Peter Wu <peter@lekensteyn.nl>
Signed-off-by: Robert Moore <robert.moore@intel.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
  • Loading branch information
acpibob authored and Lv Zheng committed Jun 14, 2017
1 parent 1c1765b commit dcb8548
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 9 deletions.
3 changes: 2 additions & 1 deletion source/components/executer/exdump.c
Expand Up @@ -207,12 +207,13 @@ static ACPI_EXDUMP_INFO AcpiExDumpInteger[2] =
{ACPI_EXD_UINT64, ACPI_EXD_OFFSET (Integer.Value), "Value"}
};

static ACPI_EXDUMP_INFO AcpiExDumpString[5] =
static ACPI_EXDUMP_INFO AcpiExDumpString[6] =
{
{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE (AcpiExDumpString), NULL},
{ACPI_EXD_UINT32, ACPI_EXD_OFFSET (String.Length), "Length"},
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET (String.Pointer), "Pointer"},
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET (String.ScopeNode), "Scope Node"},
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET (String.Node), "Reference Node"},
{ACPI_EXD_STRING, 0, NULL}
};

Expand Down
2 changes: 2 additions & 0 deletions source/components/namespace/nsxfeval.c
Expand Up @@ -588,8 +588,10 @@ AcpiEvaluateObject (
{
/* We have enough space for the object, build it */

AcpiExEnterInterpreter ();
Status = AcpiUtCopyIobjectToEobject (
Info->ReturnObject, ReturnBuffer);
AcpiExExitInterpreter ();
}
}

Expand Down
176 changes: 168 additions & 8 deletions source/components/utilities/utcopy.c
Expand Up @@ -152,6 +152,7 @@
#include "acpi.h"
#include "accommon.h"
#include "acnamesp.h"
#include "acinterp.h"


#define _COMPONENT ACPI_UTILITIES
Expand All @@ -166,6 +167,11 @@ AcpiUtCopyIsimpleToEsimple (
UINT8 *DataSpace,
ACPI_SIZE *BufferSpaceUsed);

static ACPI_STATUS
AcpiUtResolveReferenceString (
ACPI_OPERAND_OBJECT **StringObject,
ACPI_OBJECT *ExternalObject);

static ACPI_STATUS
AcpiUtCopyIelementToIelement (
UINT8 ObjectType,
Expand Down Expand Up @@ -244,8 +250,8 @@ AcpiUtCopyIsimpleToEsimple (
*BufferSpaceUsed = 0;

/*
* Check for NULL object case (could be an uninitialized
* package element)
* Check for NULL internal object case (could be an uninitialized package
* element)
*/
if (!InternalObject)
{
Expand All @@ -258,16 +264,41 @@ AcpiUtCopyIsimpleToEsimple (

/*
* In general, the external object will be the same type as
* the internal object
* the internal object. However, only a limited number of external
* types are supported
*/
ExternalObject->Type = InternalObject->Common.Type;

/* However, only a limited number of external types are supported */
/* String/Namestring is a named reference */

if ((InternalObject->Common.Type == ACPI_TYPE_STRING) &&
(InternalObject->Common.Flags & AOPOBJ_NAMESTRING))
{
/*
* References within packages are stored internally as String
* objects for compatibility with other ACPI implementations.
* These references are resolved only when an external version
* of the package is requested (from ACPICA external interfaces)
* and created here. (04/2017).
*/
Status = AcpiUtResolveReferenceString (&InternalObject,
ExternalObject);
if (Status == AE_CTRL_TERMINATE)
{
return_ACPI_STATUS (AE_OK);
}
else if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
}

switch (InternalObject->Common.Type)
{
case ACPI_TYPE_STRING:

/* Normal string object */

ExternalObject->String.Pointer = (char *) DataSpace;
ExternalObject->String.Length = InternalObject->String.Length;
*BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
Expand Down Expand Up @@ -297,7 +328,7 @@ AcpiUtCopyIsimpleToEsimple (

case ACPI_TYPE_LOCAL_REFERENCE:

/* This is an object reference. */
/* This is an object reference */

switch (InternalObject->Reference.Class)
{
Expand Down Expand Up @@ -340,9 +371,9 @@ AcpiUtCopyIsimpleToEsimple (
break;

default:
/*
* There is no corresponding external object type
*/

/* There is no corresponding external object type */

ACPI_ERROR ((AE_INFO,
"Unsupported object type, cannot convert to external object: %s",
AcpiUtGetTypeName (InternalObject->Common.Type)));
Expand All @@ -354,6 +385,135 @@ AcpiUtCopyIsimpleToEsimple (
}


/*******************************************************************************
*
* FUNCTION: AcpiUtResolveReferenceString
*
* PARAMETERS: InternalStringPtr - Pointer to internal String object to be
* resolved
* ExternalObject - Where to return the resolved object
*
* RETURN: Status, AE_CTRL_TERMINATE means resolution was completed here
* and no further processing is necessary.
*
* DESCRIPTION: Resolve a named reference that is contained in a string object.
* Objects that are "data" types (integers, etc.) are resolved
* to actual values here. Other types are resolved to a
* namespace node.
*
******************************************************************************/

static ACPI_STATUS
AcpiUtResolveReferenceString (
ACPI_OPERAND_OBJECT **InternalStringPtr,
ACPI_OBJECT *ExternalObject)
{
ACPI_OPERAND_OBJECT *StringObject = *InternalStringPtr;
ACPI_OPERAND_OBJECT *ReturnObject;
ACPI_OBJECT_TYPE ResolvedType;
ACPI_STATUS Status;


ACPI_FUNCTION_TRACE (UtResolveReferenceString);


/* Only need to lookup the string once, then save the node */

if (!StringObject->String.Node)
{
/*
* The reference has not been resolved to a namespace node yet.
* Lookup the string/name in the namespace.
*/
Status = AcpiNsGetNodeUnlocked (
StringObject->String.ScopeNode,
StringObject->String.Pointer, ACPI_NS_SEARCH_PARENT,
&StringObject->String.Node);

if (ACPI_FAILURE (Status))
{
/*
* We didn't find the target and we are populating elements
* of a package - ignore this error. Some ASL code
* contains dangling invalid references in packages and
* expects that no exception will be issued. Leave the
* element as a null element. It cannot be used, but it
* can be overwritten by subsequent ASL code - this is
* typically the case.
*/
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
"Could not locate object in namespace - %s",
StringObject->String.Pointer));
}
}

ReturnObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT,
StringObject->String.Node);
if (!StringObject->String.Node)
{
ResolvedType = ACPI_TYPE_ANY;
}
else
{
/* This is where the object resolution happens */

Status = AcpiExResolveNodeToValue (ACPI_CAST_INDIRECT_PTR (
ACPI_NAMESPACE_NODE, &ReturnObject), NULL);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
ResolvedType = ReturnObject->Common.Type;
}

switch (ResolvedType)
{
case ACPI_TYPE_INTEGER:
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:

/*
* Fully resolved values should be simple objects:
* integers/strings/buffers
*/
ExternalObject->Type = ReturnObject->Common.Type;
*InternalStringPtr = ReturnObject;
return_ACPI_STATUS (AE_OK);

case ACPI_TYPE_ANY:
case ACPI_TYPE_DEVICE:
case ACPI_TYPE_EVENT:
case ACPI_TYPE_METHOD:
case ACPI_TYPE_MUTEX:
case ACPI_TYPE_REGION:
case ACPI_TYPE_POWER:
case ACPI_TYPE_PROCESSOR:
case ACPI_TYPE_THERMAL:

/*
* All other objects become reference objects -- in actuality this
* means a namespace node.
*/
ExternalObject->Type = ACPI_TYPE_LOCAL_REFERENCE;
ExternalObject->Reference.Handle =
ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ReturnObject);
ExternalObject->Reference.ActualType = ResolvedType;
return_ACPI_STATUS (AE_CTRL_TERMINATE);

default:

break;
}

/* Shouldn't reach here */

ACPI_ERROR ((AE_INFO,
"Unsupported external object type - %d",
ResolvedType));
return_ACPI_STATUS (AE_SUPPORT);
}


/*******************************************************************************
*
* FUNCTION: AcpiUtCopyIelementToEelement
Expand Down
2 changes: 2 additions & 0 deletions source/include/acobject.h
Expand Up @@ -238,6 +238,7 @@ typedef struct acpi_object_integer
* Fields common to both Strings and Buffers
*/
#define ACPI_COMMON_BUFFER_INFO(_Type) \
UINT8 Fill[3]; /* Prevent warning on some compilers */ \
_Type *Pointer; \
UINT32 Length;

Expand All @@ -249,6 +250,7 @@ typedef struct acpi_object_string
ACPI_OBJECT_COMMON_HEADER
ACPI_COMMON_BUFFER_INFO (char) /* String in AML stream or allocated string */
ACPI_NAMESPACE_NODE *ScopeNode; /* Scope node, may not be needed */
ACPI_NAMESPACE_NODE *Node; /* Used when the string is actually a named reference */

} ACPI_OBJECT_STRING;

Expand Down

0 comments on commit dcb8548

Please sign in to comment.