diff options
Diffstat (limited to 'sys/contrib/dev/acpica/exoparg1.c')
-rw-r--r-- | sys/contrib/dev/acpica/exoparg1.c | 219 |
1 files changed, 174 insertions, 45 deletions
diff --git a/sys/contrib/dev/acpica/exoparg1.c b/sys/contrib/dev/acpica/exoparg1.c index d52f945..56d98e1 100644 --- a/sys/contrib/dev/acpica/exoparg1.c +++ b/sys/contrib/dev/acpica/exoparg1.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: exoparg1 - AML execution - opcodes with 1 argument - * $Revision: 152 $ + * $Revision: 163 $ * *****************************************************************************/ @@ -141,7 +141,7 @@ * Where: * * xA - ARGUMENTS: The number of arguments (input operands) that are - * required for this opcode type (1 through 6 args). + * required for this opcode type (0 through 6 args). * yT - TARGETS: The number of targets (output operands) that are required * for this opcode type (0, 1, or 2 targets). * zR - RETURN VALUE: Indicates whether this opcode type returns a value @@ -153,6 +153,73 @@ /******************************************************************************* * + * FUNCTION: AcpiExOpcode_0A_0T_1R + * + * PARAMETERS: WalkState - Current state (contains AML opcode) + * + * RETURN: Status + * + * DESCRIPTION: Execute operator with no operands, one return value + * + ******************************************************************************/ + +ACPI_STATUS +AcpiExOpcode_0A_0T_1R ( + ACPI_WALK_STATE *WalkState) +{ + ACPI_STATUS Status = AE_OK; + ACPI_OPERAND_OBJECT *ReturnDesc = NULL; + + + ACPI_FUNCTION_TRACE_STR ("ExOpcode_0A_0T_1R", AcpiPsGetOpcodeName (WalkState->Opcode)); + + + /* Examine the AML opcode */ + + switch (WalkState->Opcode) + { + case AML_TIMER_OP: /* Timer () */ + + /* Create a return object of type Integer */ + + ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + if (!ReturnDesc) + { + Status = AE_NO_MEMORY; + goto Cleanup; + } + + ReturnDesc->Integer.Value = AcpiOsGetTimer (); + break; + + default: /* Unknown opcode */ + + ACPI_REPORT_ERROR (("AcpiExOpcode_0A_0T_1R: Unknown opcode %X\n", + WalkState->Opcode)); + Status = AE_AML_BAD_OPCODE; + break; + } + +Cleanup: + + if (!WalkState->ResultObj) + { + WalkState->ResultObj = ReturnDesc; + } + + /* Delete return object on error */ + + if (ACPI_FAILURE (Status)) + { + AcpiUtRemoveReference (ReturnDesc); + } + + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * * FUNCTION: AcpiExOpcode_1A_0T_0R * * PARAMETERS: WalkState - Current state (contains AML opcode) @@ -199,7 +266,7 @@ AcpiExOpcode_1A_0T_0R ( case AML_SLEEP_OP: /* Sleep (MsecTime) */ - Status = AcpiExSystemDoSuspend ((UINT32) Operand[0]->Integer.Value); + Status = AcpiExSystemDoSuspend (Operand[0]->Integer.Value); break; @@ -298,7 +365,7 @@ AcpiExOpcode_1A_1T_1R ( ACPI_OPERAND_OBJECT *ReturnDesc2 = NULL; UINT32 Temp32; UINT32 i; - UINT32 PowerOfTen; + ACPI_INTEGER PowerOfTen; ACPI_INTEGER Digit; @@ -341,7 +408,8 @@ AcpiExOpcode_1A_1T_1R ( * Acpi specification describes Integer type as a little * endian unsigned value, so this boundary condition is valid. */ - for (Temp32 = 0; ReturnDesc->Integer.Value && Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32) + for (Temp32 = 0; ReturnDesc->Integer.Value && + Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32) { ReturnDesc->Integer.Value >>= 1; } @@ -358,14 +426,16 @@ AcpiExOpcode_1A_1T_1R ( * The Acpi specification describes Integer type as a little * endian unsigned value, so this boundary condition is valid. */ - for (Temp32 = 0; ReturnDesc->Integer.Value && Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32) + for (Temp32 = 0; ReturnDesc->Integer.Value && + Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32) { ReturnDesc->Integer.Value <<= 1; } /* Since the bit position is one-based, subtract from 33 (65) */ - ReturnDesc->Integer.Value = Temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - Temp32; + ReturnDesc->Integer.Value = Temp32 == 0 ? 0 : + (ACPI_INTEGER_BIT_SIZE + 1) - Temp32; break; @@ -402,7 +472,8 @@ AcpiExOpcode_1A_1T_1R ( /* Sum the digit into the result with the current power of 10 */ - ReturnDesc->Integer.Value += (((ACPI_INTEGER) Temp32) * PowerOfTen); + ReturnDesc->Integer.Value += (((ACPI_INTEGER) Temp32) * + PowerOfTen); /* Shift to next BCD digit */ @@ -424,19 +495,21 @@ AcpiExOpcode_1A_1T_1R ( for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++) { - (void) AcpiUtShortDivide (&Digit, 10, &Digit, &Temp32); + (void) AcpiUtShortDivide (Digit, 10, &Digit, &Temp32); /* Insert the BCD digit that resides in the remainder from above */ - ReturnDesc->Integer.Value |= (((ACPI_INTEGER) Temp32) << (i * 4)); + ReturnDesc->Integer.Value |= (((ACPI_INTEGER) Temp32) << + ACPI_MUL_4 (i)); } /* Overflow if there is any data left in Digit */ if (Digit > 0) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Integer too large to convert to BCD: %8.8X%8.8X\n", - ACPI_FORMAT_UINT64 (Operand[0]->Integer.Value))); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Integer too large to convert to BCD: %8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (Operand[0]->Integer.Value))); Status = AE_AML_NUMERIC_OVERFLOW; goto Cleanup; } @@ -518,42 +591,47 @@ AcpiExOpcode_1A_1T_1R ( */ case AML_COPY_OP: /* Copy (Source, Target) */ - Status = AcpiUtCopyIobjectToIobject (Operand[0], &ReturnDesc, WalkState); + Status = AcpiUtCopyIobjectToIobject (Operand[0], &ReturnDesc, + WalkState); break; case AML_TO_DECSTRING_OP: /* ToDecimalString (Data, Result) */ - Status = AcpiExConvertToString (Operand[0], &ReturnDesc, 10, ACPI_UINT32_MAX, WalkState); + Status = AcpiExConvertToString (Operand[0], &ReturnDesc, + ACPI_EXPLICIT_CONVERT_DECIMAL); break; case AML_TO_HEXSTRING_OP: /* ToHexString (Data, Result) */ - Status = AcpiExConvertToString (Operand[0], &ReturnDesc, 16, ACPI_UINT32_MAX, WalkState); + Status = AcpiExConvertToString (Operand[0], &ReturnDesc, + ACPI_EXPLICIT_CONVERT_HEX); break; case AML_TO_BUFFER_OP: /* ToBuffer (Data, Result) */ - Status = AcpiExConvertToBuffer (Operand[0], &ReturnDesc, WalkState); + Status = AcpiExConvertToBuffer (Operand[0], &ReturnDesc); break; case AML_TO_INTEGER_OP: /* ToInteger (Data, Result) */ - Status = AcpiExConvertToInteger (Operand[0], &ReturnDesc, WalkState); + Status = AcpiExConvertToInteger (Operand[0], &ReturnDesc, + ACPI_ANY_BASE); break; - case AML_SHIFT_LEFT_BIT_OP: /* ShiftLeftBit (Source, BitNum) */ - case AML_SHIFT_RIGHT_BIT_OP: /* ShiftRightBit (Source, BitNum) */ + case AML_SHIFT_LEFT_BIT_OP: /* ShiftLeftBit (Source, BitNum) */ + case AML_SHIFT_RIGHT_BIT_OP: /* ShiftRightBit (Source, BitNum) */ /* * These are two obsolete opcodes */ - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s is obsolete and not implemented\n", - AcpiPsGetOpcodeName (WalkState->Opcode))); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "%s is obsolete and not implemented\n", + AcpiPsGetOpcodeName (WalkState->Opcode))); Status = AE_SUPPORT; goto Cleanup; @@ -630,7 +708,14 @@ AcpiExOpcode_1A_0T_1R ( goto Cleanup; } - ReturnDesc->Integer.Value = !Operand[0]->Integer.Value; + /* + * Set result to ONES (TRUE) if Value == 0. Note: + * ReturnDesc->Integer.Value is initially == 0 (FALSE) from above. + */ + if (!Operand[0]->Integer.Value) + { + ReturnDesc->Integer.Value = ACPI_INTEGER_MAX; + } break; @@ -638,51 +723,79 @@ AcpiExOpcode_1A_0T_1R ( case AML_INCREMENT_OP: /* Increment (Operand) */ /* - * Since we are expecting a Reference operand, it - * can be either a NS Node or an internal object. + * Create a new integer. Can't just get the base integer and + * increment it because it may be an Arg or Field. */ - ReturnDesc = Operand[0]; - if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_OPERAND) + ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + if (!ReturnDesc) + { + Status = AE_NO_MEMORY; + goto Cleanup; + } + + /* + * Since we are expecting a Reference operand, it can be either a + * NS Node or an internal object. + */ + TempDesc = Operand[0]; + if (ACPI_GET_DESCRIPTOR_TYPE (TempDesc) == ACPI_DESC_TYPE_OPERAND) { /* Internal reference object - prevent deletion */ - AcpiUtAddReference (ReturnDesc); + AcpiUtAddReference (TempDesc); } /* - * Convert the ReturnDesc Reference to a Number - * (This removes a reference on the ReturnDesc object) + * Convert the Reference operand to an Integer (This removes a + * reference on the Operand[0] object) + * + * NOTE: We use LNOT_OP here in order to force resolution of the + * reference operand to an actual integer. */ - Status = AcpiExResolveOperands (AML_LNOT_OP, &ReturnDesc, WalkState); + Status = AcpiExResolveOperands (AML_LNOT_OP, &TempDesc, WalkState); if (ACPI_FAILURE (Status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %s\n", - AcpiPsGetOpcodeName (WalkState->Opcode), AcpiFormatException(Status))); + AcpiPsGetOpcodeName (WalkState->Opcode), + AcpiFormatException(Status))); goto Cleanup; } /* - * ReturnDesc is now guaranteed to be an Integer object - * Do the actual increment or decrement + * TempDesc is now guaranteed to be an Integer object -- + * Perform the actual increment or decrement */ - if (AML_INCREMENT_OP == WalkState->Opcode) + if (WalkState->Opcode == AML_INCREMENT_OP) { - ReturnDesc->Integer.Value++; + ReturnDesc->Integer.Value = TempDesc->Integer.Value +1; } else { - ReturnDesc->Integer.Value--; + ReturnDesc->Integer.Value = TempDesc->Integer.Value -1; } - /* Store the result back in the original descriptor */ + /* Finished with this Integer object */ + + AcpiUtRemoveReference (TempDesc); + /* + * Store the result back (indirectly) through the original + * Reference object + */ Status = AcpiExStore (ReturnDesc, Operand[0], WalkState); break; case AML_TYPE_OP: /* ObjectType (SourceObject) */ + /* + * Note: The operand is not resolved at this point because we want to + * get the associated object, not its value. For example, we don't want + * to resolve a FieldUnit to its value, we want the actual FieldUnit + * object. + */ + /* Get the type of the base object */ Status = AcpiExResolveMultiple (WalkState, Operand[0], &Type, NULL); @@ -690,7 +803,6 @@ AcpiExOpcode_1A_0T_1R ( { goto Cleanup; } - /* Allocate a descriptor to hold the type. */ ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); @@ -706,6 +818,11 @@ AcpiExOpcode_1A_0T_1R ( case AML_SIZE_OF_OP: /* SizeOf (SourceObject) */ + /* + * Note: The operand is not resolved at this point because we want to + * get the associated object, not its value. + */ + /* Get the base object */ Status = AcpiExResolveMultiple (WalkState, Operand[0], &Type, &TempDesc); @@ -715,12 +832,20 @@ AcpiExOpcode_1A_0T_1R ( } /* - * Type is guaranteed to be a buffer, string, or package at this - * point (even if the original operand was an object reference, it - * will be resolved and typechecked during operand resolution.) + * The type of the base object must be integer, buffer, string, or + * package. All others are not supported. + * + * NOTE: Integer is not specifically supported by the ACPI spec, + * but is supported implicitly via implicit operand conversion. + * rather than bother with conversion, we just use the byte width + * global (4 or 8 bytes). */ switch (Type) { + case ACPI_TYPE_INTEGER: + Value = AcpiGbl_IntegerByteWidth; + break; + case ACPI_TYPE_BUFFER: Value = TempDesc->Buffer.Length; break; @@ -734,7 +859,8 @@ AcpiExOpcode_1A_0T_1R ( break; default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "SizeOf, Not Buf/Str/Pkg - found type %s\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "SizeOf - Operand is not Buf/Int/Str/Pkg - found type %s\n", AcpiUtGetTypeName (Type))); Status = AE_AML_OPERAND_TYPE; goto Cleanup; @@ -917,7 +1043,8 @@ AcpiExOpcode_1A_0T_1R ( * an uninitialized package element and is thus a * severe error. */ - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "NULL package element obj %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "NULL package element obj %p\n", Operand[0])); Status = AE_AML_UNINITIALIZED_ELEMENT; goto Cleanup; @@ -929,7 +1056,8 @@ AcpiExOpcode_1A_0T_1R ( default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Index TargetType %X in obj %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Unknown Index TargetType %X in obj %p\n", Operand[0]->Reference.TargetType, Operand[0])); Status = AE_AML_OPERAND_TYPE; goto Cleanup; @@ -954,7 +1082,8 @@ AcpiExOpcode_1A_0T_1R ( default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode in ref(%p) - %X\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Unknown opcode in ref(%p) - %X\n", Operand[0], Operand[0]->Reference.Opcode)); Status = AE_TYPE; |