diff options
Diffstat (limited to 'sys/contrib/dev/acpica/exconfig.c')
-rw-r--r-- | sys/contrib/dev/acpica/exconfig.c | 388 |
1 files changed, 308 insertions, 80 deletions
diff --git a/sys/contrib/dev/acpica/exconfig.c b/sys/contrib/dev/acpica/exconfig.c index f8c1a1c..0908575 100644 --- a/sys/contrib/dev/acpica/exconfig.c +++ b/sys/contrib/dev/acpica/exconfig.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes) - * $Revision: 47 $ + * $Revision: 59 $ * *****************************************************************************/ @@ -9,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp. * All rights reserved. * * 2. License @@ -128,156 +128,385 @@ #define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exconfig") + ACPI_MODULE_NAME ("exconfig") -/***************************************************************************** +/******************************************************************************* + * + * FUNCTION: AcpiExAddTable + * + * PARAMETERS: Table - Pointer to raw table + * ParentNode - Where to load the table (scope) + * DdbHandle - Where to return the table handle. + * + * RETURN: Status + * + * DESCRIPTION: Common function to Install and Load an ACPI table with a + * returned table handle. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiExAddTable ( + ACPI_TABLE_HEADER *Table, + ACPI_NAMESPACE_NODE *ParentNode, + ACPI_OPERAND_OBJECT **DdbHandle) +{ + ACPI_STATUS Status; + ACPI_TABLE_DESC TableInfo; + ACPI_OPERAND_OBJECT *ObjDesc; + + + ACPI_FUNCTION_TRACE ("ExAddTable"); + + + /* Create an object to be the table handle */ + + ObjDesc = AcpiUtCreateInternalObject (INTERNAL_TYPE_REFERENCE); + if (!ObjDesc) + { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* Install the new table into the local data structures */ + + TableInfo.Pointer = Table; + TableInfo.Length = Table->Length; + TableInfo.Allocation = ACPI_MEM_ALLOCATED; + TableInfo.BasePointer = Table; + + Status = AcpiTbInstallTable (NULL, &TableInfo); + if (ACPI_FAILURE (Status)) + { + goto Cleanup; + } + + /* Add the table to the namespace */ + + Status = AcpiNsLoadTable (TableInfo.InstalledDesc, ParentNode); + if (ACPI_FAILURE (Status)) + { + /* Uninstall table on error */ + + AcpiTbUninstallTable (TableInfo.InstalledDesc); + goto Cleanup; + } + + /* Init the table handle */ + + ObjDesc->Reference.Opcode = AML_LOAD_OP; + ObjDesc->Reference.Object = TableInfo.InstalledDesc; + *DdbHandle = ObjDesc; + return_ACPI_STATUS (AE_OK); + + +Cleanup: + AcpiUtRemoveReference (ObjDesc); + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* * * FUNCTION: AcpiExLoadTableOp * - * PARAMETERS: RgnDesc - Op region where the table will be obtained - * DdbHandle - Where a handle to the table will be returned + * PARAMETERS: WalkState - Current state with operands + * ReturnDesc - Where to store the return object * * RETURN: Status * * DESCRIPTION: Load an ACPI table * - ****************************************************************************/ + ******************************************************************************/ ACPI_STATUS -AcpiExLoadOp ( - ACPI_OPERAND_OBJECT *RgnDesc, - ACPI_OPERAND_OBJECT *DdbHandle) +AcpiExLoadTableOp ( + ACPI_WALK_STATE *WalkState, + ACPI_OPERAND_OBJECT **ReturnDesc) { ACPI_STATUS Status; - ACPI_OPERAND_OBJECT *TableDesc = NULL; - UINT8 *TablePtr; - UINT8 *TableDataPtr; - ACPI_TABLE_HEADER TableHeader; - ACPI_TABLE_DESC TableInfo; - UINT32 i; + ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; + ACPI_TABLE_HEADER *Table; + ACPI_NAMESPACE_NODE *ParentNode; + ACPI_NAMESPACE_NODE *StartNode; + ACPI_NAMESPACE_NODE *ParameterNode = NULL; + ACPI_OPERAND_OBJECT *DdbHandle; + + + ACPI_FUNCTION_TRACE ("ExLoadTableOp"); + + + /* + * Make sure that the signature does not match one of the tables that + * is already loaded. + */ + Status = AcpiTbMatchSignature (Operand[0]->String.Pointer, NULL); + if (Status == AE_OK) + { + /* Signature matched -- don't allow override */ + + return_ACPI_STATUS (AE_ALREADY_EXISTS); + } + + /* Find the ACPI table */ + + Status = AcpiTbFindTable (Operand[0]->String.Pointer, + Operand[1]->String.Pointer, + Operand[2]->String.Pointer, &Table); + if (ACPI_FAILURE (Status)) + { + if (Status != AE_NOT_FOUND) + { + return_ACPI_STATUS (Status); + } + /* Not found, return an Integer=0 and AE_OK */ - FUNCTION_TRACE ("ExLoadOp"); + DdbHandle = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + if (!DdbHandle) + { + return_ACPI_STATUS (AE_NO_MEMORY); + } - /* Object can be either a field or an opregion */ + DdbHandle->Integer.Value = 0; + *ReturnDesc = DdbHandle; - /* TBD: Handle field vs. Opregion *? + return_ACPI_STATUS (AE_OK); + } + /* Default nodes */ - /* Get the table header */ + StartNode = WalkState->ScopeInfo->Scope.Node; + ParentNode = AcpiGbl_RootNode; - TableHeader.Length = 0; - for (i = 0; i < sizeof (ACPI_TABLE_HEADER); i++) + /* RootPath (optional parameter) */ + + if (Operand[3]->String.Length > 0) { - Status = AcpiEvAddressSpaceDispatch (RgnDesc, ACPI_READ, - (ACPI_PHYSICAL_ADDRESS) i, 8, - (ACPI_INTEGER *) ((UINT8 *) &TableHeader + i)); + /* + * Find the node referenced by the RootPathString. This is the + * location within the namespace where the table will be loaded. + */ + Status = AcpiNsGetNodeByPath (Operand[3]->String.Pointer, StartNode, + ACPI_NS_SEARCH_PARENT, &ParentNode); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } - /* Allocate a buffer for the entire table */ + /* ParameterPath (optional parameter) */ - TablePtr = ACPI_MEM_ALLOCATE (TableHeader.Length); - if (!TablePtr) + if (Operand[4]->String.Length > 0) { - return_ACPI_STATUS (AE_NO_MEMORY); + if ((Operand[4]->String.Pointer[0] != '\\') && + (Operand[4]->String.Pointer[0] != '^')) + { + /* + * Path is not absolute, so it will be relative to the node + * referenced by the RootPathString (or the NS root if omitted) + */ + StartNode = ParentNode; + } + + /* + * Find the node referenced by the ParameterPathString + */ + Status = AcpiNsGetNodeByPath (Operand[4]->String.Pointer, StartNode, + ACPI_NS_SEARCH_PARENT, &ParameterNode); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + } + + /* Load the table into the namespace */ + + Status = AcpiExAddTable (Table, ParentNode, &DdbHandle); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + /* Parameter Data (optional) */ + + if (ParameterNode) + { + /* Store the parameter data into the optional parameter object */ + + Status = AcpiExStore (Operand[5], (ACPI_OPERAND_OBJECT *) ParameterNode, + WalkState); + if (ACPI_FAILURE (Status)) + { + AcpiExUnloadTable (DdbHandle); + } } - /* Copy the header to the buffer */ + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiExLoadOp + * + * PARAMETERS: ObjDesc - Region or Field where the table will be + * obtained + * Target - Where a handle to the table will be stored + * WalkState - Current state + * + * RETURN: Status + * + * DESCRIPTION: Load an ACPI table from a field or operation region + * + ******************************************************************************/ + +ACPI_STATUS +AcpiExLoadOp ( + ACPI_OPERAND_OBJECT *ObjDesc, + ACPI_OPERAND_OBJECT *Target, + ACPI_WALK_STATE *WalkState) +{ + ACPI_STATUS Status; + ACPI_OPERAND_OBJECT *DdbHandle; + ACPI_OPERAND_OBJECT *BufferDesc = NULL; + ACPI_TABLE_HEADER *TablePtr = NULL; + UINT8 *TableDataPtr; + ACPI_TABLE_HEADER TableHeader; + UINT32 i; + - MEMCPY (TablePtr, &TableHeader, sizeof (ACPI_TABLE_HEADER)); - TableDataPtr = TablePtr + sizeof (ACPI_TABLE_HEADER); + ACPI_FUNCTION_TRACE ("ExLoadOp"); - /* Get the table from the op region */ + /* Object can be either an OpRegion or a Field */ - for (i = 0; i < TableHeader.Length; i++) + switch (ACPI_GET_OBJECT_TYPE (ObjDesc)) { - Status = AcpiEvAddressSpaceDispatch (RgnDesc, ACPI_READ, - (ACPI_PHYSICAL_ADDRESS) i, 8, - (ACPI_INTEGER *) (TableDataPtr + i)); + case ACPI_TYPE_REGION: + + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Region %p %s\n", + ObjDesc, AcpiUtGetTypeName (ObjDesc->Common.Type))); + + /* Get the table header */ + + TableHeader.Length = 0; + for (i = 0; i < sizeof (ACPI_TABLE_HEADER); i++) + { + Status = AcpiEvAddressSpaceDispatch (ObjDesc, ACPI_READ, + (ACPI_PHYSICAL_ADDRESS) i, 8, + (ACPI_INTEGER *) ((UINT8 *) &TableHeader + i)); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + } + + /* Allocate a buffer for the entire table */ + + TablePtr = ACPI_MEM_ALLOCATE (TableHeader.Length); + if (!TablePtr) + { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* Copy the header to the buffer */ + + ACPI_MEMCPY (TablePtr, &TableHeader, sizeof (ACPI_TABLE_HEADER)); + TableDataPtr = ACPI_PTR_ADD (UINT8, TablePtr, sizeof (ACPI_TABLE_HEADER)); + + /* Get the table from the op region */ + + for (i = 0; i < TableHeader.Length; i++) + { + Status = AcpiEvAddressSpaceDispatch (ObjDesc, ACPI_READ, + (ACPI_PHYSICAL_ADDRESS) i, 8, + (ACPI_INTEGER *) (TableDataPtr + i)); + if (ACPI_FAILURE (Status)) + { + goto Cleanup; + } + } + break; + + + case ACPI_TYPE_BUFFER_FIELD: + case INTERNAL_TYPE_REGION_FIELD: + case INTERNAL_TYPE_BANK_FIELD: + case INTERNAL_TYPE_INDEX_FIELD: + + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Field %p %s\n", + ObjDesc, AcpiUtGetTypeName (ObjDesc->Common.Type))); + + /* + * The length of the field must be at least as large as the table. + * Read the entire field and thus the entire table. Buffer is + * allocated during the read. + */ + Status = AcpiExReadDataFromField (ObjDesc, &BufferDesc); if (ACPI_FAILURE (Status)) { goto Cleanup; } + + TablePtr = (ACPI_TABLE_HEADER *) BufferDesc->Buffer.Pointer; + break; + + + default: + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } - /* Table must be either an SSDT or a PSDT */ + /* The table must be either an SSDT or a PSDT */ - if ((!STRNCMP (TableHeader.Signature, + if ((!ACPI_STRNCMP (TablePtr->Signature, AcpiGbl_AcpiTableData[ACPI_TABLE_PSDT].Signature, AcpiGbl_AcpiTableData[ACPI_TABLE_PSDT].SigLength)) && - (!STRNCMP (TableHeader.Signature, + (!ACPI_STRNCMP (TablePtr->Signature, AcpiGbl_AcpiTableData[ACPI_TABLE_SSDT].Signature, AcpiGbl_AcpiTableData[ACPI_TABLE_SSDT].SigLength))) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Table has invalid signature [%4.4s], must be SSDT or PSDT\n", - (char*)TableHeader.Signature)); + (char *) &TablePtr->Signature)); Status = AE_BAD_SIGNATURE; goto Cleanup; } - /* Create an object to be the table handle */ - - TableDesc = AcpiUtCreateInternalObject (INTERNAL_TYPE_REFERENCE); - if (!TableDesc) - { - Status = AE_NO_MEMORY; - goto Cleanup; - } - /* Install the new table into the local data structures */ - TableInfo.Pointer = (ACPI_TABLE_HEADER *) TablePtr; - TableInfo.Length = TableHeader.Length; - TableInfo.Allocation = ACPI_MEM_ALLOCATED; - TableInfo.BasePointer = TablePtr; - - Status = AcpiTbInstallTable (NULL, &TableInfo); + Status = AcpiExAddTable (TablePtr, AcpiGbl_RootNode, &DdbHandle); if (ACPI_FAILURE (Status)) { goto Cleanup; } - /* Add the table to the namespace */ + /* Store the DdbHandle into the Target operand */ - Status = AcpiNsLoadTable (TableInfo.InstalledDesc, AcpiGbl_RootNode); + Status = AcpiExStore (DdbHandle, Target, WalkState); if (ACPI_FAILURE (Status)) { - /* Uninstall table and free the buffer */ - - AcpiTbUninstallTable (TableInfo.InstalledDesc); - goto Cleanup; + AcpiExUnloadTable (DdbHandle); } - - /* We need a pointer to the table desc */ - - /* Init the table handle */ - - TableDesc->Reference.Opcode = AML_LOAD_OP; - TableDesc->Reference.Object = TableInfo.InstalledDesc; - - /* Store the tabledesc into the DdbHandle target */ - /* DdbHandle = TableDesc; */ - return_ACPI_STATUS (Status); Cleanup: - ACPI_MEM_FREE (TableDesc); - ACPI_MEM_FREE (TablePtr); + if (BufferDesc) + { + AcpiUtRemoveReference (BufferDesc); + } + else + { + ACPI_MEM_FREE (TablePtr); + } return_ACPI_STATUS (Status); } -/***************************************************************************** +/******************************************************************************* * * FUNCTION: AcpiExUnloadTable * @@ -287,7 +516,7 @@ Cleanup: * * DESCRIPTION: Unload an ACPI table * - ****************************************************************************/ + ******************************************************************************/ ACPI_STATUS AcpiExUnloadTable ( @@ -298,7 +527,7 @@ AcpiExUnloadTable ( ACPI_TABLE_DESC *TableInfo; - FUNCTION_TRACE ("ExUnloadTable"); + ACPI_FUNCTION_TRACE ("ExUnloadTable"); /* @@ -308,7 +537,7 @@ AcpiExUnloadTable ( * validated here. */ if ((!DdbHandle) || - (!VALID_DESCRIPTOR_TYPE (DdbHandle, ACPI_DESC_TYPE_INTERNAL)) || + (ACPI_GET_DESCRIPTOR_TYPE (DdbHandle) != ACPI_DESC_TYPE_INTERNAL) || (((ACPI_OPERAND_OBJECT *)DdbHandle)->Common.Type != INTERNAL_TYPE_REFERENCE)) { @@ -336,7 +565,6 @@ AcpiExUnloadTable ( /* Delete the table descriptor (DdbHandle) */ AcpiUtRemoveReference (TableDesc); - return_ACPI_STATUS (Status); } |