diff --git a/source/compiler/aslcompile.c b/source/compiler/aslcompile.c index 9481b6bb2d..787a544444 100644 --- a/source/compiler/aslcompile.c +++ b/source/compiler/aslcompile.c @@ -283,6 +283,7 @@ CmDoCompile ( LsDumpParseTree (); + UtEndEvent (Event); UtEndEvent (FullCompile); return (AE_OK); diff --git a/source/components/debugger/dbinput.c b/source/components/debugger/dbinput.c index 0bfe994745..378e3db1a1 100644 --- a/source/components/debugger/dbinput.c +++ b/source/components/debugger/dbinput.c @@ -637,19 +637,16 @@ AcpiDbGetNextToken ( return (NULL); } - /* Remove any spaces at the beginning */ + /* Remove any spaces at the beginning, ignore blank lines */ - if (*String == ' ') + while (*String && isspace (*String)) { - while (*String && (*String == ' ')) - { - String++; - } + String++; + } - if (!(*String)) - { - return (NULL); - } + if (!(*String)) + { + return (NULL); } switch (*String) @@ -754,7 +751,7 @@ AcpiDbGetNextToken ( /* Find end of token */ - while (*String && (*String != ' ')) + while (*String && !isspace (*String)) { String++; } diff --git a/source/components/dispatcher/dswexec.c b/source/components/dispatcher/dswexec.c index f2925ecff0..ff6f47676d 100644 --- a/source/components/dispatcher/dswexec.c +++ b/source/components/dispatcher/dswexec.c @@ -158,7 +158,9 @@ #include "acinterp.h" #include "acnamesp.h" #include "acdebug.h" - +#ifdef ACPI_EXEC_APP +#include "aecommon.h" +#endif #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME ("dswexec") @@ -504,7 +506,10 @@ AcpiDsExecEndOp ( UINT32 OpClass; ACPI_PARSE_OBJECT *NextOp; ACPI_PARSE_OBJECT *FirstArg; - +#ifdef ACPI_EXEC_APP + char *Namepath; + ACPI_OPERAND_OBJECT *ObjDesc; +#endif ACPI_FUNCTION_TRACE_PTR (DsExecEndOp, WalkState); @@ -717,6 +722,24 @@ AcpiDsExecEndOp ( } Status = AcpiDsEvalBufferFieldOperands (WalkState, Op); +#ifdef ACPI_EXEC_APP + /* + * AcpiExec support for namespace initialization file (initialize + * BufferFields in this code.) + */ + Namepath = AcpiNsGetExternalPathname (Op->Common.Node); + Status = AeLookupInitFileEntry (Namepath, &ObjDesc); + if (ACPI_SUCCESS (Status)) + { + Status = AcpiExWriteDataToField (ObjDesc, Op->Common.Node->Object, NULL); + if ACPI_FAILURE (Status) + { + ACPI_EXCEPTION ((AE_INFO, Status, "While writing to buffer field")); + } + } + ACPI_FREE (Namepath); + Status = AE_OK; +#endif break; diff --git a/source/components/dispatcher/dswload.c b/source/components/dispatcher/dswload.c index d37bd5d4cc..62a4fdca41 100644 --- a/source/components/dispatcher/dswload.c +++ b/source/components/dispatcher/dswload.c @@ -156,7 +156,6 @@ #include "acdispat.h" #include "acinterp.h" #include "acnamesp.h" - #ifdef ACPI_ASL_COMPILER #include "acdisasm.h" #endif @@ -555,7 +554,6 @@ AcpiDsLoad1EndOp ( ACPI_PARSE_OBJECT *Op; ACPI_OBJECT_TYPE ObjectType; ACPI_STATUS Status = AE_OK; - #ifdef ACPI_ASL_COMPILER UINT8 ParamCount; #endif diff --git a/source/components/dispatcher/dswload2.c b/source/components/dispatcher/dswload2.c index ff2135ce62..0ab715cd13 100644 --- a/source/components/dispatcher/dswload2.c +++ b/source/components/dispatcher/dswload2.c @@ -157,6 +157,9 @@ #include "acinterp.h" #include "acnamesp.h" #include "acevents.h" +#ifdef ACPI_EXEC_APP +#include "aecommon.h" +#endif #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME ("dswload2") @@ -531,6 +534,10 @@ AcpiDsLoad2EndOp ( ACPI_NAMESPACE_NODE *NewNode; UINT32 i; UINT8 RegionSpace; +#ifdef ACPI_EXEC_APP + ACPI_OPERAND_OBJECT *ObjDesc; + char *Namepath; +#endif ACPI_FUNCTION_TRACE (DsLoad2EndOp); @@ -627,6 +634,11 @@ AcpiDsLoad2EndOp ( * be evaluated later during the execution phase */ Status = AcpiDsCreateBufferField (Op, WalkState); + if ACPI_FAILURE (Status) + { + ACPI_EXCEPTION ((AE_INFO, Status, "CreateBufferField failure")); + goto Cleanup; + } break; case AML_TYPE_NAMED_FIELD: @@ -766,6 +778,31 @@ AcpiDsLoad2EndOp ( case AML_NAME_OP: Status = AcpiDsCreateNode (WalkState, Node, Op); + if (ACPI_FAILURE (Status)) + { + goto Cleanup; + } + +#ifdef ACPI_EXEC_APP + /* + * AcpiExec support for namespace initialization file (initialize + * Name opcodes in this code.) + */ + Namepath = AcpiNsGetExternalPathname (Node); + Status = AeLookupInitFileEntry (Namepath, &ObjDesc); + if (ACPI_SUCCESS (Status)) + { + /* Detach any existing object, attach new object */ + + if (Node->Object) + { + AcpiNsDetachObject (Node); + } + AcpiNsAttachObject (Node, ObjDesc, ObjDesc->Common.Type); + } + ACPI_FREE (Namepath); + Status = AE_OK; +#endif break; case AML_METHOD_OP: diff --git a/source/components/namespace/nsnames.c b/source/components/namespace/nsnames.c index a9509195c8..a27a87f02b 100644 --- a/source/components/namespace/nsnames.c +++ b/source/components/namespace/nsnames.c @@ -158,12 +158,6 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME ("nsnames") -/* Local Prototypes */ - -static void -AcpiNsNormalizePathname ( - char *OriginalPath); - /******************************************************************************* * @@ -616,7 +610,7 @@ AcpiNsBuildPrefixedPathname ( * ******************************************************************************/ -static void +void AcpiNsNormalizePathname ( char *OriginalPath) { diff --git a/source/components/utilities/utdelete.c b/source/components/utilities/utdelete.c index 2f60917bdf..502ff41321 100644 --- a/source/components/utilities/utdelete.c +++ b/source/components/utilities/utdelete.c @@ -626,13 +626,13 @@ AcpiUtUpdateRefCount ( * * FUNCTION: AcpiUtUpdateObjectReference * - * PARAMETERS: Object - Increment ref count for this object - * and all sub-objects + * PARAMETERS: Object - Increment or decrement the ref count for + * this object and all sub-objects * Action - Either REF_INCREMENT or REF_DECREMENT * * RETURN: Status * - * DESCRIPTION: Increment the object reference count + * DESCRIPTION: Increment or decrement the object reference count * * Object references are incremented when: * 1) An object is attached to a Node (namespace object) @@ -671,7 +671,7 @@ AcpiUtUpdateObjectReference ( } /* - * All sub-objects must have their reference count incremented + * All sub-objects must have their reference count updated * also. Different object types have different subobjects. */ switch (Object->Common.Type) @@ -740,6 +740,7 @@ AcpiUtUpdateObjectReference ( break; } } + NextObject = NULL; break; diff --git a/source/include/acnamesp.h b/source/include/acnamesp.h index 3dd605a0fd..48b3659364 100644 --- a/source/include/acnamesp.h +++ b/source/include/acnamesp.h @@ -487,6 +487,10 @@ AcpiNsBuildNormalizedPath ( UINT32 PathSize, BOOLEAN NoTrailing); +void +AcpiNsNormalizePathname ( + char *OriginalPath); + char * AcpiNsGetNormalizedPathname ( ACPI_NAMESPACE_NODE *Node, diff --git a/source/tools/acpiexec/aecommon.h b/source/tools/acpiexec/aecommon.h index d9ade0b601..9dbb3fac16 100644 --- a/source/tools/acpiexec/aecommon.h +++ b/source/tools/acpiexec/aecommon.h @@ -195,7 +195,9 @@ typedef struct ae_debug_regions typedef struct init_file_entry { char *Name; + char *Value; ACPI_OPERAND_OBJECT *ObjDesc; + BOOLEAN IsUsed; } INIT_FILE_ENTRY; @@ -346,19 +348,23 @@ int AeOpenInitializationFile ( char *Filename); -void +ACPI_STATUS AeProcessInitFile ( void); -ACPI_STATUS -AeSetupConfiguration ( - void *RegionAddr); - ACPI_STATUS AeLookupInitFileEntry ( char *Pathname, ACPI_OPERAND_OBJECT **ObjDesc); +void +AeDisplayUnusedInitFileItems ( + void); + +void +AeDeleteInitFileList ( + void); + /* aeexec */ void @@ -376,6 +382,10 @@ AeGetDevices ( void *Context, void **ReturnValue); +ACPI_STATUS +AeSetupConfiguration ( + void *RegionAddr); + ACPI_STATUS ExecuteOSI ( char *OsiString, diff --git a/source/tools/acpiexec/aeinitfile.c b/source/tools/acpiexec/aeinitfile.c index 0813c8739d..29115323e8 100644 --- a/source/tools/acpiexec/aeinitfile.c +++ b/source/tools/acpiexec/aeinitfile.c @@ -151,24 +151,17 @@ #include "aecommon.h" #include "acdispat.h" +#include "acnamesp.h" + #define _COMPONENT ACPI_TOOLS ACPI_MODULE_NAME ("aeinitfile") -/* Local prototypes */ - -static void -AeEnterInitFileEntry ( - INIT_FILE_ENTRY InitEntry, - ACPI_WALK_STATE *WalkState); - - #define AE_FILE_BUFFER_SIZE 512 static char LineBuffer[AE_FILE_BUFFER_SIZE]; static char NameBuffer[AE_FILE_BUFFER_SIZE]; -static char ValueBuffer[AE_FILE_BUFFER_SIZE]; static FILE *InitFile; @@ -211,23 +204,23 @@ AeOpenInitializationFile ( * RETURN: None * * DESCRIPTION: Read the initialization file and perform all namespace - * initializations. AcpiGbl_InitEntries will be used for region - * field initialization. + * initializations. AcpiGbl_InitEntries will be used for all + * object initialization. * * NOTE: The format of the file is multiple lines, each of format: - * + * * *****************************************************************************/ -void -AeProcessInitFile( +ACPI_STATUS +AeProcessInitFile ( void) { ACPI_WALK_STATE *WalkState; UINT64 idx; - ACPI_STATUS Status; + ACPI_STATUS Status = AE_OK; char *Token; - char *ObjectBuffer; + char *ValueBuffer; char *TempNameBuffer; ACPI_OBJECT_TYPE Type; ACPI_OBJECT TempObject; @@ -235,13 +228,14 @@ AeProcessInitFile( if (!InitFile) { - return; + return (AE_OK); } /* Create needed objects to be reused for each init entry */ WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); NameBuffer[0] = '\\'; + NameBuffer[1] = 0; while (fgets (LineBuffer, AE_FILE_BUFFER_SIZE, InitFile) != NULL) { @@ -249,12 +243,20 @@ AeProcessInitFile( } rewind (InitFile); + /* + * Allocate and populate the Gbl_InitEntries array + */ AcpiGbl_InitEntries = - AcpiOsAllocate (sizeof (INIT_FILE_ENTRY) * AcpiGbl_InitFileLineCount); + AcpiOsAllocateZeroed (sizeof (INIT_FILE_ENTRY) * AcpiGbl_InitFileLineCount); for (idx = 0; fgets (LineBuffer, AE_FILE_BUFFER_SIZE, InitFile); ++idx) { - TempNameBuffer = AcpiDbGetNextToken (LineBuffer, &Token, &Type); + if (!TempNameBuffer) + { + AcpiGbl_InitEntries[idx].Name = NULL; + continue; + } + if (LineBuffer[0] == '\\') { strcpy (NameBuffer, TempNameBuffer); @@ -266,48 +268,67 @@ AeProcessInitFile( strcpy (NameBuffer + 1, TempNameBuffer); } + AcpiNsNormalizePathname (NameBuffer); AcpiGbl_InitEntries[idx].Name = AcpiOsAllocateZeroed (strnlen (NameBuffer, AE_FILE_BUFFER_SIZE) + 1); - strcpy (AcpiGbl_InitEntries[idx].Name, NameBuffer); - ObjectBuffer = AcpiDbGetNextToken (Token, &Token, &Type); + ValueBuffer = AcpiDbGetNextToken (Token, &Token, &Type); + if (!ValueBuffer) + { + AcpiGbl_InitEntries[idx].Value = NULL; + continue; + } + + AcpiGbl_InitEntries[idx].Value = + AcpiOsAllocateZeroed (strnlen (ValueBuffer, AE_FILE_BUFFER_SIZE) + 1); + strcpy (AcpiGbl_InitEntries[idx].Value, ValueBuffer); if (Type == ACPI_TYPE_FIELD_UNIT) { - Status = AcpiDbConvertToObject (ACPI_TYPE_BUFFER, ObjectBuffer, + Status = AcpiDbConvertToObject (ACPI_TYPE_BUFFER, ValueBuffer, &TempObject); } else { - Status = AcpiDbConvertToObject (Type, ObjectBuffer, &TempObject); + Status = AcpiDbConvertToObject (Type, ValueBuffer, &TempObject); + } + + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("%s[%s]: %s\n", NameBuffer, AcpiUtGetTypeName (Type), + AcpiFormatException (Status)); + goto CleanupAndExit; } Status = AcpiUtCopyEobjectToIobject (&TempObject, &AcpiGbl_InitEntries[idx].ObjDesc); - if (Type == ACPI_TYPE_BUFFER || Type == ACPI_TYPE_FIELD_UNIT) + /* Cleanup the external object created by DbConvertToObject above */ + + if (ACPI_SUCCESS (Status)) { - ACPI_FREE (TempObject.Buffer.Pointer); + if (Type == ACPI_TYPE_BUFFER || Type == ACPI_TYPE_FIELD_UNIT) + { + ACPI_FREE (TempObject.Buffer.Pointer); + } + else if (Type == ACPI_TYPE_PACKAGE) + { + AcpiDbDeleteObjects (1, &TempObject); + } } - - if (ACPI_FAILURE (Status)) + else { - AcpiOsPrintf ("%s %s\n", ValueBuffer, + AcpiOsPrintf ("%s[%s]: %s\n", NameBuffer, AcpiUtGetTypeName (Type), AcpiFormatException (Status)); goto CleanupAndExit; } /* - * Special case for field units. Field units are dependent on the - * parent region. This parent region has yet to be created so defer the - * initialization until the dispatcher. For all other types, initialize - * the namespace node with the value found in the init file. + * Initialize the namespace node with the value found in the init file. */ - if (Type != ACPI_TYPE_FIELD_UNIT) - { - AeEnterInitFileEntry (AcpiGbl_InitEntries[idx], WalkState); - } + AcpiOsPrintf ("Namespace object init from file: %16s, Value \"%s\", Type %s\n", + AcpiGbl_InitEntries[idx].Name, AcpiGbl_InitEntries[idx].Value, AcpiUtGetTypeName (Type)); } /* Cleanup */ @@ -315,97 +336,131 @@ AeProcessInitFile( CleanupAndExit: fclose (InitFile); AcpiDsDeleteWalkState (WalkState); + return (Status); } /****************************************************************************** * - * FUNCTION: AeInitFileEntry - * - * PARAMETERS: InitEntry - Entry of the init file - * WalkState - Used for the Store operation + * FUNCTION: AeLookupInitFileEntry * - * RETURN: None + * PARAMETERS: Pathname - AML namepath in external format + * ObjDesc - Where the object is returned if it exists * - * DESCRIPTION: Perform initialization of a single namespace object + * RETURN: Status. AE_OK if a match was found * - * Note: namespace of objects are limited to integers and region - * fields units of 8 bytes at this time. + * DESCRIPTION: Search the init file for a particular name and its value. * *****************************************************************************/ -static void -AeEnterInitFileEntry ( - INIT_FILE_ENTRY InitEntry, - ACPI_WALK_STATE *WalkState) +ACPI_STATUS +AeLookupInitFileEntry ( + char *Pathname, + ACPI_OPERAND_OBJECT **ObjDesc) { - char *Pathname = InitEntry.Name; - ACPI_OPERAND_OBJECT *ObjDesc = InitEntry.ObjDesc; - ACPI_NAMESPACE_NODE *NewNode; - ACPI_STATUS Status; + UINT32 i; + ACPI_FUNCTION_TRACE (AeLookupInitFileEntry); - Status = AcpiNsLookup (NULL, Pathname, ObjDesc->Common.Type, - ACPI_IMODE_LOAD_PASS2, ACPI_NS_ERROR_IF_FOUND | ACPI_NS_NO_UPSEARCH | - ACPI_NS_EARLY_INIT, NULL, &NewNode); - if (ACPI_FAILURE (Status)) + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Lookup: %s\n", Pathname)); + + if (!AcpiGbl_InitEntries) { - ACPI_EXCEPTION ((AE_INFO, Status, - "While creating name from namespace initialization file: %s", - Pathname)); - return; + return (AE_NOT_FOUND); } - /* Store pointer to value descriptor in the Node */ + AcpiNsNormalizePathname (Pathname); - Status = AcpiNsAttachObject (NewNode, ObjDesc, - ObjDesc->Common.Type); - if (ACPI_FAILURE (Status)) + for (i = 0; i < AcpiGbl_InitFileLineCount; ++i) { - ACPI_EXCEPTION ((AE_INFO, Status, - "While attaching object to node from namespace initialization file: %s", - Pathname)); - return; + if (AcpiGbl_InitEntries[i].Name && + !strcmp (AcpiGbl_InitEntries[i].Name, Pathname)) + { + *ObjDesc = AcpiGbl_InitEntries[i].ObjDesc; + AcpiGbl_InitEntries[i].IsUsed = TRUE; + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Found match: %s, %p\n", Pathname, *ObjDesc)); + return_ACPI_STATUS (AE_OK); + } } - /* Remove local reference to the object */ + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "No match found: %s\n", Pathname)); + return_ACPI_STATUS (AE_NOT_FOUND); +} + + +/****************************************************************************** + * + * FUNCTION: AeDisplayUnusedInitFileItems + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Display all init file items that have not been referenced + * (i.e., items that have not been found in the namespace). + * + *****************************************************************************/ + +void +AeDisplayUnusedInitFileItems ( + void) +{ + UINT32 i; + + + if (!AcpiGbl_InitEntries) + { + return; + } - AcpiUtRemoveReference (ObjDesc); + for (i = 0; i < AcpiGbl_InitFileLineCount; ++i) + { + if (AcpiGbl_InitEntries[i].Name && + !AcpiGbl_InitEntries[i].IsUsed) + { + AcpiOsPrintf ("Init file entry not found in namespace " + "(or is a non-data type): %s\n", + AcpiGbl_InitEntries[i].Name); + } + } } /****************************************************************************** * - * FUNCTION: AeLookupInitFileEntry + * FUNCTION: AeDeleteInitFileList * - * PARAMETERS: Pathname - AML namepath in external format - * ValueString - value of the namepath if it exitst + * PARAMETERS: None * * RETURN: None * - * DESCRIPTION: Search the init file for a particular name and its value. + * DESCRIPTION: Delete the global namespace initialization file data * *****************************************************************************/ -ACPI_STATUS -AeLookupInitFileEntry ( - char *Pathname, - ACPI_OPERAND_OBJECT **ObjDesc) +void +AeDeleteInitFileList ( + void) { UINT32 i; + if (!AcpiGbl_InitEntries) { - return AE_NOT_FOUND; + AcpiOsPrintf ("Exiting AeDeleteInitFileList\n"); + return; } for (i = 0; i < AcpiGbl_InitFileLineCount; ++i) { - if (!strcmp(AcpiGbl_InitEntries[i].Name, Pathname)) + + if ((AcpiGbl_InitEntries[i].ObjDesc) && (AcpiGbl_InitEntries[i].Value)) { - *ObjDesc = AcpiGbl_InitEntries[i].ObjDesc; - return AE_OK; + /* Remove one reference on the object (and all subobjects) */ + + AcpiUtRemoveReference (AcpiGbl_InitEntries[i].ObjDesc); } } - return AE_NOT_FOUND; + + AcpiOsFree (AcpiGbl_InitEntries); } diff --git a/source/tools/acpiexec/aemain.c b/source/tools/acpiexec/aemain.c index 200b818d24..502684a473 100644 --- a/source/tools/acpiexec/aemain.c +++ b/source/tools/acpiexec/aemain.c @@ -674,8 +674,6 @@ main ( signal (SIGSEGV, AeSignalHandler); } - AeProcessInitFile(); - /* The remaining arguments are filenames for ACPI tables */ if (!argv[AcpiGbl_Optind]) @@ -733,7 +731,21 @@ main ( goto EnterDebugger; } + /* Read the entire namespace initialization file if requested */ + + Status = AeProcessInitFile(); + if (ACPI_FAILURE (Status)) + { + ExitCode = -1; + goto ErrorExit; + } + Status = AeLoadTables (); + if (ACPI_FAILURE (Status)) + { + ExitCode = -1; + goto ErrorExit; + } /* * Exit namespace initialization for the "load namespace only" option. @@ -794,6 +806,7 @@ main ( goto EnterDebugger; } + AeDisplayUnusedInitFileItems (); AeMiscellaneousTests (); @@ -840,7 +853,9 @@ main ( ErrorExit: AeLateTest (); - AcpiOsFree (AcpiGbl_InitEntries); + + AeDeleteInitFileList (); + (void) AcpiTerminate (); AcDeleteTableList (ListHead); return (ExitCode);