diff options
Diffstat (limited to 'sys/contrib/dev/acpica/components/debugger/dbtest.c')
-rw-r--r-- | sys/contrib/dev/acpica/components/debugger/dbtest.c | 1138 |
1 files changed, 1138 insertions, 0 deletions
diff --git a/sys/contrib/dev/acpica/components/debugger/dbtest.c b/sys/contrib/dev/acpica/components/debugger/dbtest.c new file mode 100644 index 0000000..fe7a33f --- /dev/null +++ b/sys/contrib/dev/acpica/components/debugger/dbtest.c @@ -0,0 +1,1138 @@ +/******************************************************************************* + * + * Module Name: dbtest - Various debug-related tests + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2014, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include <contrib/dev/acpica/include/acpi.h> +#include <contrib/dev/acpica/include/accommon.h> +#include <contrib/dev/acpica/include/acdebug.h> +#include <contrib/dev/acpica/include/acnamesp.h> +#include <contrib/dev/acpica/include/acpredef.h> + +#ifdef ACPI_DEBUGGER + +#define _COMPONENT ACPI_CA_DEBUGGER + ACPI_MODULE_NAME ("dbtest") + + +/* Local prototypes */ + +static void +AcpiDbTestAllObjects ( + void); + +static ACPI_STATUS +AcpiDbTestOneObject ( + ACPI_HANDLE ObjHandle, + UINT32 NestingLevel, + void *Context, + void **ReturnValue); + +static ACPI_STATUS +AcpiDbTestIntegerType ( + ACPI_NAMESPACE_NODE *Node, + UINT32 BitLength); + +static ACPI_STATUS +AcpiDbTestBufferType ( + ACPI_NAMESPACE_NODE *Node, + UINT32 BitLength); + +static ACPI_STATUS +AcpiDbTestStringType ( + ACPI_NAMESPACE_NODE *Node, + UINT32 ByteLength); + +static ACPI_STATUS +AcpiDbReadFromObject ( + ACPI_NAMESPACE_NODE *Node, + ACPI_OBJECT_TYPE ExpectedType, + ACPI_OBJECT **Value); + +static ACPI_STATUS +AcpiDbWriteToObject ( + ACPI_NAMESPACE_NODE *Node, + ACPI_OBJECT *Value); + +static void +AcpiDbEvaluateAllPredefinedNames ( + char *CountArg); + +static ACPI_STATUS +AcpiDbEvaluateOnePredefinedName ( + ACPI_HANDLE ObjHandle, + UINT32 NestingLevel, + void *Context, + void **ReturnValue); + +/* + * Test subcommands + */ +static ACPI_DB_ARGUMENT_INFO AcpiDbTestTypes [] = +{ + {"OBJECTS"}, + {"PREDEFINED"}, + {NULL} /* Must be null terminated */ +}; + +#define CMD_TEST_OBJECTS 0 +#define CMD_TEST_PREDEFINED 1 + +#define BUFFER_FILL_VALUE 0xFF + +/* + * Support for the special debugger read/write control methods. + * These methods are installed into the current namespace and are + * used to read and write the various namespace objects. The point + * is to force the AML interpreter do all of the work. + */ +#define ACPI_DB_READ_METHOD "\\_T98" +#define ACPI_DB_WRITE_METHOD "\\_T99" + +static ACPI_HANDLE ReadHandle = NULL; +static ACPI_HANDLE WriteHandle = NULL; + +/* ASL Definitions of the debugger read/write control methods */ + +#if 0 +DefinitionBlock ("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001) +{ + Method (_T98, 1, NotSerialized) /* Read */ + { + Return (DeRefOf (Arg0)) + } +} +DefinitionBlock ("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001) +{ + Method (_T99, 2, NotSerialized) /* Write */ + { + Store (Arg1, Arg0) + } +} +#endif + +static unsigned char ReadMethodCode[] = +{ + 0x53,0x53,0x44,0x54,0x2E,0x00,0x00,0x00, /* 00000000 "SSDT...." */ + 0x02,0xC9,0x49,0x6E,0x74,0x65,0x6C,0x00, /* 00000008 "..Intel." */ + 0x44,0x45,0x42,0x55,0x47,0x00,0x00,0x00, /* 00000010 "DEBUG..." */ + 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ + 0x18,0x12,0x13,0x20,0x14,0x09,0x5F,0x54, /* 00000020 "... .._T" */ + 0x39,0x38,0x01,0xA4,0x83,0x68 /* 00000028 "98...h" */ +}; + +static unsigned char WriteMethodCode[] = +{ + 0x53,0x53,0x44,0x54,0x2E,0x00,0x00,0x00, /* 00000000 "SSDT...." */ + 0x02,0x15,0x49,0x6E,0x74,0x65,0x6C,0x00, /* 00000008 "..Intel." */ + 0x44,0x45,0x42,0x55,0x47,0x00,0x00,0x00, /* 00000010 "DEBUG..." */ + 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ + 0x18,0x12,0x13,0x20,0x14,0x09,0x5F,0x54, /* 00000020 "... .._T" */ + 0x39,0x39,0x02,0x70,0x69,0x68 /* 00000028 "99.pih" */ +}; + + +/******************************************************************************* + * + * FUNCTION: AcpiDbExecuteTest + * + * PARAMETERS: TypeArg - Subcommand + * + * RETURN: None + * + * DESCRIPTION: Execute various debug tests. + * + * Note: Code is prepared for future expansion of the TEST command. + * + ******************************************************************************/ + +void +AcpiDbExecuteTest ( + char *TypeArg) +{ + UINT32 Temp; + + + AcpiUtStrupr (TypeArg); + Temp = AcpiDbMatchArgument (TypeArg, AcpiDbTestTypes); + if (Temp == ACPI_TYPE_NOT_FOUND) + { + AcpiOsPrintf ("Invalid or unsupported argument\n"); + return; + } + + switch (Temp) + { + case CMD_TEST_OBJECTS: + + AcpiDbTestAllObjects (); + break; + + case CMD_TEST_PREDEFINED: + + AcpiDbEvaluateAllPredefinedNames (NULL); + break; + + default: + break; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDbTestAllObjects + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the + * namespace by reading/writing/comparing all data objects such + * as integers, strings, buffers, fields, buffer fields, etc. + * + ******************************************************************************/ + +static void +AcpiDbTestAllObjects ( + void) +{ + ACPI_STATUS Status; + + + /* Install the debugger read-object control method if necessary */ + + if (!ReadHandle) + { + Status = AcpiInstallMethod (ReadMethodCode); + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("%s, Could not install debugger read method\n", + AcpiFormatException (Status)); + return; + } + + Status = AcpiGetHandle (NULL, ACPI_DB_READ_METHOD, &ReadHandle); + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("Could not obtain handle for debug method %s\n", + ACPI_DB_READ_METHOD); + return; + } + } + + /* Install the debugger write-object control method if necessary */ + + if (!WriteHandle) + { + Status = AcpiInstallMethod (WriteMethodCode); + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("%s, Could not install debugger write method\n", + AcpiFormatException (Status)); + return; + } + + Status = AcpiGetHandle (NULL, ACPI_DB_WRITE_METHOD, &WriteHandle); + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("Could not obtain handle for debug method %s\n", + ACPI_DB_WRITE_METHOD); + return; + } + } + + /* Walk the entire namespace, testing each supported named data object */ + + (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, AcpiDbTestOneObject, NULL, NULL, NULL); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDbTestOneObject + * + * PARAMETERS: ACPI_WALK_CALLBACK + * + * RETURN: Status + * + * DESCRIPTION: Test one namespace object. Supported types are Integer, + * String, Buffer, BufferField, and FieldUnit. All other object + * types are simply ignored. + * + * Note: Support for Packages is not implemented. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDbTestOneObject ( + ACPI_HANDLE ObjHandle, + UINT32 NestingLevel, + void *Context, + void **ReturnValue) +{ + ACPI_NAMESPACE_NODE *Node; + ACPI_OPERAND_OBJECT *ObjDesc; + ACPI_OPERAND_OBJECT *RegionObj; + ACPI_OBJECT_TYPE LocalType; + UINT32 BitLength = 0; + UINT32 ByteLength = 0; + ACPI_STATUS Status = AE_OK; + + + Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); + ObjDesc = Node->Object; + + /* + * For the supported types, get the actual bit length or + * byte length. Map the type to one of Integer/String/Buffer. + */ + switch (Node->Type) + { + case ACPI_TYPE_INTEGER: + + /* Integer width is either 32 or 64 */ + + LocalType = ACPI_TYPE_INTEGER; + BitLength = AcpiGbl_IntegerBitWidth; + break; + + case ACPI_TYPE_STRING: + + LocalType = ACPI_TYPE_STRING; + ByteLength = ObjDesc->String.Length; + break; + + case ACPI_TYPE_BUFFER: + + LocalType = ACPI_TYPE_BUFFER; + ByteLength = ObjDesc->Buffer.Length; + BitLength = ByteLength * 8; + break; + + case ACPI_TYPE_FIELD_UNIT: + case ACPI_TYPE_BUFFER_FIELD: + case ACPI_TYPE_LOCAL_REGION_FIELD: + case ACPI_TYPE_LOCAL_INDEX_FIELD: + case ACPI_TYPE_LOCAL_BANK_FIELD: + + LocalType = ACPI_TYPE_INTEGER; + if (ObjDesc) + { + /* + * Returned object will be a Buffer if the field length + * is larger than the size of an Integer (32 or 64 bits + * depending on the DSDT version). + */ + BitLength = ObjDesc->CommonField.BitLength; + ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength); + if (BitLength > AcpiGbl_IntegerBitWidth) + { + LocalType = ACPI_TYPE_BUFFER; + } + } + break; + + default: + + /* Ignore all other types */ + + return (AE_OK); + } + + /* Emit the common prefix: Type:Name */ + + AcpiOsPrintf ("%14s: %4.4s", + AcpiUtGetTypeName (Node->Type), Node->Name.Ascii); + if (!ObjDesc) + { + AcpiOsPrintf (" Ignoring, no attached object\n"); + return (AE_OK); + } + + /* + * Check for unsupported region types. Note: AcpiExec simulates + * access to SystemMemory, SystemIO, PCI_Config, and EC. + */ + switch (Node->Type) + { + case ACPI_TYPE_LOCAL_REGION_FIELD: + + RegionObj = ObjDesc->Field.RegionObj; + switch (RegionObj->Region.SpaceId) + { + case ACPI_ADR_SPACE_SYSTEM_MEMORY: + case ACPI_ADR_SPACE_SYSTEM_IO: + case ACPI_ADR_SPACE_PCI_CONFIG: + case ACPI_ADR_SPACE_EC: + + break; + + default: + + AcpiOsPrintf (" %s space is not supported [%4.4s]\n", + AcpiUtGetRegionName (RegionObj->Region.SpaceId), + RegionObj->Region.Node->Name.Ascii); + return (AE_OK); + } + break; + + default: + break; + } + + /* At this point, we have resolved the object to one of the major types */ + + switch (LocalType) + { + case ACPI_TYPE_INTEGER: + + Status = AcpiDbTestIntegerType (Node, BitLength); + break; + + case ACPI_TYPE_STRING: + + Status = AcpiDbTestStringType (Node, ByteLength); + break; + + case ACPI_TYPE_BUFFER: + + Status = AcpiDbTestBufferType (Node, BitLength); + break; + + default: + + AcpiOsPrintf (" Ignoring, type not implemented (%2.2X)", + LocalType); + break; + } + + switch (Node->Type) + { + case ACPI_TYPE_LOCAL_REGION_FIELD: + + RegionObj = ObjDesc->Field.RegionObj; + AcpiOsPrintf (" (%s)", + AcpiUtGetRegionName (RegionObj->Region.SpaceId)); + break; + + default: + break; + } + + AcpiOsPrintf ("\n"); + return (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDbTestIntegerType + * + * PARAMETERS: Node - Parent NS node for the object + * BitLength - Actual length of the object. Used for + * support of arbitrary length FieldUnit + * and BufferField objects. + * + * RETURN: Status + * + * DESCRIPTION: Test read/write for an Integer-valued object. Performs a + * write/read/compare of an arbitrary new value, then performs + * a write/read/compare of the original value. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDbTestIntegerType ( + ACPI_NAMESPACE_NODE *Node, + UINT32 BitLength) +{ + ACPI_OBJECT *Temp1 = NULL; + ACPI_OBJECT *Temp2 = NULL; + ACPI_OBJECT *Temp3 = NULL; + ACPI_OBJECT WriteValue; + UINT64 ValueToWrite; + ACPI_STATUS Status; + + + if (BitLength > 64) + { + AcpiOsPrintf (" Invalid length for an Integer: %u", BitLength); + return (AE_OK); + } + + /* Read the original value */ + + Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp1); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + AcpiOsPrintf (" (%4.4X/%3.3X) %8.8X%8.8X", + BitLength, ACPI_ROUND_BITS_UP_TO_BYTES (BitLength), + ACPI_FORMAT_UINT64 (Temp1->Integer.Value)); + + ValueToWrite = ACPI_UINT64_MAX >> (64 - BitLength); + if (Temp1->Integer.Value == ValueToWrite) + { + ValueToWrite = 0; + } + + /* Write a new value */ + + WriteValue.Type = ACPI_TYPE_INTEGER; + WriteValue.Integer.Value = ValueToWrite; + Status = AcpiDbWriteToObject (Node, &WriteValue); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } + + /* Ensure that we can read back the new value */ + + Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp2); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } + + if (Temp2->Integer.Value != ValueToWrite) + { + AcpiOsPrintf (" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X", + ACPI_FORMAT_UINT64 (Temp2->Integer.Value), + ACPI_FORMAT_UINT64 (ValueToWrite)); + } + + /* Write back the original value */ + + WriteValue.Integer.Value = Temp1->Integer.Value; + Status = AcpiDbWriteToObject (Node, &WriteValue); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } + + /* Ensure that we can read back the original value */ + + Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp3); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } + + if (Temp3->Integer.Value != Temp1->Integer.Value) + { + AcpiOsPrintf (" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X", + ACPI_FORMAT_UINT64 (Temp3->Integer.Value), + ACPI_FORMAT_UINT64 (Temp1->Integer.Value)); + } + +Exit: + if (Temp1) {AcpiOsFree (Temp1);} + if (Temp2) {AcpiOsFree (Temp2);} + if (Temp3) {AcpiOsFree (Temp3);} + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDbTestBufferType + * + * PARAMETERS: Node - Parent NS node for the object + * BitLength - Actual length of the object. + * + * RETURN: Status + * + * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a + * write/read/compare of an arbitrary new value, then performs + * a write/read/compare of the original value. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDbTestBufferType ( + ACPI_NAMESPACE_NODE *Node, + UINT32 BitLength) +{ + ACPI_OBJECT *Temp1 = NULL; + ACPI_OBJECT *Temp2 = NULL; + ACPI_OBJECT *Temp3 = NULL; + UINT8 *Buffer; + ACPI_OBJECT WriteValue; + ACPI_STATUS Status; + UINT32 ByteLength; + UINT32 i; + UINT8 ExtraBits; + + + ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength); + if (ByteLength == 0) + { + AcpiOsPrintf (" Ignoring zero length buffer"); + return (AE_OK); + } + + /* Allocate a local buffer */ + + Buffer = ACPI_ALLOCATE_ZEROED (ByteLength); + if (!Buffer) + { + return (AE_NO_MEMORY); + } + + /* Read the original value */ + + Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp1); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } + + /* Emit a few bytes of the buffer */ + + AcpiOsPrintf (" (%4.4X/%3.3X)", BitLength, Temp1->Buffer.Length); + for (i = 0; ((i < 4) && (i < ByteLength)); i++) + { + AcpiOsPrintf (" %2.2X", Temp1->Buffer.Pointer[i]); + } + AcpiOsPrintf ("... "); + + /* + * Write a new value. + * + * Handle possible extra bits at the end of the buffer. Can + * happen for FieldUnits larger than an integer, but the bit + * count is not an integral number of bytes. Zero out the + * unused bits. + */ + ACPI_MEMSET (Buffer, BUFFER_FILL_VALUE, ByteLength); + ExtraBits = BitLength % 8; + if (ExtraBits) + { + Buffer [ByteLength - 1] = ACPI_MASK_BITS_ABOVE (ExtraBits); + } + + WriteValue.Type = ACPI_TYPE_BUFFER; + WriteValue.Buffer.Length = ByteLength; + WriteValue.Buffer.Pointer = Buffer; + + Status = AcpiDbWriteToObject (Node, &WriteValue); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } + + /* Ensure that we can read back the new value */ + + Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp2); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } + + if (ACPI_MEMCMP (Temp2->Buffer.Pointer, Buffer, ByteLength)) + { + AcpiOsPrintf (" MISMATCH 2: New buffer value"); + } + + /* Write back the original value */ + + WriteValue.Buffer.Length = ByteLength; + WriteValue.Buffer.Pointer = Temp1->Buffer.Pointer; + + Status = AcpiDbWriteToObject (Node, &WriteValue); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } + + /* Ensure that we can read back the original value */ + + Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp3); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } + + if (ACPI_MEMCMP (Temp1->Buffer.Pointer, Temp3->Buffer.Pointer, ByteLength)) + { + AcpiOsPrintf (" MISMATCH 3: While restoring original buffer"); + } + +Exit: + ACPI_FREE (Buffer); + if (Temp1) {AcpiOsFree (Temp1);} + if (Temp2) {AcpiOsFree (Temp2);} + if (Temp3) {AcpiOsFree (Temp3);} + return (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDbTestStringType + * + * PARAMETERS: Node - Parent NS node for the object + * ByteLength - Actual length of the object. + * + * RETURN: Status + * + * DESCRIPTION: Test read/write for an String-valued object. Performs a + * write/read/compare of an arbitrary new value, then performs + * a write/read/compare of the original value. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDbTestStringType ( + ACPI_NAMESPACE_NODE *Node, + UINT32 ByteLength) +{ + ACPI_OBJECT *Temp1 = NULL; + ACPI_OBJECT *Temp2 = NULL; + ACPI_OBJECT *Temp3 = NULL; + char *ValueToWrite = "Test String from AML Debugger"; + ACPI_OBJECT WriteValue; + ACPI_STATUS Status; + + + /* Read the original value */ + + Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp1); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + AcpiOsPrintf (" (%4.4X/%3.3X) \"%s\"", (Temp1->String.Length * 8), + Temp1->String.Length, Temp1->String.Pointer); + + /* Write a new value */ + + WriteValue.Type = ACPI_TYPE_STRING; + WriteValue.String.Length = ACPI_STRLEN (ValueToWrite); + WriteValue.String.Pointer = ValueToWrite; + + Status = AcpiDbWriteToObject (Node, &WriteValue); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } + + /* Ensure that we can read back the new value */ + + Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp2); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } + + if (ACPI_STRCMP (Temp2->String.Pointer, ValueToWrite)) + { + AcpiOsPrintf (" MISMATCH 2: %s, expecting %s", + Temp2->String.Pointer, ValueToWrite); + } + + /* Write back the original value */ + + WriteValue.String.Length = ACPI_STRLEN (Temp1->String.Pointer); + WriteValue.String.Pointer = Temp1->String.Pointer; + + Status = AcpiDbWriteToObject (Node, &WriteValue); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } + + /* Ensure that we can read back the original value */ + + Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp3); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } + + if (ACPI_STRCMP (Temp1->String.Pointer, Temp3->String.Pointer)) + { + AcpiOsPrintf (" MISMATCH 3: %s, expecting %s", + Temp3->String.Pointer, Temp1->String.Pointer); + } + +Exit: + if (Temp1) {AcpiOsFree (Temp1);} + if (Temp2) {AcpiOsFree (Temp2);} + if (Temp3) {AcpiOsFree (Temp3);} + return (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDbReadFromObject + * + * PARAMETERS: Node - Parent NS node for the object + * ExpectedType - Object type expected from the read + * Value - Where the value read is returned + * + * RETURN: Status + * + * DESCRIPTION: Performs a read from the specified object by invoking the + * special debugger control method that reads the object. Thus, + * the AML interpreter is doing all of the work, increasing the + * validity of the test. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDbReadFromObject ( + ACPI_NAMESPACE_NODE *Node, + ACPI_OBJECT_TYPE ExpectedType, + ACPI_OBJECT **Value) +{ + ACPI_OBJECT *RetValue; + ACPI_OBJECT_LIST ParamObjects; + ACPI_OBJECT Params[2]; + ACPI_BUFFER ReturnObj; + ACPI_STATUS Status; + + + Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE; + Params[0].Reference.ActualType = Node->Type; + Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node); + + ParamObjects.Count = 1; + ParamObjects.Pointer = Params; + + ReturnObj.Length = ACPI_ALLOCATE_BUFFER; + + AcpiGbl_MethodExecuting = TRUE; + Status = AcpiEvaluateObject (ReadHandle, NULL, &ParamObjects, &ReturnObj); + AcpiGbl_MethodExecuting = FALSE; + + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("Could not read from object, %s", + AcpiFormatException (Status)); + return (Status); + } + + RetValue = (ACPI_OBJECT *) ReturnObj.Pointer; + + switch (RetValue->Type) + { + case ACPI_TYPE_INTEGER: + case ACPI_TYPE_BUFFER: + case ACPI_TYPE_STRING: + /* + * Did we receive the type we wanted? Most important for the + * Integer/Buffer case (when a field is larger than an Integer, + * it should return a Buffer). + */ + if (RetValue->Type != ExpectedType) + { + AcpiOsPrintf (" Type mismatch: Expected %s, Received %s", + AcpiUtGetTypeName (ExpectedType), + AcpiUtGetTypeName (RetValue->Type)); + + return (AE_TYPE); + } + + *Value = RetValue; + break; + + default: + + AcpiOsPrintf (" Unsupported return object type, %s", + AcpiUtGetTypeName (RetValue->Type)); + AcpiOsFree (ReturnObj.Pointer); + + return (AE_TYPE); + } + + return (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDbWriteToObject + * + * PARAMETERS: Node - Parent NS node for the object + * Value - Value to be written + * + * RETURN: Status + * + * DESCRIPTION: Performs a write to the specified object by invoking the + * special debugger control method that writes the object. Thus, + * the AML interpreter is doing all of the work, increasing the + * validity of the test. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDbWriteToObject ( + ACPI_NAMESPACE_NODE *Node, + ACPI_OBJECT *Value) +{ + ACPI_OBJECT_LIST ParamObjects; + ACPI_OBJECT Params[2]; + ACPI_STATUS Status; + + + Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE; + Params[0].Reference.ActualType = Node->Type; + Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node); + + /* Copy the incoming user parameter */ + + ACPI_MEMCPY (&Params[1], Value, sizeof (ACPI_OBJECT)); + + ParamObjects.Count = 2; + ParamObjects.Pointer = Params; + + AcpiGbl_MethodExecuting = TRUE; + Status = AcpiEvaluateObject (WriteHandle, NULL, &ParamObjects, NULL); + AcpiGbl_MethodExecuting = FALSE; + + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("Could not write to object, %s", + AcpiFormatException (Status)); + } + + return (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDbEvaluateAllPredefinedNames + * + * PARAMETERS: CountArg - Max number of methods to execute + * + * RETURN: None + * + * DESCRIPTION: Namespace batch execution. Execute predefined names in the + * namespace, up to the max count, if specified. + * + ******************************************************************************/ + +static void +AcpiDbEvaluateAllPredefinedNames ( + char *CountArg) +{ + ACPI_DB_EXECUTE_WALK Info; + + + Info.Count = 0; + Info.MaxCount = ACPI_UINT32_MAX; + + if (CountArg) + { + Info.MaxCount = ACPI_STRTOUL (CountArg, NULL, 0); + } + + /* Search all nodes in namespace */ + + (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, + AcpiDbEvaluateOnePredefinedName, NULL, (void *) &Info, NULL); + + AcpiOsPrintf ("Evaluated %u predefined names in the namespace\n", Info.Count); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDbEvaluateOnePredefinedName + * + * PARAMETERS: Callback from WalkNamespace + * + * RETURN: Status + * + * DESCRIPTION: Batch execution module. Currently only executes predefined + * ACPI names. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDbEvaluateOnePredefinedName ( + ACPI_HANDLE ObjHandle, + UINT32 NestingLevel, + void *Context, + void **ReturnValue) +{ + ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; + ACPI_DB_EXECUTE_WALK *Info = (ACPI_DB_EXECUTE_WALK *) Context; + char *Pathname; + const ACPI_PREDEFINED_INFO *Predefined; + ACPI_DEVICE_INFO *ObjInfo; + ACPI_OBJECT_LIST ParamObjects; + ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; + ACPI_OBJECT *ThisParam; + ACPI_BUFFER ReturnObj; + ACPI_STATUS Status; + UINT16 ArgTypeList; + UINT8 ArgCount; + UINT8 ArgType; + UINT32 i; + + + /* The name must be a predefined ACPI name */ + + Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii); + if (!Predefined) + { + return (AE_OK); + } + + if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) + { + return (AE_OK); + } + + Pathname = AcpiNsGetExternalPathname (Node); + if (!Pathname) + { + return (AE_OK); + } + + /* Get the object info for number of method parameters */ + + Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo); + if (ACPI_FAILURE (Status)) + { + ACPI_FREE (Pathname); + return (Status); + } + + ParamObjects.Count = 0; + ParamObjects.Pointer = NULL; + + if (ObjInfo->Type == ACPI_TYPE_METHOD) + { + /* Setup default parameters (with proper types) */ + + ArgTypeList = Predefined->Info.ArgumentList; + ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList); + + /* + * Setup the ACPI-required number of arguments, regardless of what + * the actual method defines. If there is a difference, then the + * method is wrong and a warning will be issued during execution. + */ + ThisParam = Params; + for (i = 0; i < ArgCount; i++) + { + ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList); + ThisParam->Type = ArgType; + + switch (ArgType) + { + case ACPI_TYPE_INTEGER: + + ThisParam->Integer.Value = 1; + break; + + case ACPI_TYPE_STRING: + + ThisParam->String.Pointer = "This is the default argument string"; + ThisParam->String.Length = ACPI_STRLEN (ThisParam->String.Pointer); + break; + + case ACPI_TYPE_BUFFER: + + ThisParam->Buffer.Pointer = (UINT8 *) Params; /* just a garbage buffer */ + ThisParam->Buffer.Length = 48; + break; + + case ACPI_TYPE_PACKAGE: + + ThisParam->Package.Elements = NULL; + ThisParam->Package.Count = 0; + break; + + default: + + AcpiOsPrintf ("%s: Unsupported argument type: %u\n", + Pathname, ArgType); + break; + } + + ThisParam++; + } + + ParamObjects.Count = ArgCount; + ParamObjects.Pointer = Params; + } + + ACPI_FREE (ObjInfo); + ReturnObj.Pointer = NULL; + ReturnObj.Length = ACPI_ALLOCATE_BUFFER; + + /* Do the actual method execution */ + + AcpiGbl_MethodExecuting = TRUE; + + Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj); + + AcpiOsPrintf ("%-32s returned %s\n", Pathname, AcpiFormatException (Status)); + AcpiGbl_MethodExecuting = FALSE; + ACPI_FREE (Pathname); + + /* Ignore status from method execution */ + + Status = AE_OK; + + /* Update count, check if we have executed enough methods */ + + Info->Count++; + if (Info->Count >= Info->MaxCount) + { + Status = AE_CTRL_TERMINATE; + } + + return (Status); +} + +#endif /* ACPI_DEBUGGER */ |