diff options
Diffstat (limited to 'sys/contrib/dev/acpica/components')
25 files changed, 761 insertions, 462 deletions
diff --git a/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c b/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c index 8134848aa39a..365e3015744a 100644 --- a/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c +++ b/sys/contrib/dev/acpica/components/disassembler/dmbuffer.c @@ -439,12 +439,16 @@ AcpiDmIsUnicodeBuffer ( return (FALSE); } - /* For each word, 1st byte must be ascii (1-0x7F), 2nd byte must be zero */ - + /* + * For each word, 1st byte must be printable ascii, and the + * 2nd byte must be zero. This does not allow for escape + * sequences, but it is the most secure way to detect a + * unicode string. + */ for (i = 0; i < (ByteCount - 2); i += 2) { if ((ByteData[i] == 0) || - (ByteData[i] > 0x7F) || + !(isprint (ByteData[i])) || (ByteData[(ACPI_SIZE) i + 1] != 0)) { return (FALSE); @@ -507,12 +511,27 @@ AcpiDmIsStringBuffer ( return (FALSE); } + /* + * Check for a possible standalone resource EndTag, ignore it + * here. However, this sequence is also the string "Y", but + * this seems rare enough to be acceptable. + */ + if ((ByteCount == 2) && (ByteData[0] == 0x79)) + { + return (FALSE); + } + + /* Check all bytes for ASCII */ + for (i = 0; i < (ByteCount - 1); i++) { - /* TBD: allow some escapes (non-ascii chars). + /* + * TBD: allow some escapes (non-ascii chars). * they will be handled in the string output routine */ + /* Not a string if not printable ascii */ + if (!isprint (ByteData[i])) { return (FALSE); diff --git a/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c b/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c index 6307bfe52cf9..3b03e3472ab1 100644 --- a/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c +++ b/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c @@ -73,6 +73,11 @@ AcpiDmIsTargetAnOperand ( ACPI_PARSE_OBJECT *Operand, BOOLEAN TopLevel); +static BOOLEAN +AcpiDmIsOptimizationIgnored ( + ACPI_PARSE_OBJECT *StoreOp, + ACPI_PARSE_OBJECT *StoreArgument); + /******************************************************************************* * @@ -95,12 +100,10 @@ AcpiDmCheckForSymbolicOpcode ( ACPI_OP_WALK_INFO *Info) { char *OperatorSymbol = NULL; - ACPI_PARSE_OBJECT *Child1; - ACPI_PARSE_OBJECT *Child2; + ACPI_PARSE_OBJECT *Argument1; + ACPI_PARSE_OBJECT *Argument2; ACPI_PARSE_OBJECT *Target; - ACPI_PARSE_OBJECT *GrandChild1; - ACPI_PARSE_OBJECT *GrandChild2; - ACPI_PARSE_OBJECT *GrandTarget = NULL; + ACPI_PARSE_OBJECT *Target2; /* Exit immediately if ASL+ not enabled */ @@ -110,25 +113,17 @@ AcpiDmCheckForSymbolicOpcode ( return (FALSE); } - /* Check for a non-ASL+ statement, propagate the flag */ - - if (Op->Common.Parent->Common.DisasmFlags & ACPI_PARSEOP_LEGACY_ASL_ONLY) - { - Op->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY; - return (FALSE); - } - /* Get the first operand */ - Child1 = AcpiPsGetArg (Op, 0); - if (!Child1) + Argument1 = AcpiPsGetArg (Op, 0); + if (!Argument1) { return (FALSE); } /* Get the second operand */ - Child2 = Child1->Common.Next; + Argument2 = Argument1->Common.Next; /* Setup the operator string for this opcode */ @@ -202,7 +197,7 @@ AcpiDmCheckForSymbolicOpcode ( * LNotEqual, LLessEqual, and LGreaterEqual. There are * no actual AML opcodes for these operators. */ - switch (Child1->Common.AmlOpcode) + switch (Argument1->Common.AmlOpcode) { case AML_LEQUAL_OP: OperatorSymbol = " != "; @@ -224,19 +219,18 @@ AcpiDmCheckForSymbolicOpcode ( return (TRUE); } - Child1->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX; + Argument1->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX; Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX; - Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND_ASSIGNMENT; /* Save symbol string in the next child (not peer) */ - Child2 = AcpiPsGetArg (Child1, 0); - if (!Child2) + Argument2 = AcpiPsGetArg (Argument1, 0); + if (!Argument2) { return (FALSE); } - Child2->Common.OperatorSymbol = OperatorSymbol; + Argument2->Common.OperatorSymbol = OperatorSymbol; return (TRUE); case AML_INDEX_OP: @@ -246,10 +240,10 @@ AcpiDmCheckForSymbolicOpcode ( * the symbolic operators for Index(). It doesn't make sense to * use Index() with a constant anyway. */ - if ((Child1->Common.AmlOpcode == AML_STRING_OP) || - (Child1->Common.AmlOpcode == AML_BUFFER_OP) || - (Child1->Common.AmlOpcode == AML_PACKAGE_OP) || - (Child1->Common.AmlOpcode == AML_VAR_PACKAGE_OP)) + if ((Argument1->Common.AmlOpcode == AML_STRING_OP) || + (Argument1->Common.AmlOpcode == AML_BUFFER_OP) || + (Argument1->Common.AmlOpcode == AML_PACKAGE_OP) || + (Argument1->Common.AmlOpcode == AML_VAR_PACKAGE_OP)) { Op->Common.DisasmFlags |= ACPI_PARSEOP_CLOSING_PAREN; return (FALSE); @@ -257,8 +251,8 @@ AcpiDmCheckForSymbolicOpcode ( /* Index operator is [] */ - Child1->Common.OperatorSymbol = " ["; - Child2->Common.OperatorSymbol = "]"; + Argument1->Common.OperatorSymbol = " ["; + Argument2->Common.OperatorSymbol = "]"; break; /* Unary operators */ @@ -280,7 +274,7 @@ AcpiDmCheckForSymbolicOpcode ( return (FALSE); } - if (Child1->Common.DisasmOpcode == ACPI_DASM_LNOT_SUFFIX) + if (Argument1->Common.DisasmOpcode == ACPI_DASM_LNOT_SUFFIX) { return (TRUE); } @@ -291,9 +285,9 @@ AcpiDmCheckForSymbolicOpcode ( * deferring symbol output until after the first operand has been * emitted. */ - if (!Child1->Common.OperatorSymbol) + if (!Argument1->Common.OperatorSymbol) { - Child1->Common.OperatorSymbol = OperatorSymbol; + Argument1->Common.OperatorSymbol = OperatorSymbol; } /* @@ -323,23 +317,58 @@ AcpiDmCheckForSymbolicOpcode ( /* Target is 3rd operand */ - Target = Child2->Common.Next; + Target = Argument2->Common.Next; if (Op->Common.AmlOpcode == AML_DIVIDE_OP) { + Target2 = Target->Common.Next; + /* * Divide has an extra target operand (Remainder). - * If this extra target is specified, it cannot be converted - * to a C-style operator + * Default behavior is to simply ignore ASL+ conversion + * if the remainder target (modulo) is specified. */ - if (AcpiDmIsValidTarget (Target)) + if (!AcpiGbl_DoDisassemblerOptimizations) { - Child1->Common.OperatorSymbol = NULL; - Op->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY; - return (FALSE); + if (AcpiDmIsValidTarget (Target)) + { + Argument1->Common.OperatorSymbol = NULL; + Op->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY; + return (FALSE); + } + + Target->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; + Target = Target2; } + else + { + /* + * Divide has an extra target operand (Remainder). + * If both targets are specified, it cannot be converted + * to a C-style operator. + */ + if (AcpiDmIsValidTarget (Target) && + AcpiDmIsValidTarget (Target2)) + { + Argument1->Common.OperatorSymbol = NULL; + Op->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY; + return (FALSE); + } + + if (AcpiDmIsValidTarget (Target)) /* Only first Target is valid (remainder) */ + { + /* Convert the Divide to Modulo */ + + Op->Common.AmlOpcode = AML_MOD_OP; - Target->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; - Target = Target->Common.Next; + Argument1->Common.OperatorSymbol = " % "; + Target2->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; + } + else /* Only second Target (quotient) is valid */ + { + Target->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; + Target = Target2; + } + } } /* Parser should ensure there is at least a placeholder target */ @@ -351,13 +380,6 @@ AcpiDmCheckForSymbolicOpcode ( if (!AcpiDmIsValidTarget (Target)) { - if (Op->Common.Parent->Common.AmlOpcode == AML_STORE_OP) - { - Op->Common.DisasmFlags = 0; - Child1->Common.OperatorSymbol = NULL; - return (FALSE); - } - /* Not a valid target (placeholder only, from parser) */ break; } @@ -390,8 +412,8 @@ AcpiDmCheckForSymbolicOpcode ( * Add (B, A, A) --> A += B * Add (B, C, A) --> A = (B + C) */ - if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)) || - (AcpiDmIsTargetAnOperand (Target, Child2, TRUE))) + if ((AcpiDmIsTargetAnOperand (Target, Argument1, TRUE)) || + (AcpiDmIsTargetAnOperand (Target, Argument2, TRUE))) { Target->Common.OperatorSymbol = AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode); @@ -399,7 +421,7 @@ AcpiDmCheckForSymbolicOpcode ( /* Convert operator to compound assignment */ Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND_ASSIGNMENT; - Child1->Common.OperatorSymbol = NULL; + Argument1->Common.OperatorSymbol = NULL; return (TRUE); } break; @@ -419,7 +441,7 @@ AcpiDmCheckForSymbolicOpcode ( * Subtract (A, B, A) --> A -= B * Subtract (B, A, A) --> A = (B - A) */ - if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE))) + if ((AcpiDmIsTargetAnOperand (Target, Argument1, TRUE))) { Target->Common.OperatorSymbol = AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode); @@ -427,7 +449,7 @@ AcpiDmCheckForSymbolicOpcode ( /* Convert operator to compound assignment */ Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND_ASSIGNMENT; - Child1->Common.OperatorSymbol = NULL; + Argument1->Common.OperatorSymbol = NULL; return (TRUE); } break; @@ -481,7 +503,7 @@ AcpiDmCheckForSymbolicOpcode ( /* Target is optional, 3rd operand */ - Target = Child2->Common.Next; + Target = Argument2->Common.Next; if (AcpiDmIsValidTarget (Target)) { AcpiDmPromoteTarget (Op, Target); @@ -495,75 +517,23 @@ AcpiDmCheckForSymbolicOpcode ( case AML_STORE_OP: /* - * Target is the 2nd operand. - * We know the target is valid, it is not optional. + * For Store, the Target is the 2nd operand. We know the target + * is valid, because it is not optional. * - * The following block implements "Ignore conversion if a store - * is followed by a math/bit operator that has no target". Used - * only for the ASL test suite. + * Ignore any optimizations/folding if flag is set. + * Used for iASL/disassembler test suite only. */ - if (!AcpiGbl_DoDisassemblerOptimizations) + if (AcpiDmIsOptimizationIgnored (Op, Argument1)) { - switch (Child1->Common.AmlOpcode) - { - /* This operator has two operands and two targets */ - - case AML_DIVIDE_OP: - - GrandChild1 = Child1->Common.Value.Arg; - GrandChild2 = GrandChild1->Common.Next; - GrandTarget = GrandChild2->Common.Next; - - if (GrandTarget && !AcpiDmIsValidTarget (GrandTarget)) - { - Op->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY; - return (FALSE); - } - GrandTarget = GrandTarget->Common.Next; - break; - - case AML_ADD_OP: - case AML_SUBTRACT_OP: - case AML_MULTIPLY_OP: - case AML_MOD_OP: - case AML_SHIFT_LEFT_OP: - case AML_SHIFT_RIGHT_OP: - case AML_BIT_AND_OP: - case AML_BIT_OR_OP: - case AML_BIT_XOR_OP: - case AML_INDEX_OP: - - /* These operators have two operands and a target */ - - GrandChild1 = Child1->Common.Value.Arg; - GrandChild2 = GrandChild1->Common.Next; - GrandTarget = GrandChild2->Common.Next; - break; - - case AML_BIT_NOT_OP: - - /* This operator has one operand and a target */ - - GrandChild1 = Child1->Common.Value.Arg; - GrandTarget = GrandChild1->Common.Next; - break; - - default: - break; - } - - if (GrandTarget && !AcpiDmIsValidTarget (GrandTarget)) - { - Op->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY; - return (FALSE); - } + return (FALSE); } /* + * Perform conversion. * In the parse tree, simply swap the target with the * source so that the target is processed first. */ - Target = Child1->Common.Next; + Target = Argument1->Common.Next; if (!Target) { return (FALSE); @@ -580,7 +550,7 @@ AcpiDmCheckForSymbolicOpcode ( /* Target is optional, 2nd operand */ - Target = Child1->Common.Next; + Target = Argument1->Common.Next; if (!Target) { return (FALSE); @@ -605,23 +575,129 @@ AcpiDmCheckForSymbolicOpcode ( break; } + /* All other operators, emit an open paren */ + + AcpiOsPrintf ("("); + return (TRUE); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmIsOptimizationIgnored + * + * PARAMETERS: StoreOp - Store operator parse object + * StoreArgument - Target associate with the Op + * + * RETURN: TRUE if this Store operator should not be converted/removed. + * + * DESCRIPTION: The following function implements "Do not optimize if a + * store is immediately followed by a math/bit operator that + * has no target". + * + * Function is ignored if DoDisassemblerOptimizations is TRUE. + * This is the default, ignore this function. + * + * Disables these types of optimizations, and simply emits + * legacy ASL code: + * Store (Add (INT1, 4), INT2) --> Add (INT1, 4, INT2) + * --> INT2 = INT1 + 4 + * + * Store (Not (INT1), INT2) --> Not (INT1, INT2) + * --> INT2 = ~INT1 + * + * Used only for the ASL test suite. For the test suite, we + * don't want to perform some optimizations to ensure binary + * compatibility with the generation of the legacy ASL->AML. + * In other words, for all test modules we want exactly: + * (ASL+ -> AML) == (ASL- -> AML) + * + ******************************************************************************/ + +static BOOLEAN +AcpiDmIsOptimizationIgnored ( + ACPI_PARSE_OBJECT *StoreOp, + ACPI_PARSE_OBJECT *StoreArgument) +{ + ACPI_PARSE_OBJECT *Argument1; + ACPI_PARSE_OBJECT *Argument2; + ACPI_PARSE_OBJECT *Target; + + + /* No optimizations/folding for the typical case */ + + if (AcpiGbl_DoDisassemblerOptimizations) + { + return (FALSE); + } + /* - * Nodes marked with ACPI_PARSEOP_PARAMLIST don't need a parens - * output here. We also need to check the parent to see if this op - * is part of a compound test (!=, >=, <=). + * Only a small subset of ASL/AML operators can be optimized. + * Can only optimize/fold if there is no target (or targets) + * specified for the operator. And of course, the operator + * is surrrounded by a Store() operator. */ - if ((Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST) || - ((Op->Common.Parent->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST) && - (Op->Common.DisasmOpcode == ACPI_DASM_LNOT_SUFFIX))) + switch (StoreArgument->Common.AmlOpcode) { - /* Do Nothing. Paren already generated */ - return (TRUE); - } + case AML_ADD_OP: + case AML_SUBTRACT_OP: + case AML_MULTIPLY_OP: + case AML_MOD_OP: + case AML_SHIFT_LEFT_OP: + case AML_SHIFT_RIGHT_OP: + case AML_BIT_AND_OP: + case AML_BIT_OR_OP: + case AML_BIT_XOR_OP: + case AML_INDEX_OP: - /* All other operators, emit an open paren */ + /* These operators have two arguments and one target */ - AcpiOsPrintf ("("); - return (TRUE); + Argument1 = StoreArgument->Common.Value.Arg; + Argument2 = Argument1->Common.Next; + Target = Argument2->Common.Next; + + if (!AcpiDmIsValidTarget (Target)) + { + StoreOp->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY; + return (TRUE); + } + break; + + case AML_DIVIDE_OP: + + /* This operator has two arguments and two targets */ + + Argument1 = StoreArgument->Common.Value.Arg; + Argument2 = Argument1->Common.Next; + Target = Argument2->Common.Next; + + if (!AcpiDmIsValidTarget (Target) || + !AcpiDmIsValidTarget (Target->Common.Next)) + { + StoreOp->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY; + return (TRUE); + } + break; + + case AML_BIT_NOT_OP: + + /* This operator has one operand and one target */ + + Argument1 = StoreArgument->Common.Value.Arg; + Target = Argument1->Common.Next; + + if (!AcpiDmIsValidTarget (Target)) + { + StoreOp->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY; + return (TRUE); + } + break; + + default: + break; + } + + return (FALSE); } @@ -643,8 +719,6 @@ void AcpiDmCloseOperator ( ACPI_PARSE_OBJECT *Op) { - BOOLEAN IsCStyleOp = FALSE; - /* Always emit paren if ASL+ disassembly disabled */ @@ -654,8 +728,6 @@ AcpiDmCloseOperator ( return; } - /* Check for a non-ASL+ statement */ - if (Op->Common.DisasmFlags & ACPI_PARSEOP_LEGACY_ASL_ONLY) { AcpiOsPrintf (")"); @@ -695,8 +767,6 @@ AcpiDmCloseOperator ( { AcpiOsPrintf (")"); } - - IsCStyleOp = TRUE; break; case AML_INDEX_OP: @@ -724,21 +794,7 @@ AcpiDmCloseOperator ( break; } - /* - * Nodes marked with ACPI_PARSEOP_PARAMLIST don't need a parens - * output here. We also need to check the parent to see if this op - * is part of a compound test (!=, >=, <=). - */ - if (IsCStyleOp && - ((Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST) || - ((Op->Common.Parent->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST) && - (Op->Common.DisasmOpcode == ACPI_DASM_LNOT_SUFFIX)))) - { - return; - } - AcpiOsPrintf (")"); - return; } diff --git a/sys/contrib/dev/acpica/components/disassembler/dmresrc.c b/sys/contrib/dev/acpica/components/disassembler/dmresrc.c index 57903a9f2dfb..5a3628855d34 100644 --- a/sys/contrib/dev/acpica/components/disassembler/dmresrc.c +++ b/sys/contrib/dev/acpica/components/disassembler/dmresrc.c @@ -392,7 +392,8 @@ AcpiDmIsResourceTemplate ( ACPI_PARSE_OBJECT *NextOp; UINT8 *Aml; UINT8 *EndAml; - ACPI_SIZE Length; + UINT32 BufferLength; + UINT32 DeclaredBufferLength; /* This op must be a buffer */ @@ -402,8 +403,10 @@ AcpiDmIsResourceTemplate ( return (AE_TYPE); } - /* Get the ByteData list and length */ - + /* + * Get the declared length of the buffer. + * This is the nn in "Buffer (nn)" + */ NextOp = Op->Common.Value.Arg; if (!NextOp) { @@ -411,6 +414,10 @@ AcpiDmIsResourceTemplate ( return (AE_TYPE); } + DeclaredBufferLength = NextOp->Common.Value.Size; + + /* Get the length of the raw initialization byte list */ + NextOp = NextOp->Common.Next; if (!NextOp) { @@ -418,11 +425,22 @@ AcpiDmIsResourceTemplate ( } Aml = NextOp->Named.Data; - Length = (ACPI_SIZE) NextOp->Common.Value.Integer; + BufferLength = NextOp->Common.Value.Size; + + /* + * Not a template if declared buffer length != actual length of the + * intialization byte list. Because the resource macros will create + * a buffer of the exact required length (buffer length will be equal + * to the actual length). + */ + if (DeclaredBufferLength != BufferLength) + { + return (AE_TYPE); + } /* Walk the byte list, abort on any invalid descriptor type or length */ - Status = AcpiUtWalkAmlResources (WalkState, Aml, Length, + Status = AcpiUtWalkAmlResources (WalkState, Aml, BufferLength, NULL, ACPI_CAST_INDIRECT_PTR (void, &EndAml)); if (ACPI_FAILURE (Status)) { @@ -435,7 +453,7 @@ AcpiDmIsResourceTemplate ( * of a ResourceTemplate, the buffer must not have any extra data after * the EndTag.) */ - if ((Aml + Length - sizeof (AML_RESOURCE_END_TAG)) != EndAml) + if ((Aml + BufferLength - sizeof (AML_RESOURCE_END_TAG)) != EndAml) { return (AE_AML_NO_RESOURCE_END_TAG); } diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsinit.c b/sys/contrib/dev/acpica/components/dispatcher/dsinit.c index e5d99299b8f0..92a604d1434b 100644 --- a/sys/contrib/dev/acpica/components/dispatcher/dsinit.c +++ b/sys/contrib/dev/acpica/components/dispatcher/dsinit.c @@ -46,6 +46,7 @@ #include <contrib/dev/acpica/include/acdispat.h> #include <contrib/dev/acpica/include/acnamesp.h> #include <contrib/dev/acpica/include/actables.h> +#include <contrib/dev/acpica/include/acinterp.h> #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME ("dsinit") @@ -231,23 +232,16 @@ AcpiDsInitializeObjects ( /* Walk entire namespace from the supplied root */ - Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - /* * We don't use AcpiWalkNamespace since we do not want to acquire * the namespace reader lock. */ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX, - ACPI_NS_WALK_UNLOCK, AcpiDsInitOneObject, NULL, &Info, NULL); + ACPI_NS_WALK_NO_UNLOCK, AcpiDsInitOneObject, NULL, &Info, NULL); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace")); } - (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); Status = AcpiGetTableByIndex (TableIndex, &Table); if (ACPI_FAILURE (Status)) diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsmethod.c b/sys/contrib/dev/acpica/components/dispatcher/dsmethod.c index 27ba6343b8e4..020df913db3e 100644 --- a/sys/contrib/dev/acpica/components/dispatcher/dsmethod.c +++ b/sys/contrib/dev/acpica/components/dispatcher/dsmethod.c @@ -107,15 +107,12 @@ AcpiDsAutoSerializeMethod ( "Method auto-serialization parse [%4.4s] %p\n", AcpiUtGetNodeName (Node), Node)); - AcpiExEnterInterpreter (); - /* Create/Init a root op for the method parse tree */ Op = AcpiPsAllocOp (AML_METHOD_OP, ObjDesc->Method.AmlStart); if (!Op) { - Status = AE_NO_MEMORY; - goto Unlock; + return_ACPI_STATUS (AE_NO_MEMORY); } AcpiPsSetName (Op, Node->Name.Integer); @@ -127,8 +124,7 @@ AcpiDsAutoSerializeMethod ( if (!WalkState) { AcpiPsFreeOp (Op); - Status = AE_NO_MEMORY; - goto Unlock; + return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitAmlWalk (WalkState, Op, Node, @@ -147,8 +143,6 @@ AcpiDsAutoSerializeMethod ( Status = AcpiPsParseAml (WalkState); AcpiPsDeleteParseTree (Op); -Unlock: - AcpiExExitInterpreter (); return_ACPI_STATUS (Status); } @@ -784,26 +778,6 @@ AcpiDsTerminateControlMethod ( AcpiDsMethodDataDeleteAll (WalkState); /* - * If method is serialized, release the mutex and restore the - * current sync level for this thread - */ - if (MethodDesc->Method.Mutex) - { - /* Acquisition Depth handles recursive calls */ - - MethodDesc->Method.Mutex->Mutex.AcquisitionDepth--; - if (!MethodDesc->Method.Mutex->Mutex.AcquisitionDepth) - { - WalkState->Thread->CurrentSyncLevel = - MethodDesc->Method.Mutex->Mutex.OriginalSyncLevel; - - AcpiOsReleaseMutex ( - MethodDesc->Method.Mutex->Mutex.OsMutex); - MethodDesc->Method.Mutex->Mutex.ThreadId = 0; - } - } - - /* * Delete any namespace objects created anywhere within the * namespace by the execution of this method. Unless: * 1) This method is a module-level executable code method, in which @@ -836,6 +810,26 @@ AcpiDsTerminateControlMethod ( ~ACPI_METHOD_MODIFIED_NAMESPACE; } } + + /* + * If method is serialized, release the mutex and restore the + * current sync level for this thread + */ + if (MethodDesc->Method.Mutex) + { + /* Acquisition Depth handles recursive calls */ + + MethodDesc->Method.Mutex->Mutex.AcquisitionDepth--; + if (!MethodDesc->Method.Mutex->Mutex.AcquisitionDepth) + { + WalkState->Thread->CurrentSyncLevel = + MethodDesc->Method.Mutex->Mutex.OriginalSyncLevel; + + AcpiOsReleaseMutex ( + MethodDesc->Method.Mutex->Mutex.OsMutex); + MethodDesc->Method.Mutex->Mutex.ThreadId = 0; + } + } } /* Decrement the thread count on the method */ diff --git a/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c b/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c index 826866b8bed5..19bdd5518564 100644 --- a/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c +++ b/sys/contrib/dev/acpica/components/dispatcher/dsopcode.c @@ -90,7 +90,7 @@ AcpiDsInitializeRegion ( /* Namespace is NOT locked */ - Status = AcpiEvInitializeRegion (ObjDesc, FALSE); + Status = AcpiEvInitializeRegion (ObjDesc); return (Status); } diff --git a/sys/contrib/dev/acpica/components/dispatcher/dswload2.c b/sys/contrib/dev/acpica/components/dispatcher/dswload2.c index e9a34cc05dd9..e060b7c73648 100644 --- a/sys/contrib/dev/acpica/components/dispatcher/dswload2.c +++ b/sys/contrib/dev/acpica/components/dispatcher/dswload2.c @@ -626,23 +626,8 @@ AcpiDsLoad2EndOp ( } } - AcpiExExitInterpreter (); Status = AcpiEvInitializeRegion ( - AcpiNsGetAttachedObject (Node), FALSE); - AcpiExEnterInterpreter (); - - if (ACPI_FAILURE (Status)) - { - /* - * If AE_NOT_EXIST is returned, it is not fatal - * because many regions get created before a handler - * is installed for said region. - */ - if (AE_NOT_EXIST == Status) - { - Status = AE_OK; - } - } + AcpiNsGetAttachedObject (Node)); break; case AML_NAME_OP: diff --git a/sys/contrib/dev/acpica/components/events/evrgnini.c b/sys/contrib/dev/acpica/components/events/evrgnini.c index 4859e692767d..da759c63e711 100644 --- a/sys/contrib/dev/acpica/components/events/evrgnini.c +++ b/sys/contrib/dev/acpica/components/events/evrgnini.c @@ -45,6 +45,7 @@ #include <contrib/dev/acpica/include/accommon.h> #include <contrib/dev/acpica/include/acevents.h> #include <contrib/dev/acpica/include/acnamesp.h> +#include <contrib/dev/acpica/include/acinterp.h> #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME ("evrgnini") @@ -537,7 +538,6 @@ AcpiEvDefaultRegionSetup ( * FUNCTION: AcpiEvInitializeRegion * * PARAMETERS: RegionObj - Region we are initializing - * AcpiNsLocked - Is namespace locked? * * RETURN: Status * @@ -555,21 +555,33 @@ AcpiEvDefaultRegionSetup ( * MUTEX: Interpreter should be unlocked, because we may run the _REG * method for this region. * + * NOTE: Possible incompliance: + * There is a behavior conflict in automatic _REG execution: + * 1. When the interpreter is evaluating a method, we can only + * automatically run _REG for the following case: + * Method(_REG, 2) {} + * OperationRegion (OPR1, 0x80, 0x1000010, 0x4) + * 2. When the interpreter is loading a table, we can also + * automatically run _REG for the following case: + * OperationRegion (OPR1, 0x80, 0x1000010, 0x4) + * Method(_REG, 2) {} + * Though this may not be compliant to the de-facto standard, the + * logic is kept in order not to trigger regressions. And keeping + * this logic should be taken care by the caller of this function. + * ******************************************************************************/ ACPI_STATUS AcpiEvInitializeRegion ( - ACPI_OPERAND_OBJECT *RegionObj, - BOOLEAN AcpiNsLocked) + ACPI_OPERAND_OBJECT *RegionObj) { ACPI_OPERAND_OBJECT *HandlerObj; ACPI_OPERAND_OBJECT *ObjDesc; ACPI_ADR_SPACE_TYPE SpaceId; ACPI_NAMESPACE_NODE *Node; - ACPI_STATUS Status; - ACPI_FUNCTION_TRACE_U32 (EvInitializeRegion, AcpiNsLocked); + ACPI_FUNCTION_TRACE (EvInitializeRegion); if (!RegionObj) @@ -641,33 +653,15 @@ AcpiEvInitializeRegion ( "Found handler %p for region %p in obj %p\n", HandlerObj, RegionObj, ObjDesc)); - Status = AcpiEvAttachRegion (HandlerObj, RegionObj, - AcpiNsLocked); + (void) AcpiEvAttachRegion (HandlerObj, RegionObj, FALSE); /* * Tell all users that this region is usable by * running the _REG method */ - if (AcpiNsLocked) - { - Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - } - - Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT); - - if (AcpiNsLocked) - { - Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - } - + AcpiExExitInterpreter (); + (void) AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT); + AcpiExEnterInterpreter (); return_ACPI_STATUS (AE_OK); } } @@ -677,11 +671,14 @@ AcpiEvInitializeRegion ( Node = Node->Parent; } - /* If we get here, there is no handler for this region */ - + /* + * If we get here, there is no handler for this region. This is not + * fatal because many regions get created before a handler is installed + * for said region. + */ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "No handler for RegionType %s(%X) (RegionObj %p)\n", AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj)); - return_ACPI_STATUS (AE_NOT_EXIST); + return_ACPI_STATUS (AE_OK); } diff --git a/sys/contrib/dev/acpica/components/executer/exconfig.c b/sys/contrib/dev/acpica/components/executer/exconfig.c index a6be0a7d5ef4..628c1893a36b 100644 --- a/sys/contrib/dev/acpica/components/executer/exconfig.c +++ b/sys/contrib/dev/acpica/components/executer/exconfig.c @@ -480,7 +480,7 @@ AcpiExLoadOp ( ACPI_INFO (("Dynamic OEM Table Load:")); AcpiExExitInterpreter (); - Status = AcpiTbInstallAndLoadTable (Table, ACPI_PTR_TO_PHYSADDR (Table), + Status = AcpiTbInstallAndLoadTable (ACPI_PTR_TO_PHYSADDR (Table), ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, TRUE, &TableIndex); AcpiExEnterInterpreter (); if (ACPI_FAILURE (Status)) @@ -545,7 +545,6 @@ AcpiExUnloadTable ( ACPI_STATUS Status = AE_OK; ACPI_OPERAND_OBJECT *TableDesc = DdbHandle; UINT32 TableIndex; - ACPI_TABLE_HEADER *Table; ACPI_FUNCTION_TRACE (ExUnloadTable); @@ -586,42 +585,7 @@ AcpiExUnloadTable ( * strict order requirement against it. */ AcpiExExitInterpreter (); - - /* Ensure the table is still loaded */ - - if (!AcpiTbIsTableLoaded (TableIndex)) - { - Status = AE_NOT_EXIST; - goto LockAndExit; - } - - /* Invoke table handler if present */ - - if (AcpiGbl_TableHandler) - { - Status = AcpiGetTableByIndex (TableIndex, &Table); - if (ACPI_SUCCESS (Status)) - { - (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, Table, - AcpiGbl_TableHandlerContext); - } - } - - /* Delete the portion of the namespace owned by this table */ - - Status = AcpiTbDeleteNamespaceByOwner (TableIndex); - if (ACPI_FAILURE (Status)) - { - goto LockAndExit; - } - - (void) AcpiTbReleaseOwnerId (TableIndex); - AcpiTbSetTableLoadedFlag (TableIndex, FALSE); - -LockAndExit: - - /* Re-acquire the interpreter lock */ - + Status = AcpiTbUnloadTable (TableIndex); AcpiExEnterInterpreter (); /* diff --git a/sys/contrib/dev/acpica/components/executer/exconvrt.c b/sys/contrib/dev/acpica/components/executer/exconvrt.c index 5e664d676813..497788a9f638 100644 --- a/sys/contrib/dev/acpica/components/executer/exconvrt.c +++ b/sys/contrib/dev/acpica/components/executer/exconvrt.c @@ -645,7 +645,6 @@ AcpiExConvertToTargetType ( switch (GET_CURRENT_ARG_TYPE (WalkState->OpInfo->RuntimeArgs)) { case ARGI_SIMPLE_TARGET: - case ARGI_FIXED_TARGET: case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */ switch (DestinationType) diff --git a/sys/contrib/dev/acpica/components/executer/exresop.c b/sys/contrib/dev/acpica/components/executer/exresop.c index 6bff61530793..de909989e42d 100644 --- a/sys/contrib/dev/acpica/components/executer/exresop.c +++ b/sys/contrib/dev/acpica/components/executer/exresop.c @@ -321,7 +321,6 @@ AcpiExResolveOperands ( case ARGI_OBJECT_REF: case ARGI_DEVICE_REF: case ARGI_TARGETREF: /* Allows implicit conversion rules before store */ - case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */ case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion */ case ARGI_STORE_TARGET: diff --git a/sys/contrib/dev/acpica/components/namespace/nsload.c b/sys/contrib/dev/acpica/components/namespace/nsload.c index a7dba4fd762e..42d9f0db58d9 100644 --- a/sys/contrib/dev/acpica/components/namespace/nsload.c +++ b/sys/contrib/dev/acpica/components/namespace/nsload.c @@ -154,7 +154,9 @@ Unlock: ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Begin Table Object Initialization\n")); + AcpiExEnterInterpreter (); Status = AcpiDsInitializeObjects (TableIndex, Node); + AcpiExExitInterpreter (); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Completed Table Object Initialization\n")); diff --git a/sys/contrib/dev/acpica/components/namespace/nsnames.c b/sys/contrib/dev/acpica/components/namespace/nsnames.c index f558c59c4960..5ddc0d41f44e 100644 --- a/sys/contrib/dev/acpica/components/namespace/nsnames.c +++ b/sys/contrib/dev/acpica/components/namespace/nsnames.c @@ -110,6 +110,58 @@ AcpiNsGetPathnameLength ( /******************************************************************************* * + * FUNCTION: AcpiNsHandleToName + * + * PARAMETERS: TargetHandle - Handle of named object whose name is + * to be found + * Buffer - Where the name is returned + * + * RETURN: Status, Buffer is filled with name if status is AE_OK + * + * DESCRIPTION: Build and return a full namespace name + * + ******************************************************************************/ + +ACPI_STATUS +AcpiNsHandleToName ( + ACPI_HANDLE TargetHandle, + ACPI_BUFFER *Buffer) +{ + ACPI_STATUS Status; + ACPI_NAMESPACE_NODE *Node; + const char *NodeName; + + + ACPI_FUNCTION_TRACE_PTR (NsHandleToName, TargetHandle); + + + Node = AcpiNsValidateHandle (TargetHandle); + if (!Node) + { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + /* Validate/Allocate/Clear caller buffer */ + + Status = AcpiUtInitializeBuffer (Buffer, ACPI_PATH_SEGMENT_LENGTH); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + /* Just copy the ACPI name from the Node and zero terminate it */ + + NodeName = AcpiUtGetNodeName (Node); + ACPI_MOVE_NAME (Buffer->Pointer, NodeName); + ((char *) Buffer->Pointer) [ACPI_NAME_SIZE] = 0; + + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%4.4s\n", (char *) Buffer->Pointer)); + return_ACPI_STATUS (AE_OK); +} + + +/******************************************************************************* + * * FUNCTION: AcpiNsHandleToPathname * * PARAMETERS: TargetHandle - Handle of named object whose name is diff --git a/sys/contrib/dev/acpica/components/namespace/nsxfname.c b/sys/contrib/dev/acpica/components/namespace/nsxfname.c index 55c515ff0aa8..7a5c1c32385a 100644 --- a/sys/contrib/dev/acpica/components/namespace/nsxfname.c +++ b/sys/contrib/dev/acpica/components/namespace/nsxfname.c @@ -176,8 +176,6 @@ AcpiGetName ( ACPI_BUFFER *Buffer) { ACPI_STATUS Status; - ACPI_NAMESPACE_NODE *Node; - const char *NodeName; /* Parameter validation */ @@ -193,16 +191,6 @@ AcpiGetName ( return (Status); } - if (NameType == ACPI_FULL_PATHNAME || - NameType == ACPI_FULL_PATHNAME_NO_TRAILING) - { - /* Get the full pathname (From the namespace root) */ - - Status = AcpiNsHandleToPathname (Handle, Buffer, - NameType == ACPI_FULL_PATHNAME ? FALSE : TRUE); - return (Status); - } - /* * Wants the single segment ACPI name. * Validate handle and convert to a namespace Node @@ -213,30 +201,20 @@ AcpiGetName ( return (Status); } - Node = AcpiNsValidateHandle (Handle); - if (!Node) + if (NameType == ACPI_FULL_PATHNAME || + NameType == ACPI_FULL_PATHNAME_NO_TRAILING) { - Status = AE_BAD_PARAMETER; - goto UnlockAndExit; - } - - /* Validate/Allocate/Clear caller buffer */ + /* Get the full pathname (From the namespace root) */ - Status = AcpiUtInitializeBuffer (Buffer, ACPI_PATH_SEGMENT_LENGTH); - if (ACPI_FAILURE (Status)) - { - goto UnlockAndExit; + Status = AcpiNsHandleToPathname (Handle, Buffer, + NameType == ACPI_FULL_PATHNAME ? FALSE : TRUE); } + else + { + /* Get the single name */ - /* Just copy the ACPI name from the Node and zero terminate it */ - - NodeName = AcpiUtGetNodeName (Node); - ACPI_MOVE_NAME (Buffer->Pointer, NodeName); - ((char *) Buffer->Pointer) [ACPI_NAME_SIZE] = 0; - Status = AE_OK; - - -UnlockAndExit: + Status = AcpiNsHandleToName (Handle, Buffer); + } (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); return (Status); diff --git a/sys/contrib/dev/acpica/components/parser/psargs.c b/sys/contrib/dev/acpica/components/parser/psargs.c index 9c49ea652f22..dbc8df489596 100644 --- a/sys/contrib/dev/acpica/components/parser/psargs.c +++ b/sys/contrib/dev/acpica/components/parser/psargs.c @@ -298,23 +298,12 @@ AcpiPsGetNextNamepath ( PossibleMethodCall && (Node->Type == ACPI_TYPE_METHOD)) { - if (WalkState->Opcode == AML_UNLOAD_OP) - { - /* - * AcpiPsGetNextNamestring has increased the AML pointer, - * so we need to restore the saved AML pointer for method call. - */ - WalkState->ParserState.Aml = Start; - WalkState->ArgCount = 1; - AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); - return_ACPI_STATUS (AE_OK); - } - /* 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)); + "Control Method invocation %4.4s - %p Desc %p Path=%p\n", + Node->Name.Ascii, Node, MethodDesc, Path)); NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Start); if (!NameOp) @@ -771,6 +760,10 @@ AcpiPsGetNextArg ( ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState); + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, + "Expected argument type ARGP: %s (%2.2X)\n", + AcpiUtGetArgumentTypeName (ArgType), ArgType)); + switch (ArgType) { case ARGP_BYTEDATA: @@ -854,11 +847,13 @@ AcpiPsGetNextArg ( } break; - case ARGP_TARGET: - case ARGP_SUPERNAME: case ARGP_SIMPLENAME: case ARGP_NAME_OR_REF: + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, + "**** SimpleName/NameOrRef: %s (%2.2X)\n", + AcpiUtGetArgumentTypeName (ArgType), ArgType)); + Subop = AcpiPsPeekOpcode (ParserState); if (Subop == 0 || AcpiPsIsLeadingChar (Subop) || @@ -873,28 +868,37 @@ AcpiPsGetNextArg ( return_ACPI_STATUS (AE_NO_MEMORY); } - /* To support SuperName arg of Unload */ + Status = AcpiPsGetNextNamepath (WalkState, ParserState, + Arg, ACPI_NOT_METHOD_CALL); + } + else + { + /* Single complex argument, nothing returned */ - if (WalkState->Opcode == AML_UNLOAD_OP) - { - Status = AcpiPsGetNextNamepath (WalkState, ParserState, - Arg, ACPI_POSSIBLE_METHOD_CALL); - - /* - * If the SuperName argument is a method call, we have - * already restored the AML pointer, just free this Arg - */ - if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP) - { - AcpiPsFreeOp (Arg); - Arg = NULL; - } - } - else + WalkState->ArgCount = 1; + } + break; + + case ARGP_TARGET: + case ARGP_SUPERNAME: + + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, + "**** Target/Supername: %s (%2.2X)\n", + AcpiUtGetArgumentTypeName (ArgType), ArgType)); + + Subop = AcpiPsPeekOpcode (ParserState); + if (Subop == 0) + { + /* NULL target (zero). Convert to a NULL namepath */ + + Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml); + if (!Arg) { - Status = AcpiPsGetNextNamepath (WalkState, ParserState, - Arg, ACPI_NOT_METHOD_CALL); + return_ACPI_STATUS (AE_NO_MEMORY); } + + Status = AcpiPsGetNextNamepath (WalkState, ParserState, + Arg, ACPI_POSSIBLE_METHOD_CALL); } else { @@ -907,6 +911,11 @@ AcpiPsGetNextArg ( case ARGP_DATAOBJ: case ARGP_TERMARG: + + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, + "**** TermArg/DataObj: %s (%2.2X)\n", + AcpiUtGetArgumentTypeName (ArgType), ArgType)); + /* Single complex argument, nothing returned */ WalkState->ArgCount = 1; diff --git a/sys/contrib/dev/acpica/components/parser/psloop.c b/sys/contrib/dev/acpica/components/parser/psloop.c index cbcca1088ffa..8565421071f3 100644 --- a/sys/contrib/dev/acpica/components/parser/psloop.c +++ b/sys/contrib/dev/acpica/components/parser/psloop.c @@ -104,6 +104,9 @@ AcpiPsGetArguments ( ACPI_FUNCTION_TRACE_PTR (PsGetArguments, WalkState); + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, + "Get arguments for opcode [%s]\n", Op->Common.AmlOpName)); + switch (Op->Common.AmlOpcode) { case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ diff --git a/sys/contrib/dev/acpica/components/parser/psobject.c b/sys/contrib/dev/acpica/components/parser/psobject.c index 3b94e2cd7dc8..31050f15239d 100644 --- a/sys/contrib/dev/acpica/components/parser/psobject.c +++ b/sys/contrib/dev/acpica/components/parser/psobject.c @@ -373,7 +373,13 @@ AcpiPsCreateOp ( Op->Common.Flags |= ACPI_PARSEOP_TARGET; } } - else if (ParentScope->Common.AmlOpcode == AML_INCREMENT_OP) + + /* + * Special case for both Increment() and Decrement(), where + * the lone argument is both a source and a target. + */ + else if ((ParentScope->Common.AmlOpcode == AML_INCREMENT_OP) || + (ParentScope->Common.AmlOpcode == AML_DECREMENT_OP)) { Op->Common.Flags |= ACPI_PARSEOP_TARGET; } diff --git a/sys/contrib/dev/acpica/components/parser/pstree.c b/sys/contrib/dev/acpica/components/parser/pstree.c index dd2d5e0d1895..8dab452dfa23 100644 --- a/sys/contrib/dev/acpica/components/parser/pstree.c +++ b/sys/contrib/dev/acpica/components/parser/pstree.c @@ -142,12 +142,12 @@ AcpiPsAppendArg ( const ACPI_OPCODE_INFO *OpInfo; - ACPI_FUNCTION_ENTRY (); + ACPI_FUNCTION_TRACE ("PsAppendArg"); if (!Op) { - return; + return_VOID; } /* Get the info structure for this opcode */ @@ -159,7 +159,7 @@ AcpiPsAppendArg ( ACPI_ERROR ((AE_INFO, "Invalid AML Opcode: 0x%2.2X", Op->Common.AmlOpcode)); - return; + return_VOID; } /* Check if this opcode requires argument sub-objects */ @@ -168,7 +168,7 @@ AcpiPsAppendArg ( { /* Has no linked argument objects */ - return; + return_VOID; } /* Append the argument to the linked argument list */ @@ -200,6 +200,8 @@ AcpiPsAppendArg ( Op->Common.ArgListLength++; } + + return_VOID; } diff --git a/sys/contrib/dev/acpica/components/tables/tbdata.c b/sys/contrib/dev/acpica/components/tables/tbdata.c index 39c627c0bbac..e1eccd8a2828 100644 --- a/sys/contrib/dev/acpica/components/tables/tbdata.c +++ b/sys/contrib/dev/acpica/components/tables/tbdata.c @@ -937,9 +937,9 @@ AcpiTbLoadTable ( * * FUNCTION: AcpiTbInstallAndLoadTable * - * PARAMETERS: Table - Pointer to the table - * Address - Physical address of the table + * PARAMETERS: Address - Physical address of the table * Flags - Allocation flags of the table + * Override - Whether override should be performed * TableIndex - Where table index is returned * * RETURN: Status @@ -950,7 +950,6 @@ AcpiTbLoadTable ( ACPI_STATUS AcpiTbInstallAndLoadTable ( - ACPI_TABLE_HEADER *Table, ACPI_PHYSICAL_ADDRESS Address, UINT8 Flags, BOOLEAN Override, @@ -958,10 +957,9 @@ AcpiTbInstallAndLoadTable ( { ACPI_STATUS Status; UINT32 i; - ACPI_OWNER_ID OwnerId; - ACPI_FUNCTION_TRACE (AcpiLoadTable); + ACPI_FUNCTION_TRACE (TbInstallAndLoadTable); (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); @@ -975,48 +973,68 @@ AcpiTbInstallAndLoadTable ( goto UnlockAndExit; } - /* - * Note: Now table is "INSTALLED", it must be validated before - * using. - */ - Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]); - if (ACPI_FAILURE (Status)) - { - goto UnlockAndExit; - } + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + Status = AcpiTbLoadTable (i, AcpiGbl_RootNode); + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); +UnlockAndExit: + *TableIndex = i; (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - Status = AcpiNsLoadTable (i, AcpiGbl_RootNode); + return_ACPI_STATUS (Status); +} - /* Execute any module-level code that was found in the table */ - if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode) - { - AcpiNsExecModuleCodeList (); - } +/******************************************************************************* + * + * FUNCTION: AcpiTbUnloadTable + * + * PARAMETERS: TableIndex - Table index + * + * RETURN: Status + * + * DESCRIPTION: Unload an ACPI table + * + ******************************************************************************/ - /* - * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is - * responsible for discovering any new wake GPEs by running _PRW methods - * that may have been loaded by this table. - */ - Status = AcpiTbGetOwnerId (i, &OwnerId); - if (ACPI_SUCCESS (Status)) +ACPI_STATUS +AcpiTbUnloadTable ( + UINT32 TableIndex) +{ + ACPI_STATUS Status = AE_OK; + ACPI_TABLE_HEADER *Table; + + + ACPI_FUNCTION_TRACE (TbUnloadTable); + + + /* Ensure the table is still loaded */ + + if (!AcpiTbIsTableLoaded (TableIndex)) { - AcpiEvUpdateGpes (OwnerId); + return_ACPI_STATUS (AE_NOT_EXIST); } /* Invoke table handler if present */ if (AcpiGbl_TableHandler) { - (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table, - AcpiGbl_TableHandlerContext); + Status = AcpiGetTableByIndex (TableIndex, &Table); + if (ACPI_SUCCESS (Status)) + { + (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, Table, + AcpiGbl_TableHandlerContext); + } } - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); -UnlockAndExit: - *TableIndex = i; - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + /* Delete the portion of the namespace owned by this table */ + + Status = AcpiTbDeleteNamespaceByOwner (TableIndex); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + (void) AcpiTbReleaseOwnerId (TableIndex); + AcpiTbSetTableLoadedFlag (TableIndex, FALSE); return_ACPI_STATUS (Status); } diff --git a/sys/contrib/dev/acpica/components/tables/tbfadt.c b/sys/contrib/dev/acpica/components/tables/tbfadt.c index 2ab5da088ed0..ee8a815a8226 100644 --- a/sys/contrib/dev/acpica/components/tables/tbfadt.c +++ b/sys/contrib/dev/acpica/components/tables/tbfadt.c @@ -341,6 +341,8 @@ AcpiTbParseFadt ( { UINT32 Length; ACPI_TABLE_HEADER *Table; + ACPI_TABLE_DESC *FadtDesc; + ACPI_STATUS Status; /* @@ -350,14 +352,13 @@ AcpiTbParseFadt ( * Get a local copy of the FADT and convert it to a common format * Map entire FADT, assumed to be smaller than one page. */ - Length = AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex].Length; - - Table = AcpiOsMapMemory ( - AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex].Address, Length); - if (!Table) + FadtDesc = &AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex]; + Status = AcpiTbGetTable (FadtDesc, &Table); + if (ACPI_FAILURE (Status)) { return; } + Length = FadtDesc->Length; /* * Validate the FADT checksum before we copy the table. Ignore @@ -371,7 +372,7 @@ AcpiTbParseFadt ( /* All done with the real FADT, unmap it */ - AcpiOsUnmapMemory (Table, Length); + AcpiTbPutTable (FadtDesc); /* Obtain the DSDT and FACS tables via their addresses within the FADT */ @@ -522,19 +523,17 @@ AcpiTbConvertFadt ( /* - * For ACPI 1.0 FADTs (revision 1), ensure that reserved fields which + * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which * should be zero are indeed zero. This will workaround BIOSs that * inadvertently place values in these fields. * * The ACPI 1.0 reserved fields that will be zeroed are the bytes located * at offset 45, 55, 95, and the word located at offset 109, 110. * - * Note: The FADT revision value is unreliable because of BIOS errors. - * The table length is instead used as the final word on the version. - * - * Note: FADT revision 3 is the ACPI 2.0 version of the FADT. + * Note: The FADT revision value is unreliable. Only the length can be + * trusted. */ - if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V3_SIZE) + if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE) { AcpiGbl_FADT.PreferredProfile = 0; AcpiGbl_FADT.PstateControl = 0; diff --git a/sys/contrib/dev/acpica/components/tables/tbutils.c b/sys/contrib/dev/acpica/components/tables/tbutils.c index d9a12fedeb81..08ab87f8e1f7 100644 --- a/sys/contrib/dev/acpica/components/tables/tbutils.c +++ b/sys/contrib/dev/acpica/components/tables/tbutils.c @@ -411,3 +411,99 @@ NextTable: AcpiOsUnmapMemory (Table, Length); return_ACPI_STATUS (AE_OK); } + + +/******************************************************************************* + * + * FUNCTION: AcpiTbGetTable + * + * PARAMETERS: TableDesc - Table descriptor + * OutTable - Where the pointer to the table is returned + * + * RETURN: Status and pointer to the requested table + * + * DESCRIPTION: Increase a reference to a table descriptor and return the + * validated table pointer. + * If the table descriptor is an entry of the root table list, + * this API must be invoked with ACPI_MTX_TABLES acquired. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbGetTable ( + ACPI_TABLE_DESC *TableDesc, + ACPI_TABLE_HEADER **OutTable) +{ + ACPI_STATUS Status; + + + ACPI_FUNCTION_TRACE (AcpiTbGetTable); + + + if (TableDesc->ValidationCount == 0) + { + /* Table need to be "VALIDATED" */ + + Status = AcpiTbValidateTable (TableDesc); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + } + + TableDesc->ValidationCount++; + if (TableDesc->ValidationCount == 0) + { + ACPI_ERROR ((AE_INFO, + "Table %p, Validation count is zero after increment\n", + TableDesc)); + TableDesc->ValidationCount--; + return_ACPI_STATUS (AE_LIMIT); + } + + *OutTable = TableDesc->Pointer; + return_ACPI_STATUS (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbPutTable + * + * PARAMETERS: TableDesc - Table descriptor + * + * RETURN: None + * + * DESCRIPTION: Decrease a reference to a table descriptor and release the + * validated table pointer if no references. + * If the table descriptor is an entry of the root table list, + * this API must be invoked with ACPI_MTX_TABLES acquired. + * + ******************************************************************************/ + +void +AcpiTbPutTable ( + ACPI_TABLE_DESC *TableDesc) +{ + + ACPI_FUNCTION_TRACE (AcpiTbPutTable); + + + if (TableDesc->ValidationCount == 0) + { + ACPI_WARNING ((AE_INFO, + "Table %p, Validation count is zero before decrement\n", + TableDesc)); + return_VOID; + } + TableDesc->ValidationCount--; + + if (TableDesc->ValidationCount == 0) + { + /* Table need to be "INVALIDATED" */ + + AcpiTbInvalidateTable (TableDesc); + } + + return_VOID; +} diff --git a/sys/contrib/dev/acpica/components/tables/tbxface.c b/sys/contrib/dev/acpica/components/tables/tbxface.c index 2b12bb790aee..6e231cd8fceb 100644 --- a/sys/contrib/dev/acpica/components/tables/tbxface.c +++ b/sys/contrib/dev/acpica/components/tables/tbxface.c @@ -184,6 +184,7 @@ AcpiReallocateRootTable ( void) { ACPI_STATUS Status; + UINT32 i; ACPI_FUNCTION_TRACE (AcpiReallocateRootTable); @@ -198,6 +199,22 @@ AcpiReallocateRootTable ( return_ACPI_STATUS (AE_SUPPORT); } + /* + * Ensure OS early boot logic, which is required by some hosts. If the + * table state is reported to be wrong, developers should fix the + * issue by invoking AcpiPutTable() for the reported table during the + * early stage. + */ + for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) + { + if (AcpiGbl_RootTableList.Tables[i].Pointer) + { + ACPI_ERROR ((AE_INFO, + "Table [%4.4s] is not invalidated during early boot stage", + AcpiGbl_RootTableList.Tables[i].Signature.Ascii)); + } + } + AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE; Status = AcpiTbResizeRootTableList (); @@ -307,6 +324,11 @@ ACPI_EXPORT_SYMBOL (AcpiGetTableHeader) * * DESCRIPTION: Finds and verifies an ACPI table. Table must be in the * RSDT/XSDT. + * Note that an early stage AcpiGetTable() call must be paired + * with an early stage AcpiPutTable() call. otherwise the table + * pointer mapped by the early stage mapping implementation may be + * erroneously unmapped by the late stage unmapping implementation + * in an AcpiPutTable() invoked during the late stage. * ******************************************************************************/ @@ -318,7 +340,8 @@ AcpiGetTable ( { UINT32 i; UINT32 j; - ACPI_STATUS Status; + ACPI_STATUS Status = AE_NOT_FOUND; + ACPI_TABLE_DESC *TableDesc; /* Parameter validation */ @@ -328,12 +351,22 @@ AcpiGetTable ( return (AE_BAD_PARAMETER); } + /* + * Note that the following line is required by some OSPMs, they only + * check if the returned table is NULL instead of the returned status + * to determined if this function is succeeded. + */ + *OutTable = NULL; + + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + /* Walk the root table list */ for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) { - if (!ACPI_COMPARE_NAME ( - &(AcpiGbl_RootTableList.Tables[i].Signature), Signature)) + TableDesc = &AcpiGbl_RootTableList.Tables[i]; + + if (!ACPI_COMPARE_NAME (&TableDesc->Signature, Signature)) { continue; } @@ -343,19 +376,66 @@ AcpiGetTable ( continue; } - Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]); - if (ACPI_SUCCESS (Status)) + Status = AcpiTbGetTable (TableDesc, OutTable); + break; + } + + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + return (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiGetTable) + + +/******************************************************************************* + * + * FUNCTION: AcpiPutTable + * + * PARAMETERS: Table - The pointer to the table + * + * RETURN: None + * + * DESCRIPTION: Release a table returned by AcpiGetTable() and its clones. + * Note that it is not safe if this function was invoked after an + * uninstallation happened to the original table descriptor. + * Currently there is no OSPMs' requirement to handle such + * situations. + * + ******************************************************************************/ + +void +AcpiPutTable ( + ACPI_TABLE_HEADER *Table) +{ + UINT32 i; + ACPI_TABLE_DESC *TableDesc; + + + ACPI_FUNCTION_TRACE (AcpiPutTable); + + + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + + /* Walk the root table list */ + + for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) + { + TableDesc = &AcpiGbl_RootTableList.Tables[i]; + + if (TableDesc->Pointer != Table) { - *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer; + continue; } - return (Status); + AcpiTbPutTable (TableDesc); + break; } - return (AE_NOT_FOUND); + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + return_VOID; } -ACPI_EXPORT_SYMBOL (AcpiGetTable) +ACPI_EXPORT_SYMBOL (AcpiPutTable) /******************************************************************************* @@ -363,7 +443,7 @@ ACPI_EXPORT_SYMBOL (AcpiGetTable) * FUNCTION: AcpiGetTableByIndex * * PARAMETERS: TableIndex - Table index - * Table - Where the pointer to the table is returned + * OutTable - Where the pointer to the table is returned * * RETURN: Status and pointer to the requested table * @@ -375,7 +455,7 @@ ACPI_EXPORT_SYMBOL (AcpiGetTable) ACPI_STATUS AcpiGetTableByIndex ( UINT32 TableIndex, - ACPI_TABLE_HEADER **Table) + ACPI_TABLE_HEADER **OutTable) { ACPI_STATUS Status; @@ -385,37 +465,34 @@ AcpiGetTableByIndex ( /* Parameter validation */ - if (!Table) + if (!OutTable) { return_ACPI_STATUS (AE_BAD_PARAMETER); } + /* + * Note that the following line is required by some OSPMs, they only + * check if the returned table is NULL instead of the returned status + * to determined if this function is succeeded. + */ + *OutTable = NULL; + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); /* Validate index */ if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) { - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (AE_BAD_PARAMETER); + Status = AE_BAD_PARAMETER; + goto UnlockAndExit; } - if (!AcpiGbl_RootTableList.Tables[TableIndex].Pointer) - { - /* Table is not mapped, map it */ - - Status = AcpiTbValidateTable ( - &AcpiGbl_RootTableList.Tables[TableIndex]); - if (ACPI_FAILURE (Status)) - { - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (Status); - } - } + Status = AcpiTbGetTable ( + &AcpiGbl_RootTableList.Tables[TableIndex], OutTable); - *Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer; +UnlockAndExit: (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (AE_OK); + return_ACPI_STATUS (Status); } ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex) diff --git a/sys/contrib/dev/acpica/components/tables/tbxfload.c b/sys/contrib/dev/acpica/components/tables/tbxfload.c index 12af13182c36..871797583bfc 100644 --- a/sys/contrib/dev/acpica/components/tables/tbxfload.c +++ b/sys/contrib/dev/acpica/components/tables/tbxfload.c @@ -372,7 +372,7 @@ AcpiLoadTable ( /* Install the table and load it into the namespace */ ACPI_INFO (("Host-directed Dynamic ACPI Table Load:")); - Status = AcpiTbInstallAndLoadTable (Table, ACPI_PTR_TO_PHYSADDR (Table), + Status = AcpiTbInstallAndLoadTable (ACPI_PTR_TO_PHYSADDR (Table), ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, FALSE, &TableIndex); return_ACPI_STATUS (Status); } @@ -459,39 +459,8 @@ AcpiUnloadParentTable ( break; } - /* Ensure the table is actually loaded */ - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - if (!AcpiTbIsTableLoaded (i)) - { - Status = AE_NOT_EXIST; - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); - break; - } - - /* Invoke table handler if present */ - - if (AcpiGbl_TableHandler) - { - (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, - AcpiGbl_RootTableList.Tables[i].Pointer, - AcpiGbl_TableHandlerContext); - } - - /* - * Delete all namespace objects owned by this table. Note that - * these objects can appear anywhere in the namespace by virtue - * of the AML "Scope" operator. Thus, we need to track ownership - * by an ID, not simply a position within the hierarchy. - */ - Status = AcpiTbDeleteNamespaceByOwner (i); - if (ACPI_FAILURE (Status)) - { - break; - } - - Status = AcpiTbReleaseOwnerId (i); - AcpiTbSetTableLoadedFlag (i, FALSE); + Status = AcpiTbUnloadTable (i); (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); break; } diff --git a/sys/contrib/dev/acpica/components/utilities/utdecode.c b/sys/contrib/dev/acpica/components/utilities/utdecode.c index 8f8f06e862f2..237333f9efdf 100644 --- a/sys/contrib/dev/acpica/components/utilities/utdecode.c +++ b/sys/contrib/dev/acpica/components/utilities/utdecode.c @@ -44,6 +44,7 @@ #include <contrib/dev/acpica/include/acpi.h> #include <contrib/dev/acpica/include/accommon.h> #include <contrib/dev/acpica/include/acnamesp.h> +#include <contrib/dev/acpica/include/amlcode.h> #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME ("utdecode") @@ -604,6 +605,59 @@ AcpiUtGetNotifyName ( return ("Hardware-Specific"); } + + +/******************************************************************************* + * + * FUNCTION: AcpiUtGetArgumentTypeName + * + * PARAMETERS: ArgType - an ARGP_* parser argument type + * + * RETURN: Decoded ARGP_* type + * + * DESCRIPTION: Decode an ARGP_* parser type, as defined in the amlcode.h file, + * and used in the acopcode.h file. For example, ARGP_TERMARG. + * Used for debug only. + * + ******************************************************************************/ + +static const char *AcpiGbl_ArgumentType[20] = +{ + /* 00 */ "Unknown ARGP", + /* 01 */ "ByteData", + /* 02 */ "ByteList", + /* 03 */ "CharList", + /* 04 */ "DataObject", + /* 05 */ "DataObjectList", + /* 06 */ "DWordData", + /* 07 */ "FieldList", + /* 08 */ "Name", + /* 09 */ "NameString", + /* 0A */ "ObjectList", + /* 0B */ "PackageLength", + /* 0C */ "SuperName", + /* 0D */ "Target", + /* 0E */ "TermArg", + /* 0F */ "TermList", + /* 10 */ "WordData", + /* 11 */ "QWordData", + /* 12 */ "SimpleName", + /* 13 */ "NameOrRef" +}; + +const char * +AcpiUtGetArgumentTypeName ( + UINT32 ArgType) +{ + + if (ArgType > ARGP_MAX) + { + return ("Unknown ARGP"); + } + + return (AcpiGbl_ArgumentType[ArgType]); +} + #endif diff --git a/sys/contrib/dev/acpica/components/utilities/utresrc.c b/sys/contrib/dev/acpica/components/utilities/utresrc.c index 72ebf6565e47..f59d9754855c 100644 --- a/sys/contrib/dev/acpica/components/utilities/utresrc.c +++ b/sys/contrib/dev/acpica/components/utilities/utresrc.c @@ -468,9 +468,11 @@ AcpiUtWalkAmlResources ( ACPI_FUNCTION_TRACE (UtWalkAmlResources); - /* The absolute minimum resource template is one EndTag descriptor */ - - if (AmlLength < sizeof (AML_RESOURCE_END_TAG)) + /* + * The absolute minimum resource template is one EndTag descriptor. + * However, we will treat a lone EndTag as just a simple buffer. + */ + if (AmlLength <= sizeof (AML_RESOURCE_END_TAG)) { return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); } @@ -503,8 +505,8 @@ AcpiUtWalkAmlResources ( if (UserFunction) { - Status = UserFunction ( - Aml, Length, Offset, ResourceIndex, Context); + Status = UserFunction (Aml, Length, Offset, + ResourceIndex, Context); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); @@ -531,6 +533,13 @@ AcpiUtWalkAmlResources ( *Context = Aml; } + /* Check if buffer is defined to be longer than the resource length */ + + if (AmlLength > (Offset + Length)) + { + return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); + } + /* Normal exit */ return_ACPI_STATUS (AE_OK); |