Full support for ASL Mutex SyncLevel semantics and "ForceRelease" on

interpreter exit of all owned mutexes.


date	2001.02.16.18.30.00;	author rmoore1;	state Exp;
This commit is contained in:
aystarik 2005-06-29 17:36:25 +00:00
parent 6a1c191ed6
commit 02e2de9e34
2 changed files with 278 additions and 136 deletions

View File

@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: ammonad - ACPI AML (p-code) execution for monadic operators
* $Revision: 1.90 $
* $Revision: 1.91 $
*
*****************************************************************************/
@ -272,7 +272,7 @@ AcpiAmlExecMonadic1 (
case AML_RELEASE_OP:
Status = AcpiAmlSystemReleaseMutex (ObjDesc);
Status = AcpiAmlReleaseMutex (ObjDesc, WalkState);
break;

View File

@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: amdyadic - ACPI AML (p-code) execution for dyadic operators
* $Revision: 1.66 $
* $Revision: 1.72 $
*
*****************************************************************************/
@ -9,8 +9,8 @@
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999, Intel Corp. All rights
* reserved.
* Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
* All rights reserved.
*
* 2. License
*
@ -130,7 +130,183 @@
MODULE_NAME ("amdyadic")
/*****************************************************************************
/*******************************************************************************
*
* FUNCTION: AcpiAmlDoConcatenate
*
* PARAMETERS: *ObjDesc - Object to be converted. Must be an
* Integer, Buffer, or String
*
* RETURN: Status
*
* DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
*
******************************************************************************/
ACPI_STATUS
AcpiAmlDoConcatenate (
ACPI_OPERAND_OBJECT *ObjDesc,
ACPI_OPERAND_OBJECT *ObjDesc2,
ACPI_OPERAND_OBJECT **ActualRetDesc,
ACPI_WALK_STATE *WalkState)
{
ACPI_STATUS Status;
UINT32 i;
ACPI_INTEGER ThisInteger;
ACPI_OPERAND_OBJECT *RetDesc;
NATIVE_CHAR *NewBuf;
UINT32 IntegerSize = sizeof (ACPI_INTEGER);
/*
* There are three cases to handle:
* 1) Two Integers concatenated to produce a buffer
* 2) Two Strings concatenated to produce a string
* 3) Two Buffers concatenated to produce a buffer
*/
switch (ObjDesc->Common.Type)
{
case ACPI_TYPE_INTEGER:
/* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
if (WalkState->MethodNode->Flags & ANOBJ_DATA_WIDTH_32)
{
/*
* We are running a method that exists in a 32-bit ACPI table.
* Truncate the value to 32 bits by zeroing out the upper
* 32-bit field
*/
IntegerSize = sizeof (UINT32);
}
/* Result of two integers is a buffer */
RetDesc = AcpiCmCreateInternalObject (ACPI_TYPE_BUFFER);
if (!RetDesc)
{
return (AE_NO_MEMORY);
}
/* Need enough space for two integers */
RetDesc->Buffer.Length = IntegerSize * 2;
NewBuf = AcpiCmCallocate (RetDesc->Buffer.Length);
if (!NewBuf)
{
REPORT_ERROR
(("AmlExecDyadic2R/ConcatOp: Buffer allocation failure\n"));
Status = AE_NO_MEMORY;
goto Cleanup;
}
RetDesc->Buffer.Pointer = (UINT8 *) NewBuf;
/* Convert the first integer */
ThisInteger = ObjDesc->Integer.Value;
for (i = 0; i < IntegerSize; i++)
{
NewBuf[i] = (UINT8) ThisInteger;
ThisInteger >>= 8;
}
/* Convert the second integer */
ThisInteger = ObjDesc2->Integer.Value;
for (; i < (IntegerSize * 2); i++)
{
NewBuf[i] = (UINT8) ThisInteger;
ThisInteger >>= 8;
}
break;
case ACPI_TYPE_STRING:
RetDesc = AcpiCmCreateInternalObject (ACPI_TYPE_STRING);
if (!RetDesc)
{
return (AE_NO_MEMORY);
}
/* Operand1 is string */
NewBuf = AcpiCmAllocate (ObjDesc->String.Length +
ObjDesc2->String.Length + 1);
if (!NewBuf)
{
REPORT_ERROR
(("AmlExecDyadic2R/ConcatOp: String allocation failure\n"));
Status = AE_NO_MEMORY;
goto Cleanup;
}
STRCPY (NewBuf, ObjDesc->String.Pointer);
STRCPY (NewBuf + ObjDesc->String.Length,
ObjDesc2->String.Pointer);
/* Point the return object to the new string */
RetDesc->String.Pointer = NewBuf;
RetDesc->String.Length = ObjDesc->String.Length +=
ObjDesc2->String.Length;
break;
case ACPI_TYPE_BUFFER:
/* Operand1 is a buffer */
RetDesc = AcpiCmCreateInternalObject (ACPI_TYPE_BUFFER);
if (!RetDesc)
{
return (AE_NO_MEMORY);
}
NewBuf = AcpiCmAllocate (ObjDesc->Buffer.Length +
ObjDesc2->Buffer.Length);
if (!NewBuf)
{
REPORT_ERROR
(("AmlExecDyadic2R/ConcatOp: Buffer allocation failure\n"));
Status = AE_NO_MEMORY;
goto Cleanup;
}
MEMCPY (NewBuf, ObjDesc->Buffer.Pointer,
ObjDesc->Buffer.Length);
MEMCPY (NewBuf + ObjDesc->Buffer.Length, ObjDesc2->Buffer.Pointer,
ObjDesc2->Buffer.Length);
/*
* Point the return object to the new buffer
*/
RetDesc->Buffer.Pointer = (UINT8 *) NewBuf;
RetDesc->Buffer.Length = ObjDesc->Buffer.Length +
ObjDesc2->Buffer.Length;
break;
default:
Status = AE_AML_INTERNAL;
RetDesc = NULL;
}
*ActualRetDesc = RetDesc;
return (AE_OK);
Cleanup:
AcpiCmRemoveReference (RetDesc);
return (Status);
}
/*******************************************************************************
*
* FUNCTION: AcpiAmlExecDyadic1
*
@ -143,7 +319,7 @@
*
* ALLOCATION: Deletes both operands
*
****************************************************************************/
******************************************************************************/
ACPI_STATUS
AcpiAmlExecDyadic1 (
@ -174,7 +350,7 @@ AcpiAmlExecDyadic1 (
/* Invalid parameters on object stack */
DEBUG_PRINT (ACPI_ERROR,
("ExecDyadic1/%s: bad operand(s) (0x%X)\n",
("ExecDyadic1/%s: bad operand(s) (Status=%X)\n",
AcpiPsGetOpcodeName (Opcode), Status));
goto Cleanup;
@ -211,12 +387,12 @@ AcpiAmlExecDyadic1 (
/* Dispatch the notify to the appropriate handler */
AcpiEvNotifyDispatch (Node, (UINT32) ValDesc->Number.Value);
AcpiEvNotifyDispatch (Node, (UINT32) ValDesc->Integer.Value);
break;
default:
DEBUG_PRINT (ACPI_ERROR,
("AmlExecDyadic1/NotifyOp: unexpected notify object type %d\n",
("AmlExecDyadic1/NotifyOp: unexpected notify object type %X\n",
ObjDesc->Common.Type));
Status = AE_AML_OPERAND_TYPE;
@ -244,7 +420,7 @@ Cleanup:
}
/*****************************************************************************
/*******************************************************************************
*
* FUNCTION: AcpiAmlExecDyadic2R
*
@ -257,7 +433,7 @@ Cleanup:
*
* ALLOCATION: Deletes one operand descriptor -- other remains on stack
*
****************************************************************************/
******************************************************************************/
ACPI_STATUS
AcpiAmlExecDyadic2R (
@ -273,7 +449,6 @@ AcpiAmlExecDyadic2R (
ACPI_OPERAND_OBJECT *RetDesc2 = NULL;
ACPI_STATUS Status = AE_OK;
UINT32 NumOperands = 3;
NATIVE_CHAR *NewBuf;
FUNCTION_TRACE_U32 ("AmlExecDyadic2R", Opcode);
@ -299,7 +474,7 @@ AcpiAmlExecDyadic2R (
if (ACPI_FAILURE (Status))
{
DEBUG_PRINT (ACPI_ERROR,
("ExecDyadic2R/%s: bad operand(s) (0x%X)\n",
("ExecDyadic2R/%s: bad operand(s) (Status=%X)\n",
AcpiPsGetOpcodeName (Opcode), Status));
goto Cleanup;
@ -322,7 +497,7 @@ AcpiAmlExecDyadic2R (
case AML_SHIFT_RIGHT_OP:
case AML_SUBTRACT_OP:
RetDesc = AcpiCmCreateInternalObject (ACPI_TYPE_NUMBER);
RetDesc = AcpiCmCreateInternalObject (ACPI_TYPE_INTEGER);
if (!RetDesc)
{
Status = AE_NO_MEMORY;
@ -344,8 +519,8 @@ AcpiAmlExecDyadic2R (
case AML_ADD_OP:
RetDesc->Number.Value = ObjDesc->Number.Value +
ObjDesc2->Number.Value;
RetDesc->Integer.Value = ObjDesc->Integer.Value +
ObjDesc2->Integer.Value;
break;
@ -353,8 +528,8 @@ AcpiAmlExecDyadic2R (
case AML_BIT_AND_OP:
RetDesc->Number.Value = ObjDesc->Number.Value &
ObjDesc2->Number.Value;
RetDesc->Integer.Value = ObjDesc->Integer.Value &
ObjDesc2->Integer.Value;
break;
@ -362,8 +537,8 @@ AcpiAmlExecDyadic2R (
case AML_BIT_NAND_OP:
RetDesc->Number.Value = ~(ObjDesc->Number.Value &
ObjDesc2->Number.Value);
RetDesc->Integer.Value = ~(ObjDesc->Integer.Value &
ObjDesc2->Integer.Value);
break;
@ -371,8 +546,8 @@ AcpiAmlExecDyadic2R (
case AML_BIT_OR_OP:
RetDesc->Number.Value = ObjDesc->Number.Value |
ObjDesc2->Number.Value;
RetDesc->Integer.Value = ObjDesc->Integer.Value |
ObjDesc2->Integer.Value;
break;
@ -380,8 +555,8 @@ AcpiAmlExecDyadic2R (
case AML_BIT_NOR_OP:
RetDesc->Number.Value = ~(ObjDesc->Number.Value |
ObjDesc2->Number.Value);
RetDesc->Integer.Value = ~(ObjDesc->Integer.Value |
ObjDesc2->Integer.Value);
break;
@ -389,16 +564,16 @@ AcpiAmlExecDyadic2R (
case AML_BIT_XOR_OP:
RetDesc->Number.Value = ObjDesc->Number.Value ^
ObjDesc2->Number.Value;
RetDesc->Integer.Value = ObjDesc->Integer.Value ^
ObjDesc2->Integer.Value;
break;
/* DefDivide := DivideOp Dividend Divisor Remainder Quotient */
/* DefDivide := DivideOp Dividend Divisor Remainder Quotient */
case AML_DIVIDE_OP:
if (!ObjDesc2->Number.Value)
if (!ObjDesc2->Integer.Value)
{
REPORT_ERROR
(("AmlExecDyadic2R/DivideOp: Divide by zero\n"));
@ -407,7 +582,7 @@ AcpiAmlExecDyadic2R (
goto Cleanup;
}
RetDesc2 = AcpiCmCreateInternalObject (ACPI_TYPE_NUMBER);
RetDesc2 = AcpiCmCreateInternalObject (ACPI_TYPE_INTEGER);
if (!RetDesc2)
{
Status = AE_NO_MEMORY;
@ -416,13 +591,13 @@ AcpiAmlExecDyadic2R (
/* Remainder (modulo) */
RetDesc->Number.Value = ACPI_MODULO (ObjDesc->Number.Value,
ObjDesc2->Number.Value);
RetDesc->Integer.Value = ACPI_MODULO (ObjDesc->Integer.Value,
ObjDesc2->Integer.Value);
/* Result (what we used to call the quotient) */
RetDesc2->Number.Value = ACPI_DIVIDE (ObjDesc->Number.Value,
ObjDesc2->Number.Value);
RetDesc2->Integer.Value = ACPI_DIVIDE (ObjDesc->Integer.Value,
ObjDesc2->Integer.Value);
break;
@ -430,8 +605,8 @@ AcpiAmlExecDyadic2R (
case AML_MULTIPLY_OP:
RetDesc->Number.Value = ObjDesc->Number.Value *
ObjDesc2->Number.Value;
RetDesc->Integer.Value = ObjDesc->Integer.Value *
ObjDesc2->Integer.Value;
break;
@ -439,8 +614,8 @@ AcpiAmlExecDyadic2R (
case AML_SHIFT_LEFT_OP:
RetDesc->Number.Value = ObjDesc->Number.Value <<
ObjDesc2->Number.Value;
RetDesc->Integer.Value = ObjDesc->Integer.Value <<
ObjDesc2->Integer.Value;
break;
@ -448,8 +623,8 @@ AcpiAmlExecDyadic2R (
case AML_SHIFT_RIGHT_OP:
RetDesc->Number.Value = ObjDesc->Number.Value >>
ObjDesc2->Number.Value;
RetDesc->Integer.Value = ObjDesc->Integer.Value >>
ObjDesc2->Integer.Value;
break;
@ -457,8 +632,8 @@ AcpiAmlExecDyadic2R (
case AML_SUBTRACT_OP:
RetDesc->Number.Value = ObjDesc->Number.Value -
ObjDesc2->Number.Value;
RetDesc->Integer.Value = ObjDesc->Integer.Value -
ObjDesc2->Integer.Value;
break;
@ -466,89 +641,56 @@ AcpiAmlExecDyadic2R (
case AML_CONCAT_OP:
if (ObjDesc2->Common.Type != ObjDesc->Common.Type)
/*
* Convert the second operand if necessary. The first operand
* determines the type of the second operand, (See the Data Types
* section of the ACPI specification.) Both object types are
* guaranteed to be either Integer/String/Buffer by the operand
* resolution mechanism above.
*/
switch (ObjDesc->Common.Type)
{
case ACPI_TYPE_INTEGER:
Status = AcpiAmlConvertToInteger (&ObjDesc2, WalkState);
break;
case ACPI_TYPE_STRING:
Status = AcpiAmlConvertToString (&ObjDesc2, WalkState);
break;
case ACPI_TYPE_BUFFER:
Status = AcpiAmlConvertToBuffer (&ObjDesc2, WalkState);
break;
default:
Status = AE_AML_INTERNAL;
}
if (ACPI_FAILURE (Status))
{
DEBUG_PRINT (ACPI_ERROR,
("AmlExecDyadic2R/ConcatOp: operand type mismatch %d %d\n",
ObjDesc->Common.Type, ObjDesc2->Common.Type));
Status = AE_AML_OPERAND_TYPE;
goto Cleanup;
}
/* Both operands are now known to be the same */
if (ACPI_TYPE_STRING == ObjDesc->Common.Type)
/*
* Both operands are now known to be the same object type
* (Both are Integer, String, or Buffer), and we can now perform the
* concatenation.
*/
Status = AcpiAmlDoConcatenate (ObjDesc, ObjDesc2, &RetDesc, WalkState);
if (ACPI_FAILURE (Status))
{
RetDesc = AcpiCmCreateInternalObject (ACPI_TYPE_STRING);
if (!RetDesc)
{
Status = AE_NO_MEMORY;
goto Cleanup;
}
/* Operand1 is string */
NewBuf = AcpiCmAllocate (ObjDesc->String.Length +
ObjDesc2->String.Length + 1);
if (!NewBuf)
{
REPORT_ERROR
(("AmlExecDyadic2R/ConcatOp: String allocation failure\n"));
Status = AE_NO_MEMORY;
goto Cleanup;
}
STRCPY (NewBuf, ObjDesc->String.Pointer);
STRCPY (NewBuf + ObjDesc->String.Length,
ObjDesc2->String.Pointer);
/* Point the return object to the new string */
RetDesc->String.Pointer = NewBuf;
RetDesc->String.Length = ObjDesc->String.Length +=
ObjDesc2->String.Length;
}
else
{
/* Operand1 is not a string ==> must be a buffer */
RetDesc = AcpiCmCreateInternalObject (ACPI_TYPE_BUFFER);
if (!RetDesc)
{
Status = AE_NO_MEMORY;
goto Cleanup;
}
NewBuf = AcpiCmAllocate (ObjDesc->Buffer.Length +
ObjDesc2->Buffer.Length);
if (!NewBuf)
{
REPORT_ERROR
(("AmlExecDyadic2R/ConcatOp: Buffer allocation failure\n"));
Status = AE_NO_MEMORY;
goto Cleanup;
}
MEMCPY (NewBuf, ObjDesc->Buffer.Pointer,
ObjDesc->Buffer.Length);
MEMCPY (NewBuf + ObjDesc->Buffer.Length, ObjDesc2->Buffer.Pointer,
ObjDesc2->Buffer.Length);
/*
* Point the return object to the new buffer
*/
RetDesc->Buffer.Pointer = (UINT8 *) NewBuf;
RetDesc->Buffer.Length = ObjDesc->Buffer.Length +
ObjDesc2->Buffer.Length;
goto Cleanup;
}
break;
default:
REPORT_ERROR (("AcpiAmlExecDyadic2R: Unknown dyadic opcode %X\n", Opcode));
REPORT_ERROR (("AcpiAmlExecDyadic2R: Unknown dyadic opcode %X\n",
Opcode));
Status = AE_AML_BAD_OPCODE;
goto Cleanup;
}
@ -612,7 +754,7 @@ Cleanup:
}
/*****************************************************************************
/*******************************************************************************
*
* FUNCTION: AcpiAmlExecDyadic2S
*
@ -624,7 +766,7 @@ Cleanup:
*
* ALLOCATION: Deletes one operand descriptor -- other remains on stack
*
****************************************************************************/
******************************************************************************/
ACPI_STATUS
AcpiAmlExecDyadic2S (
@ -656,7 +798,7 @@ AcpiAmlExecDyadic2S (
/* Invalid parameters on object stack */
DEBUG_PRINT (ACPI_ERROR,
("ExecDyadic2S/%s: bad operand(s) (0x%X)\n",
("ExecDyadic2S/%s: bad operand(s) (Status=%X)\n",
AcpiPsGetOpcodeName (Opcode), Status));
goto Cleanup;
@ -665,7 +807,7 @@ AcpiAmlExecDyadic2S (
/* Create the internal return object */
RetDesc = AcpiCmCreateInternalObject (ACPI_TYPE_NUMBER);
RetDesc = AcpiCmCreateInternalObject (ACPI_TYPE_INTEGER);
if (!RetDesc)
{
Status = AE_NO_MEMORY;
@ -674,7 +816,7 @@ AcpiAmlExecDyadic2S (
/* Default return value is FALSE, operation did not time out */
RetDesc->Number.Value = 0;
RetDesc->Integer.Value = 0;
/* Examine the opcode */
@ -686,7 +828,7 @@ AcpiAmlExecDyadic2S (
case AML_ACQUIRE_OP:
Status = AcpiAmlSystemAcquireMutex (TimeDesc, ObjDesc);
Status = AcpiAmlAcquireMutex (TimeDesc, ObjDesc, WalkState);
break;
@ -713,7 +855,7 @@ AcpiAmlExecDyadic2S (
if (Status == AE_TIME)
{
RetDesc->Number.Value = ACPI_INTEGER_MAX; /* TRUE, op timed out */
RetDesc->Integer.Value = ACPI_INTEGER_MAX; /* TRUE, op timed out */
Status = AE_OK;
}
@ -742,7 +884,7 @@ Cleanup:
}
/*****************************************************************************
/*******************************************************************************
*
* FUNCTION: AcpiAmlExecDyadic2
*
@ -756,7 +898,7 @@ Cleanup:
* ALLOCATION: Deletes one operand descriptor -- other remains on stack
* containing result value
*
****************************************************************************/
******************************************************************************/
ACPI_STATUS
AcpiAmlExecDyadic2 (
@ -789,7 +931,7 @@ AcpiAmlExecDyadic2 (
/* Invalid parameters on object stack */
DEBUG_PRINT (ACPI_ERROR,
("ExecDyadic2/%s: bad operand(s) (0x%X)\n",
("ExecDyadic2/%s: bad operand(s) (Status=%X)\n",
AcpiPsGetOpcodeName (Opcode), Status));
goto Cleanup;
@ -798,7 +940,7 @@ AcpiAmlExecDyadic2 (
/* Create the internal return object */
RetDesc = AcpiCmCreateInternalObject (ACPI_TYPE_NUMBER);
RetDesc = AcpiCmCreateInternalObject (ACPI_TYPE_INTEGER);
if (!RetDesc)
{
Status = AE_NO_MEMORY;
@ -817,8 +959,8 @@ AcpiAmlExecDyadic2 (
case AML_LAND_OP:
Lboolean = (BOOLEAN) (ObjDesc->Number.Value &&
ObjDesc2->Number.Value);
Lboolean = (BOOLEAN) (ObjDesc->Integer.Value &&
ObjDesc2->Integer.Value);
break;
@ -826,8 +968,8 @@ AcpiAmlExecDyadic2 (
case AML_LEQUAL_OP:
Lboolean = (BOOLEAN) (ObjDesc->Number.Value ==
ObjDesc2->Number.Value);
Lboolean = (BOOLEAN) (ObjDesc->Integer.Value ==
ObjDesc2->Integer.Value);
break;
@ -835,8 +977,8 @@ AcpiAmlExecDyadic2 (
case AML_LGREATER_OP:
Lboolean = (BOOLEAN) (ObjDesc->Number.Value >
ObjDesc2->Number.Value);
Lboolean = (BOOLEAN) (ObjDesc->Integer.Value >
ObjDesc2->Integer.Value);
break;
@ -844,8 +986,8 @@ AcpiAmlExecDyadic2 (
case AML_LLESS_OP:
Lboolean = (BOOLEAN) (ObjDesc->Number.Value <
ObjDesc2->Number.Value);
Lboolean = (BOOLEAN) (ObjDesc->Integer.Value <
ObjDesc2->Integer.Value);
break;
@ -853,8 +995,8 @@ AcpiAmlExecDyadic2 (
case AML_LOR_OP:
Lboolean = (BOOLEAN) (ObjDesc->Number.Value ||
ObjDesc2->Number.Value);
Lboolean = (BOOLEAN) (ObjDesc->Integer.Value ||
ObjDesc2->Integer.Value);
break;
@ -871,11 +1013,11 @@ AcpiAmlExecDyadic2 (
if (Lboolean)
{
RetDesc->Number.Value = ACPI_INTEGER_MAX;
RetDesc->Integer.Value = ACPI_INTEGER_MAX;
}
else
{
RetDesc->Number.Value = 0;
RetDesc->Integer.Value = 0;
}