Add support to externally execute _OSI method.

The current implemenation of _OSI within ACPICA only allows other
control methods to execute _OSI. This change allows the host OS
to execute _OSI via the AcpiEvaluateObject interface. _OSI is a
special method -- it does not exist in the AML code, it is
implemented within ACPICA.
This commit is contained in:
Robert Moore 2008-10-23 10:28:17 -07:00
parent f5e2380443
commit 28da268b28
5 changed files with 110 additions and 3 deletions

View File

@ -520,6 +520,10 @@ AcpiDsCallControlMethod (
if (ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY)
{
Status = ObjDesc->Method.Implementation (NextWalkState);
if (Status == AE_OK)
{
Status = AE_CTRL_TERMINATE;
}
}
return_ACPI_STATUS (Status);

View File

@ -540,6 +540,10 @@ AcpiPsParseAml (
WalkState, WalkState->ParserState.Aml,
WalkState->ParserState.AmlSize));
if (!WalkState->ParserState.Aml)
{
return_ACPI_STATUS (AE_NULL_OBJECT);
}
/* Create and initialize a new thread state */

View File

@ -120,6 +120,7 @@
#include "acparser.h"
#include "acdispat.h"
#include "acinterp.h"
#include "amlcode.h"
#define _COMPONENT ACPI_PARSER
@ -393,6 +394,22 @@ AcpiPsExecuteMethod (
goto Cleanup;
}
/* Invoke an internal method if necessary */
if (Info->ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY)
{
Status = Info->ObjDesc->Method.Implementation (WalkState);
Info->ReturnObject = WalkState->ReturnDesc;
/* Cleanup states */
AcpiDsScopeStackClear (WalkState);
AcpiPsCleanupScope (&WalkState->ParserState);
AcpiDsTerminateControlMethod (WalkState->MethodDesc, WalkState);
AcpiDsDeleteWalkState (WalkState);
goto Cleanup;
}
/* Parse the AML */
Status = AcpiPsParseAml (WalkState);

View File

@ -220,7 +220,7 @@ AcpiUtOsiImplementation (
{
/* The interface is supported */
return_ACPI_STATUS (AE_CTRL_TERMINATE);
return_ACPI_STATUS (AE_OK);
}
}
@ -234,13 +234,13 @@ AcpiUtOsiImplementation (
{
/* The interface is supported */
return_ACPI_STATUS (AE_CTRL_TERMINATE);
return_ACPI_STATUS (AE_OK);
}
/* The interface is not supported */
ReturnDesc->Integer.Value = 0;
return_ACPI_STATUS (AE_CTRL_TERMINATE);
return_ACPI_STATUS (AE_OK);
}

View File

@ -1319,6 +1319,86 @@ AeGetDevices (
}
/******************************************************************************
*
* FUNCTION: ExecuteOSI
*
* PARAMETERS: OsiString - String passed to _OSI method
* ExpectedResult - 0 (FALSE) or 0xFFFFFFFF (TRUE)
*
* RETURN: Status
*
* DESCRIPTION: Execute the internally implemented (in ACPICA) _OSI method.
*
*****************************************************************************/
ACPI_STATUS
ExecuteOSI (
char *OsiString,
UINT32 ExpectedResult)
{
ACPI_STATUS Status;
ACPI_OBJECT_LIST ArgList;
ACPI_OBJECT Arg[1];
ACPI_BUFFER ReturnValue;
ACPI_OBJECT *Obj;
/* Setup input argument */
ArgList.Count = 1;
ArgList.Pointer = Arg;
Arg[0].Type = ACPI_TYPE_STRING;
Arg[0].String.Pointer = OsiString;
Arg[0].String.Length = strlen (Arg[0].String.Pointer);
/* Ask ACPICA to allocate space for the return object */
ReturnValue.Length = ACPI_ALLOCATE_BUFFER;
Status = AcpiEvaluateObject (NULL, "\\_OSI", &ArgList, &ReturnValue);
if (ACPI_FAILURE (Status))
{
AcpiOsPrintf ("Could not execute _OSI method, %s\n",
AcpiFormatException (Status));
return (Status);
}
if (ReturnValue.Length < sizeof (ACPI_OBJECT))
{
AcpiOsPrintf ("Return value from _OSI method too small, %.8X\n",
ReturnValue.Length);
return (AE_ERROR);
}
Obj = ReturnValue.Pointer;
if (Obj->Type != ACPI_TYPE_INTEGER)
{
AcpiOsPrintf ("Invalid return type from _OSI method, %.2X\n", Obj->Type);
return (AE_ERROR);
}
if (Obj->Integer.Value != ExpectedResult)
{
AcpiOsPrintf ("Invalid return value from _OSI, expected %.8X found %.8X\n",
ExpectedResult, (UINT32) Obj->Integer.Value);
return (AE_ERROR);
}
return (AE_OK);
}
/******************************************************************************
*
* FUNCTION: AeMiscellaneousTests
*
* DESCRIPTION: Various ACPICA validation tests.
*
*****************************************************************************/
void
AeMiscellaneousTests (
void)
@ -1337,6 +1417,8 @@ AeMiscellaneousTests (
AeTestBufferArgument();
AeTestPackageArgument ();
ExecuteOSI ("Windows 2001", 0xFFFFFFFF);
ExecuteOSI ("MichiganTerminalSystem", 0);
ReturnBuf.Length = 32;