diff options
Diffstat (limited to 'sys/contrib/dev/acpica/psargs.c')
-rw-r--r-- | sys/contrib/dev/acpica/psargs.c | 373 |
1 files changed, 191 insertions, 182 deletions
diff --git a/sys/contrib/dev/acpica/psargs.c b/sys/contrib/dev/acpica/psargs.c index 33d5587..3c39919 100644 --- a/sys/contrib/dev/acpica/psargs.c +++ b/sys/contrib/dev/acpica/psargs.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psargs - Parse AML opcode arguments - * $Revision: 1.81 $ + * $Revision: 1.92 $ * *****************************************************************************/ @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp. * All rights reserved. * * 2. License @@ -120,6 +120,7 @@ #include <contrib/dev/acpica/acparser.h> #include <contrib/dev/acpica/amlcode.h> #include <contrib/dev/acpica/acnamesp.h> +#include <contrib/dev/acpica/acdispat.h> #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME ("psargs") @@ -141,10 +142,11 @@ AcpiPsGetNextField ( * * PARAMETERS: ParserState - Current parser state object * - * RETURN: Decoded package length. On completion, the AML pointer points + * RETURN: Decoded package length. On completion, the AML pointer points * past the length byte or bytes. * - * DESCRIPTION: Decode and return a package length field + * DESCRIPTION: Decode and return a package length field. + * Note: Largest package length is 28 bits, from ACPI specification * ******************************************************************************/ @@ -152,57 +154,43 @@ static UINT32 AcpiPsGetNextPackageLength ( ACPI_PARSE_STATE *ParserState) { - UINT32 EncodedLength; - UINT32 Length = 0; + UINT8 *Aml = ParserState->Aml; + UINT32 PackageLength = 0; + ACPI_NATIVE_UINT ByteCount; + UINT8 ByteZeroMask = 0x3F; /* Default [0:5] */ - ACPI_FUNCTION_TRACE ("PsGetNextPackageLength"); + ACPI_FUNCTION_TRACE (PsGetNextPackageLength); - EncodedLength = (UINT32) ACPI_GET8 (ParserState->Aml); - ParserState->Aml++; - - switch (EncodedLength >> 6) /* bits 6-7 contain encoding scheme */ - { - case 0: /* 1-byte encoding (bits 0-5) */ - - Length = (EncodedLength & 0x3F); - break; - - - case 1: /* 2-byte encoding (next byte + bits 0-3) */ - - Length = ((ACPI_GET8 (ParserState->Aml) << 04) | - (EncodedLength & 0x0F)); - ParserState->Aml++; - break; - - - case 2: /* 3-byte encoding (next 2 bytes + bits 0-3) */ - - Length = ((ACPI_GET8 (ParserState->Aml + 1) << 12) | - (ACPI_GET8 (ParserState->Aml) << 04) | - (EncodedLength & 0x0F)); - ParserState->Aml += 2; - break; - - - case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */ + /* + * Byte 0 bits [6:7] contain the number of additional bytes + * used to encode the package length, either 0,1,2, or 3 + */ + ByteCount = (Aml[0] >> 6); + ParserState->Aml += (ByteCount + 1); - Length = ((ACPI_GET8 (ParserState->Aml + 2) << 20) | - (ACPI_GET8 (ParserState->Aml + 1) << 12) | - (ACPI_GET8 (ParserState->Aml) << 04) | - (EncodedLength & 0x0F)); - ParserState->Aml += 3; - break; + /* Get bytes 3, 2, 1 as needed */ - default: + while (ByteCount) + { + /* + * Final bit positions for the package length bytes: + * Byte3->[20:27] + * Byte2->[12:19] + * Byte1->[04:11] + * Byte0->[00:03] + */ + PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4)); - /* Can't get here, only 2 bits / 4 cases */ - break; + ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */ + ByteCount--; } - return_UINT32 (Length); + /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */ + + PackageLength |= (Aml[0] & ByteZeroMask); + return_UINT32 (PackageLength); } @@ -224,17 +212,17 @@ AcpiPsGetNextPackageEnd ( ACPI_PARSE_STATE *ParserState) { UINT8 *Start = ParserState->Aml; - ACPI_NATIVE_UINT Length; + UINT32 PackageLength; - ACPI_FUNCTION_TRACE ("PsGetNextPackageEnd"); + ACPI_FUNCTION_TRACE (PsGetNextPackageEnd); - /* Function below changes ParserState->Aml */ + /* Function below updates ParserState->Aml */ - Length = (ACPI_NATIVE_UINT) AcpiPsGetNextPackageLength (ParserState); + PackageLength = AcpiPsGetNextPackageLength (ParserState); - return_PTR (Start + Length); /* end of package */ + return_PTR (Start + PackageLength); /* end of package */ } @@ -261,21 +249,19 @@ AcpiPsGetNextNamestring ( UINT8 *End = ParserState->Aml; - ACPI_FUNCTION_TRACE ("PsGetNextNamestring"); + ACPI_FUNCTION_TRACE (PsGetNextNamestring); - /* Handle multiple prefix characters */ + /* Point past any namestring prefix characters (backslash or carat) */ - while (AcpiPsIsPrefixChar (ACPI_GET8 (End))) + while (AcpiPsIsPrefixChar (*End)) { - /* Include prefix '\\' or '^' */ - End++; } - /* Decode the path */ + /* Decode the path prefix character */ - switch (ACPI_GET8 (End)) + switch (*End) { case 0: @@ -297,9 +283,9 @@ AcpiPsGetNextNamestring ( case AML_MULTI_NAME_PREFIX_OP: - /* Multiple name segments, 4 chars each */ + /* Multiple name segments, 4 chars each, count in next byte */ - End += 2 + ((ACPI_SIZE) ACPI_GET8 (End + 1) * ACPI_NAME_SIZE); + End += 2 + (*(End + 1) * ACPI_NAME_SIZE); break; default: @@ -310,7 +296,7 @@ AcpiPsGetNextNamestring ( break; } - ParserState->Aml = (UINT8*) End; + ParserState->Aml = End; return_PTR ((char *) Start); } @@ -323,7 +309,7 @@ AcpiPsGetNextNamestring ( * Arg - Where the namepath will be stored * ArgCount - If the namepath points to a control method * the method's argument is returned here. - * MethodCall - Whether the namepath can possibly be the + * PossibleMethodCall - Whether the namepath can possibly be the * start of a method call * * RETURN: Status @@ -341,136 +327,149 @@ AcpiPsGetNextNamepath ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_STATE *ParserState, ACPI_PARSE_OBJECT *Arg, - BOOLEAN MethodCall) + BOOLEAN PossibleMethodCall) { char *Path; ACPI_PARSE_OBJECT *NameOp; - ACPI_STATUS Status = AE_OK; + ACPI_STATUS Status; ACPI_OPERAND_OBJECT *MethodDesc; ACPI_NAMESPACE_NODE *Node; ACPI_GENERIC_STATE ScopeInfo; - ACPI_FUNCTION_TRACE ("PsGetNextNamepath"); + ACPI_FUNCTION_TRACE (PsGetNextNamepath); Path = AcpiPsGetNextNamestring (ParserState); + AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); - /* Null path case is allowed */ + /* Null path case is allowed, just exit */ - if (Path) + if (!Path) { - /* - * Lookup the name in the internal namespace - */ - ScopeInfo.Scope.Node = NULL; - Node = ParserState->StartNode; - if (Node) + Arg->Common.Value.Name = Path; + return_ACPI_STATUS (AE_OK); + } + + /* Setup search scope info */ + + ScopeInfo.Scope.Node = NULL; + Node = ParserState->StartNode; + if (Node) + { + ScopeInfo.Scope.Node = Node; + } + + /* + * Lookup the name in the internal namespace. We don't want to add + * anything new to the namespace here, however, so we use MODE_EXECUTE. + * Allow searching of the parent tree, but don't open a new scope - + * we just want to lookup the object (must be mode EXECUTE to perform + * the upsearch) + */ + Status = AcpiNsLookup (&ScopeInfo, Path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, + ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node); + + /* + * If this name is a control method invocation, we must + * setup the method call + */ + if (ACPI_SUCCESS (Status) && + PossibleMethodCall && + (Node->Type == ACPI_TYPE_METHOD)) + { + /* This name is actually a control method invocation */ + + MethodDesc = AcpiNsGetAttachedObject (Node); + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, + "Control Method - %p Desc %p Path=%p\n", Node, MethodDesc, Path)); + + NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP); + if (!NameOp) { - ScopeInfo.Scope.Node = Node; + return_ACPI_STATUS (AE_NO_MEMORY); } - /* - * Lookup object. We don't want to add anything new to the namespace - * here, however. So we use MODE_EXECUTE. Allow searching of the - * parent tree, but don't open a new scope -- we just want to lookup the - * object (MUST BE mode EXECUTE to perform upsearch) - */ - Status = AcpiNsLookup (&ScopeInfo, Path, ACPI_TYPE_ANY, - ACPI_IMODE_EXECUTE, - ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, - NULL, &Node); - if (ACPI_SUCCESS (Status) && MethodCall) - { - if (Node->Type == ACPI_TYPE_METHOD) - { - /* This name is actually a control method invocation */ + /* Change Arg into a METHOD CALL and attach name to it */ - MethodDesc = AcpiNsGetAttachedObject (Node); - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, - "Control Method - %p Desc %p Path=%p\n", - Node, MethodDesc, Path)); + AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); + NameOp->Common.Value.Name = Path; - NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP); - if (!NameOp) - { - return_ACPI_STATUS (AE_NO_MEMORY); - } + /* Point METHODCALL/NAME to the METHOD Node */ - /* Change arg into a METHOD CALL and attach name to it */ + NameOp->Common.Node = Node; + AcpiPsAppendArg (Arg, NameOp); - AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); - NameOp->Common.Value.Name = Path; + if (!MethodDesc) + { + ACPI_ERROR ((AE_INFO, + "Control Method %p has no attached object", + Node)); + return_ACPI_STATUS (AE_AML_INTERNAL); + } - /* Point METHODCALL/NAME to the METHOD Node */ + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, + "Control Method - %p Args %X\n", + Node, MethodDesc->Method.ParamCount)); - NameOp->Common.Node = Node; - AcpiPsAppendArg (Arg, NameOp); + /* Get the number of arguments to expect */ - if (!MethodDesc) - { - ACPI_REPORT_ERROR (( - "PsGetNextNamepath: Control Method %p has no attached object\n", - Node)); - return_ACPI_STATUS (AE_AML_INTERNAL); - } + WalkState->ArgCount = MethodDesc->Method.ParamCount; + return_ACPI_STATUS (AE_OK); + } - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, - "Control Method - %p Args %X\n", - Node, MethodDesc->Method.ParamCount)); + /* + * Special handling if the name was not found during the lookup - + * some NotFound cases are allowed + */ + if (Status == AE_NOT_FOUND) + { + /* 1) NotFound is ok during load pass 1/2 (allow forward references) */ - /* Get the number of arguments to expect */ + if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) != + ACPI_PARSE_EXECUTE) + { + Status = AE_OK; + } - WalkState->ArgCount = MethodDesc->Method.ParamCount; - return_ACPI_STATUS (AE_OK); - } + /* 2) NotFound during a CondRefOf(x) is ok by definition */ - /* - * Else this is normal named object reference. - * Just init the NAMEPATH object with the pathname. - * (See code below) - */ + else if (WalkState->Op->Common.AmlOpcode == AML_COND_REF_OF_OP) + { + Status = AE_OK; } - if (ACPI_FAILURE (Status)) + /* + * 3) NotFound while building a Package is ok at this point, we + * may flag as an error later if slack mode is not enabled. + * (Some ASL code depends on allowing this behavior) + */ + else if ((Arg->Common.Parent) && + ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || + (Arg->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))) { - /* - * 1) Any error other than NOT_FOUND is always severe - * 2) NOT_FOUND is only important if we are executing a method. - * 3) If executing a CondRefOf opcode, NOT_FOUND is ok. - */ - if ((((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) && - (Status == AE_NOT_FOUND) && - (WalkState->Op->Common.AmlOpcode != AML_COND_REF_OF_OP)) || - - (Status != AE_NOT_FOUND)) - { - ACPI_REPORT_NSERROR (Path, Status); + Status = AE_OK; + } + } - AcpiOsPrintf ("SearchNode %p StartNode %p ReturnNode %p\n", - ScopeInfo.Scope.Node, ParserState->StartNode, Node); + /* Final exception check (may have been changed from code above) */ + if (ACPI_FAILURE (Status)) + { + ACPI_ERROR_NAMESPACE (Path, Status); - } - else - { - /* - * We got a NOT_FOUND during table load or we encountered - * a CondRefOf(x) where the target does not exist. - * Either case is ok - */ - Status = AE_OK; - } + if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == + ACPI_PARSE_EXECUTE) + { + /* Report a control method execution error */ + + Status = AcpiDsMethodError (Status, WalkState); } } - /* - * Regardless of success/failure above, - * Just initialize the Op with the pathname. - */ - AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); - Arg->Common.Value.Name = Path; + /* Save the namepath */ + Arg->Common.Value.Name = Path; return_ACPI_STATUS (Status); } @@ -495,63 +494,71 @@ AcpiPsGetNextSimpleArg ( UINT32 ArgType, ACPI_PARSE_OBJECT *Arg) { + UINT32 Length; + UINT16 Opcode; + UINT8 *Aml = ParserState->Aml; - ACPI_FUNCTION_TRACE_U32 ("PsGetNextSimpleArg", ArgType); + + ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType); switch (ArgType) { case ARGP_BYTEDATA: - AcpiPsInitOp (Arg, AML_BYTE_OP); - Arg->Common.Value.Integer = (UINT32) ACPI_GET8 (ParserState->Aml); - ParserState->Aml++; + /* Get 1 byte from the AML stream */ + + Opcode = AML_BYTE_OP; + Arg->Common.Value.Integer = (ACPI_INTEGER) *Aml; + Length = 1; break; case ARGP_WORDDATA: - AcpiPsInitOp (Arg, AML_WORD_OP); - /* Get 2 bytes from the AML stream */ - ACPI_MOVE_16_TO_32 (&Arg->Common.Value.Integer, ParserState->Aml); - ParserState->Aml += 2; + Opcode = AML_WORD_OP; + ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml); + Length = 2; break; case ARGP_DWORDDATA: - AcpiPsInitOp (Arg, AML_DWORD_OP); - /* Get 4 bytes from the AML stream */ - ACPI_MOVE_32_TO_32 (&Arg->Common.Value.Integer, ParserState->Aml); - ParserState->Aml += 4; + Opcode = AML_DWORD_OP; + ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml); + Length = 4; break; case ARGP_QWORDDATA: - AcpiPsInitOp (Arg, AML_QWORD_OP); - /* Get 8 bytes from the AML stream */ - ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, ParserState->Aml); - ParserState->Aml += 8; + Opcode = AML_QWORD_OP; + ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml); + Length = 8; break; case ARGP_CHARLIST: - AcpiPsInitOp (Arg, AML_STRING_OP); - Arg->Common.Value.String = (char *) ParserState->Aml; + /* Get a pointer to the string, point past the string */ - while (ACPI_GET8 (ParserState->Aml) != '\0') + Opcode = AML_STRING_OP; + Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml); + + /* Find the null terminator */ + + Length = 0; + while (Aml[Length]) { - ParserState->Aml++; + Length++; } - ParserState->Aml++; + Length++; break; @@ -560,15 +567,17 @@ AcpiPsGetNextSimpleArg ( AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState); - break; + return_VOID; default: - ACPI_REPORT_ERROR (("Invalid ArgType %X\n", ArgType)); - break; + ACPI_ERROR ((AE_INFO, "Invalid ArgType %X", ArgType)); + return_VOID; } + AcpiPsInitOp (Arg, Opcode); + ParserState->Aml += Length; return_VOID; } @@ -597,7 +606,7 @@ AcpiPsGetNextField ( UINT32 Name; - ACPI_FUNCTION_TRACE ("PsGetNextField"); + ACPI_FUNCTION_TRACE (PsGetNextField); /* Determine field type */ @@ -664,7 +673,7 @@ AcpiPsGetNextField ( * Get AccessType and AccessAttrib and merge into the field Op * AccessType is first operand, AccessAttribute is second */ - Field->Common.Value.Integer = (ACPI_GET8 (ParserState->Aml) << 8); + Field->Common.Value.Integer = (((UINT32) ACPI_GET8 (ParserState->Aml) << 8)); ParserState->Aml++; Field->Common.Value.Integer |= ACPI_GET8 (ParserState->Aml); ParserState->Aml++; @@ -710,7 +719,7 @@ AcpiPsGetNextArg ( ACPI_STATUS Status = AE_OK; - ACPI_FUNCTION_TRACE_PTR ("PsGetNextArg", ParserState); + ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState); switch (ArgType) @@ -850,7 +859,7 @@ AcpiPsGetNextArg ( default: - ACPI_REPORT_ERROR (("Invalid ArgType: %X\n", ArgType)); + ACPI_ERROR ((AE_INFO, "Invalid ArgType: %X", ArgType)); Status = AE_AML_OPERAND_TYPE; break; } |