diff options
67 files changed, 1738 insertions, 782 deletions
| diff --git a/changes.txt b/changes.txt index f9958564fcb4..f9f941e6ebb7 100644 --- a/changes.txt +++ b/changes.txt @@ -1,4 +1,161 @@  ---------------------------------------- +18 December 2015. Summary of changes for version 20151218: + +This release is available at https://acpica.org/downloads + + +1) ACPICA kernel-resident subsystem: + +Implemented per-AML-table execution of "module-level code" as individual  +ACPI tables are loaded into the namespace during ACPICA initialization.  +In other words, any module-level code within an AML table is executed  +immediately after the table is loaded, instead of batched and executed  +after all of the tables have been loaded. This provides compatibility  +with other ACPI implementations. ACPICA BZ 1219. Bob Moore, Lv Zheng,  +David Box. + +To fully support the feature above, the default operation region handlers  +for the SystemMemory, SystemIO, and PCI_Config address spaces are now  +installed before any ACPI tables are loaded. This enables module-level  +code to access these address spaces during the table load and module- +level code execution phase. ACPICA BZ 1220. Bob Moore, Lv Zheng, David  +Box. + +Implemented several changes to the internal _REG support in conjunction  +with the changes above. Also, changes to the AcpiExec/AcpiNames/Examples  +utilities for the changes above. Although these tools were changed, host  +operating systems that simply use the default handlers for SystemMemory,  +SystemIO, and PCI_Config spaces should not require any update. Lv Zheng. + +For example, in the code below, DEV1 is conditionally added to the  +namespace by the DSDT via module-level code that accesses an operation  +region. The SSDT references DEV1 via the Scope operator. DEV1 must be  +created immediately after the DSDT is loaded in order for the SSDT to  +successfully reference DEV1. Previously, this code would cause an  +AE_NOT_EXIST exception during the load of the SSDT. Now, this code is  +fully supported by ACPICA. + +    DefinitionBlock ("", "DSDT", 2, "Intel", "DSDT1", 1) +    { +        OperationRegion (OPR1, SystemMemory, 0x400, 32) +        Field (OPR1, AnyAcc, NoLock, Preserve) +        { +            FLD1, 1 +        } +        If (FLD1) +        { +            Device (\DEV1) +            { +            } +        } +    } +    DefinitionBlock ("", "SSDT", 2, "Intel", "SSDT1", 1) +    { +        External (\DEV1, DeviceObj) +        Scope (\DEV1) +        { +        } +    } + +Fixed an AML interpreter problem where control method invocations were  +not handled correctly when the invocation was itself a SuperName argument  +to another ASL operator. In these cases, the method was not invoked.  +ACPICA BZ 1002. Affects the following ASL operators that have a SuperName  +argument: +    Store +    Acquire, Wait +    CondRefOf, RefOf +    Decrement, Increment +    Load, Unload +    Notify +    Signal, Release, Reset +    SizeOf + +Implemented automatic String-to-ObjectReference conversion support for  +packages returned by predefined names (such as _DEP). A common BIOS error  +is to add double quotes around an ObjectReference namepath, which turns  +the reference into an unexpected string object. This support detects the  +problem and corrects it before the package is returned to the caller that  +invoked the method. Lv Zheng. + +Implemented extensions to the Concatenate operator. Concatenate now  +accepts any type of object, it is not restricted to simply  +Integer/String/Buffer. For objects other than these 3 basic data types,  +the argument is treated as a string containing the name of the object  +type. This expands the utility of Concatenate and the Printf/Fprintf  +macros. ACPICA BZ 1222. + +Cleaned up the output of the ASL Debug object. The timer() value is now  +optional and no longer emitted by default. Also, the basic data types of  +Integer/String/Buffer are simply emitted as their values, without a data  +type string -- since the data type is obvious from the output. ACPICA BZ  +1221. + +Example Code and Data Size: These are the sizes for the OS-independent  +acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The  +debug version of the code includes the debug output trace mechanism and  +has a much larger code and data size. + +  Current Release: +    Non-Debug Version: 102.6K Code, 28.4K Data, 131.0K Total +    Debug Version:     200.3K Code, 81.9K Data, 282.3K Total +  Previous Release: +    Non-Debug Version: 102.0K Code, 28.3K Data, 130.3K Total +    Debug Version:     199.6K Code, 81.8K Data, 281.4K Total + + +2) iASL Compiler/Disassembler and Tools: + +iASL: Fixed some issues with the ASL Include() operator. This operator  +was incorrectly defined in the iASL parser rules, causing a new scope to  +be opened for the code within the include file. This could lead to  +several issues, including allowing ASL code that is technically illegal  +and not supported by AML interpreters. Note, this does not affect the  +related #include preprocessor operator. ACPICA BZ 1212. + +iASL/Disassembler: Implemented support for the ASL ElseIf operator. This  +operator is essentially an ASL macro since there is no AML opcode  +associated with it. The code emitted by the iASL compiler for ElseIf is  +an Else opcode followed immediately by an If opcode. The disassembler  +will now emit an ElseIf if it finds an Else immediately followed by an  +If. This simplifies the decoded ASL, especially for deeply nested  +If..Else and large Switch constructs. Thus, the disassembled code more  +closely follows the original source ASL. ACPICA BZ 1211. Example: + +    Old disassembly: +        Else +        { +            If (Arg0 == 0x02) +            { +                Local0 = 0x05 +            } +        } + +    New disassembly: +        ElseIf (Arg0 == 0x02) +        { +            Local0 = 0x05 +        } + +AcpiExec: Added support for the new module level code behavior and the  +early region installation. This required a small change to the  +initialization, since AcpiExec must install its own operation region  +handlers. + +AcpiExec: Added support to make the debug object timer optional. Default  +is timer disabled. This cleans up the debug object output -- the timer  +data is rarely used. + +AcpiExec: Multiple ACPI tables are now loaded in the order that they  +appear on the command line. This can be important when there are  +interdependencies/references between the tables. + +iASL/Templates. Add support to generate template files with multiple  +SSDTs within a single output file. Also added ommand line support to  +specify the number of SSDTs (in addition to a single DSDT). ACPICA BZ  +1223, 1225. + +----------------------------------------  24 November 2015. Summary of changes for version 20151124:  This release is available at https://acpica.org/downloads diff --git a/source/common/acfileio.c b/source/common/acfileio.c index b94adf8c4900..96f323f74909 100644 --- a/source/common/acfileio.c +++ b/source/common/acfileio.c @@ -55,20 +55,20 @@  /* Local prototypes */  static ACPI_STATUS -AcpiAcGetOneTableFromFile ( +AcGetOneTableFromFile (      char                    *Filename,      FILE                    *File,      UINT8                   GetOnlyAmlTables,      ACPI_TABLE_HEADER       **Table);  static ACPI_STATUS -AcpiAcCheckTextModeCorruption ( +AcCheckTextModeCorruption (      ACPI_TABLE_HEADER       *Table);  /*******************************************************************************   * - * FUNCTION:    AcpiAcGetAllTablesFromFile + * FUNCTION:    AcGetAllTablesFromFile   *   * PARAMETERS:  Filename            - Table filename   *              GetOnlyAmlTables    - TRUE if the tables must be AML tables @@ -81,7 +81,7 @@ AcpiAcCheckTextModeCorruption (   ******************************************************************************/  ACPI_STATUS -AcpiAcGetAllTablesFromFile ( +AcGetAllTablesFromFile (      char                    *Filename,      UINT8                   GetOnlyAmlTables,      ACPI_NEW_TABLE_DESC     **ReturnListHead) @@ -115,19 +115,36 @@ AcpiAcGetAllTablesFromFile (          return (AE_ERROR);      } -    if (FileSize < 4) +    fprintf (stderr, +        "Input file %s, Length 0x%X (%u) bytes\n", +        Filename, FileSize, FileSize); + +    /* We must have at least one ACPI table header */ + +    if (FileSize < sizeof (ACPI_TABLE_HEADER))      {          return (AE_BAD_HEADER);      } +    /* Check for an non-binary file */ + +    if (!AcIsFileBinary (File)) +    { +        fprintf (stderr, +            "    %s: File does not appear to contain a valid AML table\n", +            Filename); +        return (AE_TYPE); +    } +      /* Read all tables within the file */      while (ACPI_SUCCESS (Status))      {          /* Get one entire ACPI table */ -        Status = AcpiAcGetOneTableFromFile ( +        Status = AcGetOneTableFromFile (              Filename, File, GetOnlyAmlTables, &Table); +          if (Status == AE_CTRL_TERMINATE)          {              Status = AE_OK; @@ -135,13 +152,20 @@ AcpiAcGetAllTablesFromFile (          }          else if (Status == AE_TYPE)          { -            continue; +            return (AE_OK);          }          else if (ACPI_FAILURE (Status))          {              return (Status);          } +        /* Print table header for iASL/disassembler only */ + +#ifdef ACPI_ASL_COMPILER + +            AcpiTbPrintTableHeader (0, Table); +#endif +          /* Allocate and link a table descriptor */          TableDesc = AcpiOsAllocate (sizeof (ACPI_NEW_TABLE_DESC)); @@ -186,7 +210,7 @@ AcpiAcGetAllTablesFromFile (  /*******************************************************************************   * - * FUNCTION:    AcpiAcGetOneTableFromFile + * FUNCTION:    AcGetOneTableFromFile   *   * PARAMETERS:  Filename            - File where table is located   *              File                - Open FILE pointer to Filename @@ -204,7 +228,7 @@ AcpiAcGetAllTablesFromFile (   ******************************************************************************/  static ACPI_STATUS -AcpiAcGetOneTableFromFile ( +AcGetOneTableFromFile (      char                    *Filename,      FILE                    *File,      UINT8                   GetOnlyAmlTables, @@ -214,21 +238,28 @@ AcpiAcGetOneTableFromFile (      ACPI_TABLE_HEADER       TableHeader;      ACPI_TABLE_HEADER       *Table;      INT32                   Count; -    long                    Position; +    long                    TableOffset;      *ReturnTable = NULL; +    /* Get the table header to examine signature and length */ -    /* Get just the table header to get signature and length */ - -    Position = ftell (File); +    TableOffset = ftell (File);      Count = fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), File);      if (Count != sizeof (ACPI_TABLE_HEADER))      {          return (AE_CTRL_TERMINATE);      } +    /* Validate the table signature/header (limited ASCII chars) */ + +    Status = AcValidateTableHeader (File, TableOffset); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } +      if (GetOnlyAmlTables)      {          /* Table must be an AML table (DSDT/SSDT) or FADT */ @@ -237,7 +268,7 @@ AcpiAcGetOneTableFromFile (              !AcpiUtIsAmlTable (&TableHeader))          {              fprintf (stderr, -                "    %s: [%4.4s] is not an AML table - ignoring\n", +                "    %s: Table [%4.4s] is not an AML table - ignoring\n",                  Filename, TableHeader.Signature);              return (AE_TYPE); @@ -252,9 +283,9 @@ AcpiAcGetOneTableFromFile (          return (AE_NO_MEMORY);      } -    /* Now read the entire table */ +    /* Read the entire ACPI table, including header */ -    fseek (File, Position, SEEK_SET); +    fseek (File, TableOffset, SEEK_SET);      Count = fread (Table, 1, TableHeader.Length, File);      if (Count != (INT32) TableHeader.Length) @@ -268,18 +299,13 @@ AcpiAcGetOneTableFromFile (      Status = AcpiTbVerifyChecksum (Table, TableHeader.Length);      if (ACPI_FAILURE (Status))      { -        Status = AcpiAcCheckTextModeCorruption (Table); +        Status = AcCheckTextModeCorruption (Table);          if (ACPI_FAILURE (Status))          {              goto ErrorExit;          }      } -    fprintf (stderr, -        "Loading ACPI table [%4.4s] from file %12s - Length 0x%06X (%u)\n", -        TableHeader.Signature, Filename, -        TableHeader.Length, TableHeader.Length); -      *ReturnTable = Table;      return (AE_OK); @@ -292,7 +318,159 @@ ErrorExit:  /*******************************************************************************   * - * FUNCTION:    AcpiAcCheckTextModeCorruption + * FUNCTION:    AcIsFileBinary + * + * PARAMETERS:  File                - Open input file + * + * RETURN:      TRUE if file appears to be binary + * + * DESCRIPTION: Scan a file for any non-ASCII bytes. + * + * Note: Maintains current file position. + * + ******************************************************************************/ + +BOOLEAN +AcIsFileBinary ( +    FILE                    *File) +{ +    UINT8                   Byte; +    BOOLEAN                 IsBinary = FALSE; +    long                    FileOffset; + + +    /* Scan entire file for any non-ASCII bytes */ + +    FileOffset = ftell (File); +    while (fread (&Byte, 1, 1, File) == 1) +    { +        if (!isprint (Byte) && !isspace (Byte)) +        { +            IsBinary = TRUE; +            goto Exit; +        } +    } + +Exit: +    fseek (File, FileOffset, SEEK_SET); +    return (IsBinary); +} + + +/******************************************************************************* + * + * FUNCTION:    AcValidateTableHeader + * + * PARAMETERS:  File                - Open input file + * + * RETURN:      Status + * + * DESCRIPTION: Determine if a file seems to contain one or more binary ACPI + *              tables, via the + *              following checks on what would be the table header: + *              1) File must be at least as long as an ACPI_TABLE_HEADER + *              2) There must be enough room in the file to hold entire table + *              3) Signature, OemId, OemTableId, AslCompilerId must be ASCII + * + * Note: There can be multiple definition blocks per file, so we cannot + * expect/compare the file size to be equal to the table length. 12/2015. + * + * Note: Maintains current file position. + * + ******************************************************************************/ + +ACPI_STATUS +AcValidateTableHeader ( +    FILE                    *File, +    long                    TableOffset) +{ +    ACPI_TABLE_HEADER       TableHeader; +    size_t                  Actual; +    long                    OriginalOffset; +    UINT32                  FileSize; +    UINT32                  i; + + +    ACPI_FUNCTION_TRACE ("AcValidateTableHeader"); + + +    /* Read a potential table header */ + +    OriginalOffset = ftell (File); +    fseek (File, TableOffset, SEEK_SET); + +    Actual = fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), File); +    fseek (File, OriginalOffset, SEEK_SET); + +    if (Actual < sizeof (ACPI_TABLE_HEADER)) +    { +        return (AE_ERROR); +    } + +    /* Validate the signature (limited ASCII chars) */ + +    if (!AcpiIsValidSignature (TableHeader.Signature)) +    { +        fprintf (stderr, "Invalid table signature: 0x%8.8X\n", +            *ACPI_CAST_PTR (UINT32, TableHeader.Signature)); +        return (AE_BAD_SIGNATURE); +    } + +    /* Validate table length against bytes remaining in the file */ + +    FileSize = CmGetFileSize (File); +    if (TableHeader.Length > (UINT32) (FileSize - TableOffset)) +    { +        fprintf (stderr, "Table [%4.4s] is too long for file - " +            "needs: 0x%.2X, remaining in file: 0x%.2X\n", +            TableHeader.Signature, TableHeader.Length, +            (UINT32) (FileSize - TableOffset)); +        return (AE_BAD_HEADER); +    } + +    /* +     * These fields must be ASCII: OemId, OemTableId, AslCompilerId. +     * We allow a NULL terminator in OemId and OemTableId. +     */ +    for (i = 0; i < ACPI_NAME_SIZE; i++) +    { +        if (!ACPI_IS_ASCII ((UINT8) TableHeader.AslCompilerId[i])) +        { +            goto BadCharacters; +        } +    } + +    for (i = 0; (i < ACPI_OEM_ID_SIZE) && (TableHeader.OemId[i]); i++) +    { +        if (!ACPI_IS_ASCII ((UINT8) TableHeader.OemId[i])) +        { +            goto BadCharacters; +        } +    } + +    for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (TableHeader.OemTableId[i]); i++) +    { +        if (!ACPI_IS_ASCII ((UINT8) TableHeader.OemTableId[i])) +        { +            goto BadCharacters; +        } +    } + +    return (AE_OK); + + +BadCharacters: + +    ACPI_WARNING ((AE_INFO, +        "Table header for [%4.4s] has invalid ASCII character(s)", +        TableHeader.Signature)); +    return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION:    AcCheckTextModeCorruption   *   * PARAMETERS:  Table           - Table buffer starting with table header   * @@ -305,7 +483,7 @@ ErrorExit:   ******************************************************************************/  static ACPI_STATUS -AcpiAcCheckTextModeCorruption ( +AcCheckTextModeCorruption (      ACPI_TABLE_HEADER       *Table)  {      UINT32                  i; diff --git a/source/common/adisasm.c b/source/common/adisasm.c index 33500d6df4d6..4011dea73b2f 100644 --- a/source/common/adisasm.c +++ b/source/common/adisasm.c @@ -192,10 +192,12 @@ AdAmlDisassemble (      {          /* Get the list of all AML tables in the file */ -        Status = AcpiAcGetAllTablesFromFile (Filename, +        Status = AcGetAllTablesFromFile (Filename,              ACPI_GET_ALL_TABLES, &ListHead);          if (ACPI_FAILURE (Status))          { +            AcpiOsPrintf ("Could not get ACPI tables from %s, %s\n", +                Filename, AcpiFormatException (Status));              return (Status);          } @@ -281,13 +283,12 @@ AdAmlDisassemble (  Cleanup: -// check! -#if 0 -    if (Table && !AcpiGbl_ForceAmlDisassembly && !AcpiUtIsAmlTable (Table)) +    if (Table && +        !AcpiGbl_ForceAmlDisassembly && +        !AcpiUtIsAmlTable (Table))      {          ACPI_FREE (Table);      } -#endif      if (File)      { @@ -592,7 +593,7 @@ AdDoExternalFileList (          AcpiOsPrintf ("External object resolution file %16s\n",              ExternalFilename); -        Status = AcpiAcGetAllTablesFromFile ( +        Status = AcGetAllTablesFromFile (              ExternalFilename, ACPI_GET_ONLY_AML_TABLES, &ExternalListHead);          if (ACPI_FAILURE (Status))          { diff --git a/source/common/getopt.c b/source/common/getopt.c index e5b72174c031..64c1fef6e58a 100644 --- a/source/common/getopt.c +++ b/source/common/getopt.c @@ -47,6 +47,7 @@   * Option strings:   *    "f"       - Option has no arguments   *    "f:"      - Option requires an argument + *    "f+"      - Option has an optional argument   *    "f^"      - Option has optional single-char sub-options   *    "f|"      - Option has required single-char sub-options   */ diff --git a/source/compiler/aslascii.c b/source/compiler/aslascii.c index f164e98f5edf..50b145b2a487 100644 --- a/source/compiler/aslascii.c +++ b/source/compiler/aslascii.c @@ -42,6 +42,7 @@   */  #include "aslcompiler.h" +#include <actables.h>  #include <acapps.h>  #define _COMPONENT          ACPI_COMPILER @@ -63,90 +64,7 @@ FlConsumeNewComment (  /*******************************************************************************   * - * FUNCTION:    FlCheckForAcpiTable - * - * PARAMETERS:  Handle              - Open input file - * - * RETURN:      Status - * - * DESCRIPTION: Determine if a file seems to be a binary ACPI table, via the - *              following checks on what would be the table header: - *              0) File must be at least as long as an ACPI_TABLE_HEADER - *              1) The header length field must match the file size - *              2) Signature, OemId, OemTableId, AslCompilerId must be ASCII - * - ******************************************************************************/ - -ACPI_STATUS -FlCheckForAcpiTable ( -    FILE                    *Handle) -{ -    ACPI_TABLE_HEADER       Table; -    UINT32                  FileSize; -    size_t                  Actual; -    UINT32                  i; - - -    /* Read a potential table header */ - -    Actual = fread (&Table, 1, sizeof (ACPI_TABLE_HEADER), Handle); -    fseek (Handle, 0, SEEK_SET); - -    if (Actual < sizeof (ACPI_TABLE_HEADER)) -    { -        return (AE_ERROR); -    } - -    /* Header length field must match the file size */ - -    FileSize = CmGetFileSize (Handle); -    if (Table.Length != FileSize) -    { -        return (AE_ERROR); -    } - -    /* -     * These fields must be ASCII: -     * Signature, OemId, OemTableId, AslCompilerId. -     * We allow a NULL terminator in OemId and OemTableId. -     */ -    for (i = 0; i < ACPI_NAME_SIZE; i++) -    { -        if (!ACPI_IS_ASCII ((UINT8) Table.Signature[i])) -        { -            return (AE_ERROR); -        } - -        if (!ACPI_IS_ASCII ((UINT8) Table.AslCompilerId[i])) -        { -            return (AE_ERROR); -        } -    } - -    for (i = 0; (i < ACPI_OEM_ID_SIZE) && (Table.OemId[i]); i++) -    { -        if (!ACPI_IS_ASCII ((UINT8) Table.OemId[i])) -        { -            return (AE_ERROR); -        } -    } - -    for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (Table.OemTableId[i]); i++) -    { -        if (!ACPI_IS_ASCII ((UINT8) Table.OemTableId[i])) -        { -            return (AE_ERROR); -        } -    } - -    printf ("Binary file appears to be a valid ACPI table, disassembling\n"); -    return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION:    FlCheckForAscii + * FUNCTION:    FlIsFileAsciiSource   *   * PARAMETERS:  Filename            - Full input filename   *              DisplayErrors       - TRUE if error messages desired @@ -163,7 +81,7 @@ FlCheckForAcpiTable (   ******************************************************************************/  ACPI_STATUS -FlCheckForAscii ( +FlIsFileAsciiSource (      char                    *Filename,      BOOLEAN                 DisplayErrors)  { diff --git a/source/compiler/aslcompiler.h b/source/compiler/aslcompiler.h index dfe80c19b2df..01a63e790f09 100644 --- a/source/compiler/aslcompiler.h +++ b/source/compiler/aslcompiler.h @@ -167,11 +167,7 @@ CmDeleteCaches (   * aslascii - ascii support   */  ACPI_STATUS -FlCheckForAcpiTable ( -    FILE                    *Handle); - -ACPI_STATUS -FlCheckForAscii ( +FlIsFileAsciiSource (      char                    *Filename,      BOOLEAN                 DisplayErrors); @@ -741,6 +737,10 @@ TrSetEndLineNumber (      ACPI_PARSE_OBJECT       *Op);  void +TrSetCurrentFilename ( +    ACPI_PARSE_OBJECT       *Op); + +void  TrWalkTree (      void); @@ -923,6 +923,10 @@ DbgPrint (  #define ASL_PARSE_OUTPUT    1  #define ASL_TREE_OUTPUT     2 +BOOLEAN +UtQueryForOverwrite ( +    char                    *Pathname); +  void  UtDisplaySupportedTables (      void); @@ -1281,6 +1285,6 @@ DtDoCompile(  ACPI_STATUS  DtCreateTemplates ( -    char                    *Signature); +    char                    **argv);  #endif /*  __ASLCOMPILER_H */ diff --git a/source/compiler/asldefine.h b/source/compiler/asldefine.h index 64ecff3e9e6c..e1aa58275995 100644 --- a/source/compiler/asldefine.h +++ b/source/compiler/asldefine.h @@ -106,10 +106,10 @@  /* Types for input files */ -#define ASL_INPUT_TYPE_BINARY       0 -#define ASL_INPUT_TYPE_ACPI_TABLE   1 -#define ASL_INPUT_TYPE_ASCII_ASL    2 -#define ASL_INPUT_TYPE_ASCII_DATA   3 +#define ASL_INPUT_TYPE_BINARY               0 +#define ASL_INPUT_TYPE_BINARY_ACPI_TABLE    1 +#define ASL_INPUT_TYPE_ASCII_ASL            2 +#define ASL_INPUT_TYPE_ASCII_DATA           3  /* Misc */ diff --git a/source/compiler/aslfiles.c b/source/compiler/aslfiles.c index 3ef1be06cb6c..cd3694454212 100644 --- a/source/compiler/aslfiles.c +++ b/source/compiler/aslfiles.c @@ -336,6 +336,7 @@ FlOpenIncludeWithPrefix (       */      Gbl_CurrentLineNumber--;      OriginalLineNumber = Gbl_CurrentLineNumber; +      while (DtGetNextLine (IncludeFile, DT_ALLOW_MULTILINE_QUOTES) != ASL_EOF)      {          if (Gbl_CurrentLineBuffer[0] == '#') @@ -344,6 +345,7 @@ FlOpenIncludeWithPrefix (                  Op, "use #include instead");          }      } +      Gbl_CurrentLineNumber = OriginalLineNumber;      /* Must seek back to the start of the file */ @@ -570,7 +572,7 @@ FlOpenMiscOutputFiles (      /* All done for disassembler */ -    if (Gbl_FileType == ASL_INPUT_TYPE_ACPI_TABLE) +    if (Gbl_FileType == ASL_INPUT_TYPE_BINARY_ACPI_TABLE)      {          return (AE_OK);      } diff --git a/source/compiler/aslglobal.h b/source/compiler/aslglobal.h index e78e58f76f3a..4e89c12ccb6e 100644 --- a/source/compiler/aslglobal.h +++ b/source/compiler/aslglobal.h @@ -197,6 +197,7 @@ ASL_EXTERN char                     ASL_INIT_GLOBAL (*Gbl_OutputFilenamePrefix,  ASL_EXTERN ASL_INCLUDE_DIR          ASL_INIT_GLOBAL (*Gbl_IncludeDirList, NULL);  ASL_EXTERN char                     *Gbl_CurrentInputFilename;  ASL_EXTERN char                     ASL_INIT_GLOBAL (*Gbl_ExternalRefFilename, NULL); +ASL_EXTERN char                     ASL_INIT_GLOBAL (*Gbl_PreviousIncludeFilename, NULL);  ASL_EXTERN BOOLEAN                  ASL_INIT_GLOBAL (Gbl_HasIncludeFiles, FALSE); @@ -246,7 +247,6 @@ ASL_EXTERN ASL_LISTING_NODE         ASL_INIT_GLOBAL (*Gbl_ListingNode, NULL);  ASL_EXTERN ACPI_PARSE_OBJECT        *Gbl_FirstLevelInsertionNode;  ASL_EXTERN UINT8                    ASL_INIT_GLOBAL (Gbl_FileType, 0);  ASL_EXTERN char                     ASL_INIT_GLOBAL (*Gbl_Signature, NULL); -ASL_EXTERN char                     *Gbl_TemplateSignature;  ASL_EXTERN UINT32                   ASL_INIT_GLOBAL (Gbl_CurrentHexColumn, 0);  ASL_EXTERN UINT32                   ASL_INIT_GLOBAL (Gbl_CurrentAmlOffset, 0); diff --git a/source/compiler/asllisting.c b/source/compiler/asllisting.c index 91ddcac43a23..c41b80e96c9d 100644 --- a/source/compiler/asllisting.c +++ b/source/compiler/asllisting.c @@ -277,6 +277,34 @@ LsTreeWriteWalk (      UtPrintFormattedName (Op->Asl.ParseOpcode, Level); +    if (Op->Asl.ParseOpcode == PARSEOP_NAMESEG) +    { +        DbgPrint (ASL_TREE_OUTPUT, +            "%10.4s      ", Op->Asl.Value.Name); +    } +    else if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || +        (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) +    { +        DbgPrint (ASL_TREE_OUTPUT, +            "%10.32s      ", Op->Asl.Value.String); +    } +    else if (Op->Asl.ParseOpcode == PARSEOP_INCLUDE) +    { +        DbgPrint (ASL_TREE_OUTPUT, +            "Open: %s\n", Op->Asl.Value.String); +        return (AE_OK); +    } +    else if (Op->Asl.ParseOpcode == PARSEOP_INCLUDE_END) +    { +        DbgPrint (ASL_TREE_OUTPUT, +            "Close: %s\n", Op->Asl.Filename); +        return (AE_OK); +    } +    else +    { +        DbgPrint (ASL_TREE_OUTPUT, "                "); +    } +      DbgPrint (ASL_TREE_OUTPUT, "    (%.4X) Flags %8.8X",          Op->Asl.ParseOpcode, Op->Asl.CompileFlags);      TrPrintNodeCompileFlags (Op->Asl.CompileFlags); @@ -428,7 +456,7 @@ LsWriteNodeToListing (          /* Create a new listing node and push it */ -        LsPushNode (Op->Asl.Child->Asl.Value.String); +        LsPushNode (Op->Asl.Value.String);          return; diff --git a/source/compiler/aslmain.c b/source/compiler/aslmain.c index c0a3d3f660ed..795a04705ef1 100644 --- a/source/compiler/aslmain.c +++ b/source/compiler/aslmain.c @@ -127,7 +127,8 @@ Usage (      printf ("\nGeneral:\n");      ACPI_OPTION ("-@ <file>",       "Specify command file");      ACPI_OPTION ("-I <dir>",        "Specify additional include directory"); -    ACPI_OPTION ("-T <sig>|ALL|*",  "Create table template file for ACPI <Sig>"); +    ACPI_OPTION ("-T <sig list>|ALL",   "Create ACPI table template/example files"); +    ACPI_OPTION ("-T <count>",      "Emit DSDT and <count> SSDTs to same file");      ACPI_OPTION ("-p <prefix>",     "Specify path/filename prefix for all output files");      ACPI_OPTION ("-v",              "Display compiler version");      ACPI_OPTION ("-vo",             "Enable optimization comments"); diff --git a/source/compiler/aslmap.c b/source/compiler/aslmap.c index a69d5c0e41e5..e34c22301fa1 100644 --- a/source/compiler/aslmap.c +++ b/source/compiler/aslmap.c @@ -313,7 +313,7 @@ const ASL_MAPPING_ENTRY     AslKeywordMapping [] =  /* NOR */                       OP_TABLE_ENTRY (AML_BIT_NOR_OP,             0,                              0,                  ACPI_BTYPE_INTEGER),  /* NOT */                       OP_TABLE_ENTRY (AML_BIT_NOT_OP,             0,                              0,                  ACPI_BTYPE_INTEGER),  /* NOTIFY */                    OP_TABLE_ENTRY (AML_NOTIFY_OP,              0,                              0,                  0), -/* OBJECTTYPE */                OP_TABLE_ENTRY (AML_TYPE_OP,                0,                              0,                  ACPI_BTYPE_INTEGER), +/* OBJECTTYPE */                OP_TABLE_ENTRY (AML_OBJECT_TYPE_OP,         0,                              0,                  ACPI_BTYPE_INTEGER),  /* OBJECTTYPE_BFF */            OP_TABLE_ENTRY (AML_BYTE_OP,                ACPI_TYPE_BUFFER_FIELD,         0,                  0),  /* OBJECTTYPE_BUF */            OP_TABLE_ENTRY (AML_BYTE_OP,                ACPI_TYPE_BUFFER,               0,                  0),  /* OBJECTTYPE_DDB */            OP_TABLE_ENTRY (AML_BYTE_OP,                ACPI_TYPE_DDB_HANDLE,           0,                  0), diff --git a/source/compiler/aslopcodes.c b/source/compiler/aslopcodes.c index 29e9d795c7be..e0b73ec50869 100644 --- a/source/compiler/aslopcodes.c +++ b/source/compiler/aslopcodes.c @@ -1510,7 +1510,6 @@ OpcGenerateAmlOpcode (      case PARSEOP_INCLUDE: -        Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;          Gbl_HasIncludeFiles = TRUE;          break; diff --git a/source/compiler/asloptions.c b/source/compiler/asloptions.c index 2473a8d142cb..1f7462aaf862 100644 --- a/source/compiler/asloptions.c +++ b/source/compiler/asloptions.c @@ -107,7 +107,7 @@ AslCommandLine (      if (Gbl_DoTemplates)      { -        Status = DtCreateTemplates (Gbl_TemplateSignature); +        Status = DtCreateTemplates (argv);          if (ACPI_FAILURE (Status))          {              exit (-1); @@ -662,7 +662,6 @@ AslDoOptions (      case 'T':   /* Create a ACPI table template file */          Gbl_DoTemplates = TRUE; -        Gbl_TemplateSignature = AcpiGbl_Optarg;          break;      case 'v':   /* Version and verbosity settings */ diff --git a/source/compiler/aslrules.y b/source/compiler/aslrules.y index 79accf4dd2e0..f8329e9cb1c4 100644 --- a/source/compiler/aslrules.y +++ b/source/compiler/aslrules.y @@ -427,6 +427,7 @@ String  CompilerDirective      : IncludeTerm                   {} +    | IncludeEndTerm                {}      | ExternalTerm                  {}      ; @@ -1033,14 +1034,13 @@ IfTerm      ;  IncludeTerm -    : PARSEOP_INCLUDE '('           {$<n>$ = TrCreateLeafNode (PARSEOP_INCLUDE);} -        String  ')'                 {TrLinkChildren ($<n>3,1,$4);FlOpenIncludeFile ($4);} -        TermList -        IncludeEndTerm              {$$ = TrLinkPeerNodes (3,$<n>3,$7,$8);} +    : PARSEOP_INCLUDE '(' +        String  ')'                 {$$ = TrUpdateNode (PARSEOP_INCLUDE, $3); +                                        FlOpenIncludeFile ($3);}      ;  IncludeEndTerm -    : PARSEOP_INCLUDE_END           {$$ = TrCreateLeafNode (PARSEOP_INCLUDE_END);} +    : PARSEOP_INCLUDE_END           {$<n>$ = TrCreateLeafNode (PARSEOP_INCLUDE_END); TrSetCurrentFilename ($$);}      ;  IncTerm diff --git a/source/compiler/aslstartup.c b/source/compiler/aslstartup.c index c04ae9c12f6a..017b4f899382 100644 --- a/source/compiler/aslstartup.c +++ b/source/compiler/aslstartup.c @@ -144,62 +144,63 @@ AslDetectSourceFileType (      ASL_FILE_INFO           *Info)  {      char                    *FileChar; -    UINT8                   Type; +    UINT8                   Type = ASL_INPUT_TYPE_ASCII_DATA; /* default */      ACPI_STATUS             Status; -    /* Check for a valid binary ACPI table */ +    /* Check for 100% ASCII source file (comments are ignored) */ -    Status = FlCheckForAcpiTable (Info->Handle); +    Status = FlIsFileAsciiSource (Info->Filename, FALSE);      if (ACPI_SUCCESS (Status))      { -        Type = ASL_INPUT_TYPE_ACPI_TABLE; -        goto Cleanup; -    } +        /* +         * File contains ASCII source code. Determine if this is an ASL +         * file or an ACPI data table file. +         */ +        while (fgets (Gbl_CurrentLineBuffer, Gbl_LineBufferSize, Info->Handle)) +        { +            /* Uppercase the buffer for caseless compare */ -    /* Check for 100% ASCII source file (comments are ignored) */ +            FileChar = Gbl_CurrentLineBuffer; +            while (*FileChar) +            { +                *FileChar = (char) toupper ((int) *FileChar); +                FileChar++; +            } -    Status = FlCheckForAscii (Info->Filename, TRUE); -    if (ACPI_FAILURE (Status)) -    { -        printf ("Invalid characters in input file - %s\n", Info->Filename); +            /* Presence of "DefinitionBlock" indicates actual ASL code */ -        if (!Gbl_IgnoreErrors) -        { -            Type = ASL_INPUT_TYPE_BINARY; -            goto Cleanup; +            if (strstr (Gbl_CurrentLineBuffer, "DEFINITIONBLOCK")) +            { +                /* Appears to be an ASL file */ + +                Type = ASL_INPUT_TYPE_ASCII_ASL; +                goto Cleanup; +            }          } -    } -    /* -     * File is ASCII. Determine if this is an ASL file or an ACPI data -     * table file. -     */ -    while (fgets (Gbl_CurrentLineBuffer, Gbl_LineBufferSize, Info->Handle)) -    { -        /* Uppercase the buffer for caseless compare */ +        /* Appears to be an ASCII data table source file */ -        FileChar = Gbl_CurrentLineBuffer; -        while (*FileChar) -        { -            *FileChar = (char) toupper ((int) *FileChar); -            FileChar++; -        } +        Type = ASL_INPUT_TYPE_ASCII_DATA; +        goto Cleanup; +    } -        /* Presence of "DefinitionBlock" indicates actual ASL code */ +    /* We have some sort of binary table, check for valid ACPI table */ -        if (strstr (Gbl_CurrentLineBuffer, "DEFINITIONBLOCK")) -        { -            /* Appears to be an ASL file */ +    fseek (Info->Handle, 0, SEEK_SET); -            Type = ASL_INPUT_TYPE_ASCII_ASL; -            goto Cleanup; -        } +    Status = AcValidateTableHeader (Info->Handle, 0); +    if (ACPI_SUCCESS (Status)) +    { +        fprintf (stderr, +            "Binary file appears to be a valid ACPI table, disassembling\n"); + +        Type = ASL_INPUT_TYPE_BINARY_ACPI_TABLE; +        goto Cleanup;      } -    /* Not an ASL source file, default to a data table source file */ +    Type = ASL_INPUT_TYPE_BINARY; -    Type = ASL_INPUT_TYPE_ASCII_DATA;  Cleanup: @@ -248,7 +249,7 @@ AslDoDisassembly (      /* Handle additional output files for disassembler */ -    Gbl_FileType = ASL_INPUT_TYPE_ACPI_TABLE; +    Gbl_FileType = ASL_INPUT_TYPE_BINARY_ACPI_TABLE;      Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix);      /* This is where the disassembly happens */ @@ -454,7 +455,7 @@ AslDoOneFile (      /*       * Binary ACPI table was auto-detected, disassemble it       */ -    case ASL_INPUT_TYPE_ACPI_TABLE: +    case ASL_INPUT_TYPE_BINARY_ACPI_TABLE:          /* We have what appears to be an ACPI table, disassemble it */ diff --git a/source/compiler/aslsupport.l b/source/compiler/aslsupport.l index 0016626e41f0..cd38564d2a6f 100644 --- a/source/compiler/aslsupport.l +++ b/source/compiler/aslsupport.l @@ -196,9 +196,13 @@ AslPopInputFileStack (      ASL_FILE_NODE           *Fnode; +    Gbl_PreviousIncludeFilename = Gbl_Files[ASL_FILE_INPUT].Filename;      Fnode = Gbl_IncludeFileStack;      DbgPrint (ASL_PARSE_OUTPUT, -        "\nPop InputFile Stack, Fnode %p\n\n", Fnode); +        "\nPop InputFile Stack, Fnode %p\n", Fnode); + +    DbgPrint (ASL_PARSE_OUTPUT, +        "Include: Closing \"%s\"\n\n", Gbl_Files[ASL_FILE_INPUT].Filename);      if (!Fnode)      { diff --git a/source/compiler/asltree.c b/source/compiler/asltree.c index 0d800654f6ca..5067640742d4 100644 --- a/source/compiler/asltree.c +++ b/source/compiler/asltree.c @@ -157,10 +157,30 @@ TrReleaseNode (  /*******************************************************************************   * + * FUNCTION:    TrSetCurrentFilename + * + * PARAMETERS:  Op                  - An existing parse node + * + * RETURN:      None + * + * DESCRIPTION: Save the include file filename. Used for debug output only. + * + ******************************************************************************/ + +void +TrSetCurrentFilename ( +    ACPI_PARSE_OBJECT       *Op) +{ +    Op->Asl.Filename = Gbl_PreviousIncludeFilename; +} + + +/******************************************************************************* + *   * FUNCTION:    TrUpdateNode   *   * PARAMETERS:  ParseOpcode         - New opcode to be assigned to the node - *              Op                - An existing parse node + *              Op                  - An existing parse node   *   * RETURN:      The updated node   * diff --git a/source/compiler/aslutils.c b/source/compiler/aslutils.c index 47851bddad88..e73f22747429 100644 --- a/source/compiler/aslutils.c +++ b/source/compiler/aslutils.c @@ -46,7 +46,9 @@  #include "acdisasm.h"  #include "acnamesp.h"  #include "amlcode.h" -#include <acapps.h> +#include "acapps.h" +#include <sys/stat.h> +  #define _COMPONENT          ACPI_COMPILER          ACPI_MODULE_NAME    ("aslutils") @@ -65,6 +67,40 @@ UtAttachNameseg (      char                    *Name); +/****************************************************************************** + * + * FUNCTION:    UtQueryForOverwrite + * + * PARAMETERS:  Pathname            - Output filename + * + * RETURN:      TRUE if file does not exist or overwrite is authorized + * + * DESCRIPTION: Query for file overwrite if it already exists. + * + ******************************************************************************/ + +BOOLEAN +UtQueryForOverwrite ( +    char                    *Pathname) +{ +    struct stat             StatInfo; + + +    if (!stat (Pathname, &StatInfo)) +    { +        fprintf (stderr, "Target file \"%s\" already exists, overwrite? [y|n] ", +            Pathname); + +        if (getchar () != 'y') +        { +            return (FALSE); +        } +    } + +    return (TRUE); +} + +  /*******************************************************************************   *   * FUNCTION:    UtDisplaySupportedTables @@ -449,9 +485,11 @@ UtDisplaySummary (              if (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)              {                  FlPrintFile (FileId, -                    "%-14s %s - %u bytes, %u named objects, %u executable opcodes\n", +                    "%-14s %s - %u bytes, %u named objects, " +                    "%u executable opcodes\n",                      "AML Output:", -                    Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, Gbl_TableLength, +                    Gbl_Files[ASL_FILE_AML_OUTPUT].Filename, +                    FlGetFileSize (ASL_FILE_AML_OUTPUT),                      TotalNamedObjects, TotalExecutableOpcodes);              }          } diff --git a/source/compiler/aslwalks.c b/source/compiler/aslwalks.c index 9485a0ae68b4..16810b49a721 100644 --- a/source/compiler/aslwalks.c +++ b/source/compiler/aslwalks.c @@ -859,21 +859,8 @@ AnAnalyzeStoreOperator (      case PARSEOP_DEREFOF:      case PARSEOP_REFOF:      case PARSEOP_INDEX: - -        return; -      case PARSEOP_METHODCALL: -        /* -         * A target is not allowed to be a method call. -         * It is technically allowed to be a method call, but this only -         * makes sense in one case: if the method returns a reference object, -         * which will then allow the Store to complete successfully. -         * However, this is not supported by the ACPICA interpreter, -         * and not supported by the MS ASL compiler -         * at this time. (09/2015) -         */ -        AslError (ASL_ERROR, ASL_MSG_UNSUPPORTED, -            TargetOperandOp, "Method invocation cannot be a target"); +          return;      default: diff --git a/source/compiler/dttemplate.c b/source/compiler/dttemplate.c index 622e2011038f..aa47a2a7ce3e 100644 --- a/source/compiler/dttemplate.c +++ b/source/compiler/dttemplate.c @@ -57,14 +57,27 @@ AcpiUtIsSpecialTable (      char                    *Signature);  static ACPI_STATUS +DtCreateOneTemplateFile ( +    char                    *Signature, +    UINT32                  TableCount); + +static ACPI_STATUS  DtCreateOneTemplate (      char                    *Signature, +    UINT32                  TableCount,      const ACPI_DMTABLE_DATA *TableData);  static ACPI_STATUS  DtCreateAllTemplates (      void); +static int +DtEmitDefinitionBlock ( +    FILE                    *File, +    char                    *Filename, +    char                    *Signature, +    UINT32                  Instance); +  /*******************************************************************************   * @@ -101,7 +114,7 @@ AcpiUtIsSpecialTable (   *   * FUNCTION:    DtCreateTemplates   * - * PARAMETERS:  Signature           - ACPI table signature + * PARAMETERS:  argv                - Standard command line arguments   *   * RETURN:      Status   * @@ -111,32 +124,115 @@ AcpiUtIsSpecialTable (  ACPI_STATUS  DtCreateTemplates ( -    char                    *Signature) +    char                    **argv)  { -    const ACPI_DMTABLE_DATA *TableData; -    ACPI_STATUS             Status; +    char                    *Signature; +    char                    *End; +    unsigned long           TableCount; +    ACPI_STATUS             Status = AE_OK;      AslInitializeGlobals (); -    /* Default (no signature) is DSDT */ +    Status = AdInitialize (); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    /* +     * Special cases for DSDT, ALL, and '*' +     */ + +    /* Default (no signature option) is DSDT */ -    if (!Signature) +    if (AcpiGbl_Optind < 3)      { -        Signature = "DSDT"; -        goto GetTemplate; +        Status = DtCreateOneTemplateFile (ACPI_SIG_DSDT, 0); +        goto Exit;      } +    AcpiGbl_Optind--; +    Signature = argv[AcpiGbl_Optind];      AcpiUtStrupr (Signature); -    if (!strcmp (Signature, "ALL") || -        !strcmp (Signature, "*")) + +    /* +     * Multiple SSDT support (-T <ssdt count>) +     */ +    TableCount = strtoul (Signature, &End, 0); +    if (Signature != End) +    { +        /* The count is used for table ID and method name - max is 254(+1) */ + +        if (TableCount > 254) +        { +            fprintf (stderr, "%u SSDTs requested, maximum is 254\n", +                (unsigned int) TableCount); + +            Status = AE_LIMIT; +            goto Exit; +        } + +        Status = DtCreateOneTemplateFile (ACPI_SIG_DSDT, TableCount); +        goto Exit; +    } + +    if (!strcmp (Signature, "ALL"))      {          /* Create all available/known templates */          Status = DtCreateAllTemplates (); -        return (Status); +        goto Exit; +    } + +    /* +     * Normal case: Create template for each signature +     */ +    while (argv[AcpiGbl_Optind]) +    { +        Signature = argv[AcpiGbl_Optind]; +        AcpiUtStrupr (Signature); + +        Status = DtCreateOneTemplateFile (Signature, 0); +        if (ACPI_FAILURE (Status)) +        { +            goto Exit; +        } + +        AcpiGbl_Optind++;      } + +Exit: +    /* Shutdown ACPICA subsystem */ + +    (void) AcpiTerminate (); +    CmDeleteCaches (); +    return (Status); +} + + +/******************************************************************************* + * + * FUNCTION:    DtCreateOneTemplateFile + * + * PARAMETERS:  Signature           - ACPI table signature + * + * RETURN:      Status + * + * DESCRIPTION: Create one template file of the requested signature. + * + ******************************************************************************/ + +static ACPI_STATUS +DtCreateOneTemplateFile ( +    char                    *Signature, +    UINT32                  TableCount) +{ +    const ACPI_DMTABLE_DATA *TableData; +    ACPI_STATUS             Status; + +      /*       * Validate signature and get the template data:       *  1) Signature must be 4 characters @@ -146,8 +242,8 @@ DtCreateTemplates (      if (strlen (Signature) != ACPI_NAME_SIZE)      {          fprintf (stderr, -            "%s: Invalid ACPI table signature (length must be 4 characters)\n", -            Signature); +            "%s: Invalid ACPI table signature " +            "(length must be 4 characters)\n", Signature);          return (AE_ERROR);      } @@ -164,7 +260,8 @@ DtCreateTemplates (          Signature = "FACP";      } -GetTemplate: +    /* TableData will point to the template */ +      TableData = AcpiDmGetTableData (Signature);      if (TableData)      { @@ -181,18 +278,7 @@ GetTemplate:          return (AE_ERROR);      } -    Status = AdInitialize (); -    if (ACPI_FAILURE (Status)) -    { -        return (Status); -    } - -    Status = DtCreateOneTemplate (Signature, TableData); - -    /* Shutdown ACPICA subsystem */ - -    (void) AcpiTerminate (); -    CmDeleteCaches (); +    Status = DtCreateOneTemplate (Signature, TableCount, TableData);      return (Status);  } @@ -217,12 +303,6 @@ DtCreateAllTemplates (      ACPI_STATUS             Status; -    Status = AdInitialize (); -    if (ACPI_FAILURE (Status)) -    { -        return (Status); -    } -      fprintf (stderr, "Creating all supported Template files\n");      /* Walk entire ACPI table data structure */ @@ -234,7 +314,7 @@ DtCreateAllTemplates (          if (TableData->Template)          {              Status = DtCreateOneTemplate (TableData->Signature, -                TableData); +                0, TableData);              if (ACPI_FAILURE (Status))              {                  return (Status); @@ -247,25 +327,31 @@ DtCreateAllTemplates (       * 1) DSDT/SSDT are AML tables, not data tables       * 2) FACS and RSDP have non-standard headers       */ -    Status = DtCreateOneTemplate (ACPI_SIG_DSDT, NULL); +    Status = DtCreateOneTemplate (ACPI_SIG_DSDT, 0, NULL);      if (ACPI_FAILURE (Status))      {          return (Status);      } -    Status = DtCreateOneTemplate (ACPI_SIG_SSDT, NULL); +    Status = DtCreateOneTemplate (ACPI_SIG_SSDT, 0, NULL);      if (ACPI_FAILURE (Status))      {          return (Status);      } -    Status = DtCreateOneTemplate (ACPI_SIG_FACS, NULL); +    Status = DtCreateOneTemplate (ACPI_SIG_OSDT, 0, NULL);      if (ACPI_FAILURE (Status))      {          return (Status);      } -    Status = DtCreateOneTemplate (ACPI_RSDP_NAME, NULL); +    Status = DtCreateOneTemplate (ACPI_SIG_FACS, 0, NULL); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    Status = DtCreateOneTemplate (ACPI_RSDP_NAME, 0, NULL);      if (ACPI_FAILURE (Status))      {          return (Status); @@ -280,6 +366,7 @@ DtCreateAllTemplates (   * FUNCTION:    DtCreateOneTemplate   *   * PARAMETERS:  Signature           - ACPI signature, NULL terminated. + *              TableCount          - Used for SSDTs in same file as DSDT   *              TableData           - Entry in ACPI table data structure.   *                                    NULL if a special ACPI table.   * @@ -292,12 +379,14 @@ DtCreateAllTemplates (  static ACPI_STATUS  DtCreateOneTemplate (      char                    *Signature, +    UINT32                  TableCount,      const ACPI_DMTABLE_DATA  *TableData)  {      char                    *DisasmFilename;      FILE                    *File;      ACPI_STATUS             Status = AE_OK; -    ACPI_SIZE               Actual; +    int                     Actual; +    UINT32                  i;      /* New file will have a .asl suffix */ @@ -310,13 +399,17 @@ DtCreateOneTemplate (          return (AE_ERROR);      } -    /* Probably should prompt to overwrite the file */ -      AcpiUtStrlwr (DisasmFilename); +    if (!UtQueryForOverwrite (DisasmFilename)) +    { +        return (AE_ERROR); +    } +      File = fopen (DisasmFilename, "w+");      if (!File)      { -        fprintf (stderr, "Could not open output file %s\n", DisasmFilename); +        fprintf (stderr, "Could not open output file %s\n", +            DisasmFilename);          return (AE_ERROR);      } @@ -327,8 +420,16 @@ DtCreateOneTemplate (      AcpiOsPrintf ("/*\n");      AcpiOsPrintf (ACPI_COMMON_HEADER ("iASL Compiler/Disassembler", " * ")); -    AcpiOsPrintf (" * Template for [%4.4s] ACPI Table", -        Signature); +    if (TableCount == 0) +    { +        AcpiOsPrintf (" * Template for [%4.4s] ACPI Table", +            Signature); +    } +    else +    { +        AcpiOsPrintf (" * Template for [%4.4s] and %u [SSDT] ACPI Tables", +            Signature, TableCount); +    }      /* Dump the actual ACPI table */ @@ -354,45 +455,55 @@ DtCreateOneTemplate (      }      else      { -        /* Special ACPI tables - DSDT, SSDT, OSDT, FADT, RSDP */ +        /* Special ACPI tables - DSDT, SSDT, OSDT, FACS, RSDP */          AcpiOsPrintf (" (AML byte code table)\n"); -          AcpiOsPrintf (" */\n"); +          if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT))          { -            Actual = fwrite (TemplateDsdt, 1, sizeof (TemplateDsdt) -1, File); -            if (Actual != sizeof (TemplateDsdt) -1) +            Actual = DtEmitDefinitionBlock ( +                File, DisasmFilename, ACPI_SIG_DSDT, 1); +            if (Actual < 0)              { -                fprintf (stderr, -                    "Could not write to output file %s\n", DisasmFilename);                  Status = AE_ERROR;                  goto Cleanup;              } + +            /* Emit any requested SSDTs into the same file */ + +            for (i = 1; i <= TableCount; i++) +            { +                Actual = DtEmitDefinitionBlock ( +                    File, DisasmFilename, ACPI_SIG_SSDT, i + 1); +                if (Actual < 0) +                { +                    Status = AE_ERROR; +                    goto Cleanup; +                } +            }          }          else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT))          { -            Actual = fwrite (TemplateSsdt, 1, sizeof (TemplateSsdt) -1, File); -            if (Actual != sizeof (TemplateSsdt) -1) +            Actual = DtEmitDefinitionBlock ( +                File, DisasmFilename, ACPI_SIG_SSDT, 1); +            if (Actual < 0)              { -                fprintf (stderr, -                    "Could not write to output file %s\n", DisasmFilename);                  Status = AE_ERROR;                  goto Cleanup;              }          }          else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_OSDT))          { -            Actual = fwrite (TemplateOsdt, 1, sizeof (TemplateOsdt) -1, File); -            if (Actual != sizeof (TemplateOsdt) -1) +            Actual = DtEmitDefinitionBlock ( +                File, DisasmFilename, ACPI_SIG_OSDT, 1); +            if (Actual < 0)              { -                fprintf (stderr, -                    "Could not write to output file %s\n", DisasmFilename);                  Status = AE_ERROR;                  goto Cleanup;              }          } -        else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) /* FADT */ +        else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))          {              AcpiDmDumpDataTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER,                  TemplateFacs)); @@ -411,12 +522,72 @@ DtCreateOneTemplate (          }      } -    fprintf (stderr, -        "Created ACPI table template for [%4.4s], written to \"%s\"\n", -        Signature, DisasmFilename); +    if (TableCount == 0) +    { +        fprintf (stderr, +            "Created ACPI table template for [%4.4s], " +            "written to \"%s\"\n", +            Signature, DisasmFilename); +    } +    else +    { +        fprintf (stderr, +            "Created ACPI table templates for [%4.4s] " +            "and %u [SSDT], written to \"%s\"\n", +            Signature, TableCount, DisasmFilename); +    }  Cleanup:      fclose (File);      AcpiOsRedirectOutput (stdout);      return (Status);  } + + +/******************************************************************************* + * + * FUNCTION:    DtEmitDefinitionBlock + * + * PARAMETERS:  File                - An open file for the block + *              Filename            - Filename for same, for error msg(s) + *              Signature           - ACPI signature for the block + *              Instance            - Used for multiple SSDTs in the same file + * + * RETURN:      Status from fprintf + * + * DESCRIPTION: Emit the raw ASL for a complete Definition Block (DSDT or SSDT) + * + * Note: The AMLFileName parameter for DefinitionBlock is left as a NULL + * string. This allows the compiler to create the output AML filename from + * the input filename. + * + ******************************************************************************/ + +static int +DtEmitDefinitionBlock ( +    FILE                    *File, +    char                    *Filename, +    char                    *Signature, +    UINT32                  Instance) +{ +    int                     Status; + + +    Status = fprintf (File, +        "DefinitionBlock (\"\", \"%4.4s\", 2, \"Intel\", \"_%4.4s_%.2X\", 0x00000001)\n" +        "{\n" +        "    Method (%2.2s%.2X)\n" +        "    {\n" +        "    }\n" +        "}\n\n", +        Signature, Signature, Instance, Signature, Instance); + +    if (Status < 0) +    { +        fprintf (stderr, +            "Could not write %4.4s to output file %s\n", +            Signature, Filename); +    } + +    return (Status); +} diff --git a/source/compiler/dttemplate.h b/source/compiler/dttemplate.h index 6f3ed6407012..031eb9b5bdd6 100644 --- a/source/compiler/dttemplate.h +++ b/source/compiler/dttemplate.h @@ -45,36 +45,6 @@  #define __DTTEMPLATE_H -/* Special templates for the ASL/AML tables: DSDT, SSDT, and OSDT */ - -const char TemplateDsdt[] = -    "DefinitionBlock (\"dsdt.aml\", \"DSDT\", 2, \"Intel\", \"Template\", 0x00000001)\n" -    "{\n" -    "    Method (MAIN, 0, NotSerialized)\n" -    "    {\n" -    "        Return (Zero)\n" -    "    }\n" -    "}\n\n"; - -const char TemplateSsdt[] = -    "DefinitionBlock (\"ssdt.aml\", \"SSDT\", 2, \"Intel\", \"Template\", 0x00000001)\n" -    "{\n" -    "    Method (MAIN, 0, NotSerialized)\n" -    "    {\n" -    "        Return (Zero)\n" -    "    }\n" -    "}\n\n"; - -const char TemplateOsdt[] = -    "DefinitionBlock (\"osdt.aml\", \"OSDT\", 2, \"Intel\", \"Template\", 0x00000001)\n" -    "{\n" -    "    Method (MAIN, 0, NotSerialized)\n" -    "    {\n" -    "        Return (Zero)\n" -    "    }\n" -    "}\n\n"; - -  /* Templates for ACPI data tables */  const unsigned char TemplateAsf[] = diff --git a/source/components/debugger/dbdisply.c b/source/components/debugger/dbdisply.c index 09d1232a74ea..75a29b526717 100644 --- a/source/components/debugger/dbdisply.c +++ b/source/components/debugger/dbdisply.c @@ -48,6 +48,7 @@  #include "acnamesp.h"  #include "acparser.h"  #include "acinterp.h" +#include "acevents.h"  #include "acdebug.h" @@ -1034,26 +1035,21 @@ AcpiDbDisplayHandlers (          for (i = 0; i < ACPI_ARRAY_LENGTH (AcpiGbl_SpaceIdList); i++)          {              SpaceId = AcpiGbl_SpaceIdList[i]; -            HandlerObj = ObjDesc->Device.Handler;              AcpiOsPrintf (ACPI_PREDEFINED_PREFIX,                  AcpiUtGetRegionName ((UINT8) SpaceId), SpaceId); -            while (HandlerObj) +            HandlerObj = AcpiEvFindRegionHandler ( +                SpaceId, ObjDesc->CommonNotify.Handler); +            if (HandlerObj)              { -                if (AcpiGbl_SpaceIdList[i] == -                    HandlerObj->AddressSpace.SpaceId) -                { -                    AcpiOsPrintf (ACPI_HANDLER_PRESENT_STRING, -                        (HandlerObj->AddressSpace.HandlerFlags & -                            ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ? -                            "Default" : "User", -                        HandlerObj->AddressSpace.Handler); - -                    goto FoundHandler; -                } +                AcpiOsPrintf (ACPI_HANDLER_PRESENT_STRING, +                    (HandlerObj->AddressSpace.HandlerFlags & +                        ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ? +                        "Default" : "User", +                    HandlerObj->AddressSpace.Handler); -                HandlerObj = HandlerObj->AddressSpace.Next; +                goto FoundHandler;              }              /* There is no handler for this SpaceId */ @@ -1065,7 +1061,7 @@ AcpiDbDisplayHandlers (          /* Find all handlers for user-defined SpaceIDs */ -        HandlerObj = ObjDesc->Device.Handler; +        HandlerObj = ObjDesc->CommonNotify.Handler;          while (HandlerObj)          {              if (HandlerObj->AddressSpace.SpaceId >= ACPI_USER_REGION_BEGIN) @@ -1176,7 +1172,7 @@ AcpiDbDisplayNonRootHandlers (      /* Display all handlers associated with this device */ -    HandlerObj = ObjDesc->Device.Handler; +    HandlerObj = ObjDesc->CommonNotify.Handler;      while (HandlerObj)      {          AcpiOsPrintf (ACPI_PREDEFINED_PREFIX, diff --git a/source/components/debugger/dbinput.c b/source/components/debugger/dbinput.c index 68043cbed6f8..96d4fb77c8b8 100644 --- a/source/components/debugger/dbinput.c +++ b/source/components/debugger/dbinput.c @@ -1122,7 +1122,7 @@ AcpiDbCommandDispatch (          {              ACPI_NEW_TABLE_DESC     *ListHead = NULL; -            Status = AcpiAcGetAllTablesFromFile (AcpiGbl_DbArgs[1], +            Status = AcGetAllTablesFromFile (AcpiGbl_DbArgs[1],                  ACPI_GET_ALL_TABLES, &ListHead);              if (ACPI_SUCCESS (Status))              { diff --git a/source/components/disassembler/dmopcode.c b/source/components/disassembler/dmopcode.c index 02c51bdefa41..4615ebe86915 100644 --- a/source/components/disassembler/dmopcode.c +++ b/source/components/disassembler/dmopcode.c @@ -60,6 +60,10 @@ static void  AcpiDmMatchKeyword (      ACPI_PARSE_OBJECT       *Op); +static void +AcpiDmConvertToElseIf ( +    ACPI_PARSE_OBJECT       *Op); +  /*******************************************************************************   * @@ -683,6 +687,11 @@ AcpiDmDisassembleOneOp (          return;      } +    if (Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF) +    { +        return; /* ElseIf macro was already emitted */ +    } +      switch (Op->Common.DisasmOpcode)      {      case ACPI_DASM_MATCHOP: @@ -955,6 +964,11 @@ AcpiDmDisassembleOneOp (          AcpiDmNamestring (Op->Common.Value.Name);          break; +    case AML_ELSE_OP: + +        AcpiDmConvertToElseIf (Op); +        break; +      default:          /* Just get the opcode name and print it */ @@ -979,3 +993,113 @@ AcpiDmDisassembleOneOp (          break;      }  } + + +/******************************************************************************* + * + * FUNCTION:    AcpiDmConvertToElseIf + * + * PARAMETERS:  OriginalElseOp          - ELSE Object to be examined + * + * RETURN:      None. Emits either an "Else" or an "ElseIf" ASL operator. + * + * DESCRIPTION: Detect and convert an If..Else..If sequence to If..ElseIf + * + * EXAMPLE: + * + * This If..Else..If nested sequence: + * + *        If (Arg0 == 1) + *        { + *            Local0 = 4 + *        } + *        Else + *        { + *            If (Arg0 == 2) + *            { + *                Local0 = 5 + *            } + *        } + * + * Is converted to this simpler If..ElseIf sequence: + * + *        If (Arg0 == 1) + *        { + *            Local0 = 4 + *        } + *        ElseIf (Arg0 == 2) + *        { + *            Local0 = 5 + *        } + * + * NOTE: There is no actual ElseIf AML opcode. ElseIf is essentially an ASL + * macro that emits an Else opcode followed by an If opcode. This function + * reverses these AML sequences back to an ElseIf macro where possible. This + * can make the disassembled ASL code simpler and more like the original code. + * + ******************************************************************************/ + +static void +AcpiDmConvertToElseIf ( +    ACPI_PARSE_OBJECT       *OriginalElseOp) +{ +    ACPI_PARSE_OBJECT       *IfOp; +    ACPI_PARSE_OBJECT       *ElseOp; + + +    /* Examine the first child of the Else */ + +    IfOp = OriginalElseOp->Common.Value.Arg; +    if (!IfOp || (IfOp->Common.AmlOpcode != AML_IF_OP)) +    { +        /* Not an Else..If sequence, cannot convert to ElseIf */ + +        AcpiOsPrintf ("%s", "Else"); +        return; +    } + +    /* Emit ElseIf, mark the IF as now an ELSEIF */ + +    AcpiOsPrintf ("%s", "ElseIf"); +    IfOp->Common.DisasmFlags |= ACPI_PARSEOP_ELSEIF; + +    /* The IF parent will now be the same as the original ELSE parent */ + +    IfOp->Common.Parent = OriginalElseOp->Common.Parent; + +    /* +     * Update the NEXT pointers to restructure the parse tree, essentially +     * promoting an If..Else block up to the same level as the original +     * Else. +     * +     * Check if the IF has a corresponding ELSE peer +     */ +    ElseOp = IfOp->Common.Next; +    if (ElseOp && +        (ElseOp->Common.AmlOpcode == AML_ELSE_OP)) +    { +        /* If an ELSE matches the IF, promote it also */ + +        ElseOp->Common.Parent = OriginalElseOp->Common.Parent; +        ElseOp->Common.Next = OriginalElseOp->Common.Next; +    } +    else +    { +        /* Otherwise, set the IF NEXT to the original ELSE NEXT */ + +        IfOp->Common.Next = OriginalElseOp->Common.Next; +    } + +    /* Detach the child IF block from the original ELSE */ + +    OriginalElseOp->Common.Value.Arg = NULL; + +    /* Ignore the original ELSE from now on */ + +    OriginalElseOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; +    OriginalElseOp->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX; + +    /* Insert IF (now ELSEIF) as next peer of the original ELSE */ + +    OriginalElseOp->Common.Next = IfOp; +} diff --git a/source/components/disassembler/dmwalk.c b/source/components/disassembler/dmwalk.c index 4a094789a703..664e709d69aa 100644 --- a/source/components/disassembler/dmwalk.c +++ b/source/components/disassembler/dmwalk.c @@ -488,39 +488,40 @@ AcpiDmDescendingOp (      }      else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&           (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) && +         (!(Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF)) &&           (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))      { +        /* +         * This is a first-level element of a term list, +         * indent a new line +         */ +        switch (Op->Common.AmlOpcode) +        { +        case AML_NOOP_OP:              /* -             * This is a first-level element of a term list, -             * indent a new line +             * Optionally just ignore this opcode. Some tables use +             * NoOp opcodes for "padding" out packages that the BIOS +             * changes dynamically. This can leave hundreds or +             * thousands of NoOp opcodes that if disassembled, +             * cannot be compiled because they are syntactically +             * incorrect.               */ -            switch (Op->Common.AmlOpcode) +            if (AcpiGbl_IgnoreNoopOperator)              { -            case AML_NOOP_OP: -                /* -                 * Optionally just ignore this opcode. Some tables use -                 * NoOp opcodes for "padding" out packages that the BIOS -                 * changes dynamically. This can leave hundreds or -                 * thousands of NoOp opcodes that if disassembled, -                 * cannot be compiled because they are syntactically -                 * incorrect. -                 */ -                if (AcpiGbl_IgnoreNoopOperator) -                { -                    Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; -                    return (AE_OK); -                } +                Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; +                return (AE_OK); +            } -                /* Fallthrough */ +            /* Fallthrough */ -            default: +        default: -                AcpiDmIndent (Level); -                break; -            } +            AcpiDmIndent (Level); +            break; +        } -            Info->LastLevel = Level; -            Info->Count = 0; +        Info->LastLevel = Level; +        Info->Count = 0;      }      /* diff --git a/source/components/dispatcher/dsinit.c b/source/components/dispatcher/dsinit.c index 573d0ddf0745..10580a3c6fa6 100644 --- a/source/components/dispatcher/dsinit.c +++ b/source/components/dispatcher/dsinit.c @@ -266,7 +266,7 @@ AcpiDsInitializeObjects (      /* Summary of objects initialized */      ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, -        "Table [%4.4s:%8.8s] (id %.2X) - %4u Objects with %3u Devices, " +        "Table [%4.4s: %-8.8s] (id %.2X) - %4u Objects with %3u Devices, "          "%3u Regions, %4u Methods (%u/%u/%u Serial/Non/Cvt)\n",          Table->Signature, Table->OemTableId, OwnerId, Info.ObjectCount,          Info.DeviceCount,Info.OpRegionCount, Info.MethodCount, diff --git a/source/components/events/evhandler.c b/source/components/events/evhandler.c index e2d5955a089c..eca683f3921d 100644 --- a/source/components/events/evhandler.c +++ b/source/components/events/evhandler.c @@ -60,6 +60,7 @@ AcpiEvInstallHandler (      void                    *Context,      void                    **ReturnValue); +  /* These are the address spaces that will get default handlers */  UINT8        AcpiGbl_DefaultAddressSpaces[ACPI_NUM_DEFAULT_SPACES] = @@ -175,7 +176,7 @@ AcpiEvHasDefaultHandler (      ObjDesc = AcpiNsGetAttachedObject (Node);      if (ObjDesc)      { -        HandlerObj = ObjDesc->Device.Handler; +        HandlerObj = ObjDesc->CommonNotify.Handler;          /* Walk the linked list of handlers for this object */ @@ -276,33 +277,25 @@ AcpiEvInstallHandler (      {          /* Check if this Device already has a handler for this address space */ -        NextHandlerObj = ObjDesc->Device.Handler; -        while (NextHandlerObj) +        NextHandlerObj = AcpiEvFindRegionHandler ( +            HandlerObj->AddressSpace.SpaceId, ObjDesc->CommonNotify.Handler); +        if (NextHandlerObj)          {              /* Found a handler, is it for the same address space? */ -            if (NextHandlerObj->AddressSpace.SpaceId == -                HandlerObj->AddressSpace.SpaceId) -            { -                ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, -                    "Found handler for region [%s] in device %p(%p) " -                    "handler %p\n", -                    AcpiUtGetRegionName (HandlerObj->AddressSpace.SpaceId), -                    ObjDesc, NextHandlerObj, HandlerObj)); - -                /* -                 * Since the object we found it on was a device, then it -                 * means that someone has already installed a handler for -                 * the branch of the namespace from this device on. Just -                 * bail out telling the walk routine to not traverse this -                 * branch. This preserves the scoping rule for handlers. -                 */ -                return (AE_CTRL_DEPTH); -            } - -            /* Walk the linked list of handlers attached to this device */ - -            NextHandlerObj = NextHandlerObj->AddressSpace.Next; +            ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, +                "Found handler for region [%s] in device %p(%p) handler %p\n", +                AcpiUtGetRegionName (HandlerObj->AddressSpace.SpaceId), +                ObjDesc, NextHandlerObj, HandlerObj)); + +            /* +             * Since the object we found it on was a device, then it means +             * that someone has already installed a handler for the branch +             * of the namespace from this device on. Just bail out telling +             * the walk routine to not traverse this branch. This preserves +             * the scoping rule for handlers. +             */ +            return (AE_CTRL_DEPTH);          }          /* @@ -337,6 +330,46 @@ AcpiEvInstallHandler (  /*******************************************************************************   * + * FUNCTION:    AcpiEvFindRegionHandler + * + * PARAMETERS:  SpaceId         - The address space ID + *              HandlerObj      - Head of the handler object list + * + * RETURN:      Matching handler object. NULL if space ID not matched + * + * DESCRIPTION: Search a handler object list for a match on the address + *              space ID. + * + ******************************************************************************/ + +ACPI_OPERAND_OBJECT * +AcpiEvFindRegionHandler ( +    ACPI_ADR_SPACE_TYPE     SpaceId, +    ACPI_OPERAND_OBJECT     *HandlerObj) +{ + +    /* Walk the handler list for this device */ + +    while (HandlerObj) +    { +        /* Same SpaceId indicates a handler is installed */ + +        if (HandlerObj->AddressSpace.SpaceId == SpaceId) +        { +            return (HandlerObj); +        } + +        /* Next handler object */ + +        HandlerObj = HandlerObj->AddressSpace.Next; +    } + +    return (NULL); +} + + +/******************************************************************************* + *   * FUNCTION:    AcpiEvInstallSpaceHandler   *   * PARAMETERS:  Node            - Namespace node for the device @@ -362,17 +395,17 @@ AcpiEvInstallSpaceHandler (  {      ACPI_OPERAND_OBJECT     *ObjDesc;      ACPI_OPERAND_OBJECT     *HandlerObj; -    ACPI_STATUS             Status; +    ACPI_STATUS             Status = AE_OK;      ACPI_OBJECT_TYPE        Type; -    UINT8                  Flags = 0; +    UINT8                   Flags = 0;      ACPI_FUNCTION_TRACE (EvInstallSpaceHandler);      /* -     * This registration is valid for only the types below and the root. This -     * is where the default handlers get placed. +     * This registration is valid for only the types below and the root. +     * The root node is where the default handlers get installed.       */      if ((Node->Type != ACPI_TYPE_DEVICE)     &&          (Node->Type != ACPI_TYPE_PROCESSOR)  && @@ -445,47 +478,39 @@ AcpiEvInstallSpaceHandler (      if (ObjDesc)      {          /* -         * The attached device object already exists. Make sure the handler -         * is not already installed. +         * The attached device object already exists. Now make sure +         * the handler is not already installed.           */ -        HandlerObj = ObjDesc->Device.Handler; +        HandlerObj = AcpiEvFindRegionHandler (SpaceId, +            ObjDesc->CommonNotify.Handler); -        /* Walk the handler list for this device */ - -        while (HandlerObj) +        if (HandlerObj)          { -            /* Same SpaceId indicates a handler already installed */ - -            if (HandlerObj->AddressSpace.SpaceId == SpaceId) +            if (HandlerObj->AddressSpace.Handler == Handler)              { -                if (HandlerObj->AddressSpace.Handler == Handler) -                { -                    /* -                     * It is (relatively) OK to attempt to install the SAME -                     * handler twice. This can easily happen with the -                     * PCI_Config space. -                     */ -                    Status = AE_SAME_HANDLER; -                    goto UnlockAndExit; -                } -                else -                { -                    /* A handler is already installed */ - -                    Status = AE_ALREADY_EXISTS; -                } +                /* +                 * It is (relatively) OK to attempt to install the SAME +                 * handler twice. This can easily happen with the +                 * PCI_Config space. +                 */ +                Status = AE_SAME_HANDLER;                  goto UnlockAndExit;              } +            else +            { +                /* A handler is already installed */ -            /* Walk the linked list of handlers */ +                Status = AE_ALREADY_EXISTS; +            } -            HandlerObj = HandlerObj->AddressSpace.Next; +            goto UnlockAndExit;          }      }      else      {          ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, -            "Creating object on Device %p while installing handler\n", Node)); +            "Creating object on Device %p while installing handler\n", +            Node));          /* ObjDesc does not exist, create one */ @@ -524,7 +549,8 @@ AcpiEvInstallSpaceHandler (      }      ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, -        "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n", +        "Installing address handler for region %s(%X) " +        "on Device %4.4s %p(%p)\n",          AcpiUtGetRegionName (SpaceId), SpaceId,          AcpiUtGetNodeName (Node), Node, ObjDesc)); @@ -549,33 +575,31 @@ AcpiEvInstallSpaceHandler (      HandlerObj->AddressSpace.Node = Node;      HandlerObj->AddressSpace.Handler = Handler;      HandlerObj->AddressSpace.Context = Context; -    HandlerObj->AddressSpace.Setup  = Setup; +    HandlerObj->AddressSpace.Setup = Setup;      /* Install at head of Device.AddressSpace list */ -    HandlerObj->AddressSpace.Next = ObjDesc->Device.Handler; +    HandlerObj->AddressSpace.Next = ObjDesc->CommonNotify.Handler;      /*       * The Device object is the first reference on the HandlerObj.       * Each region that uses the handler adds a reference.       */ -    ObjDesc->Device.Handler = HandlerObj; +    ObjDesc->CommonNotify.Handler = HandlerObj;      /* -     * Walk the namespace finding all of the regions this -     * handler will manage. +     * Walk the namespace finding all of the regions this handler will +     * manage.       * -     * Start at the device and search the branch toward -     * the leaf nodes until either the leaf is encountered or -     * a device is detected that has an address handler of the -     * same type. +     * Start at the device and search the branch toward the leaf nodes +     * until either the leaf is encountered or a device is detected that +     * has an address handler of the same type.       * -     * In either case, back up and search down the remainder -     * of the branch +     * In either case, back up and search down the remainder of the branch       */ -    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX, -        ACPI_NS_WALK_UNLOCK, AcpiEvInstallHandler, NULL, -        HandlerObj, NULL); +    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, +        ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, +        AcpiEvInstallHandler, NULL, HandlerObj, NULL);  UnlockAndExit:      return_ACPI_STATUS (Status); diff --git a/source/components/events/evregion.c b/source/components/events/evregion.c index c2f229270655..7a6ce65b7afa 100644 --- a/source/components/events/evregion.c +++ b/source/components/events/evregion.c @@ -99,6 +99,7 @@ AcpiEvInitializeOpRegions (      /* Run the _REG methods for OpRegions in each default address space */ +    AcpiGbl_RegMethodsEnabled = TRUE;      for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++)      {          /* @@ -109,13 +110,11 @@ AcpiEvInitializeOpRegions (          if (AcpiEvHasDefaultHandler (AcpiGbl_RootNode,                 AcpiGbl_DefaultAddressSpaces[i]))          { -            Status = AcpiEvExecuteRegMethods (AcpiGbl_RootNode, -                AcpiGbl_DefaultAddressSpaces[i]); +            AcpiEvExecuteRegMethods (AcpiGbl_RootNode, +                AcpiGbl_DefaultAddressSpaces[i], ACPI_REG_CONNECT);          }      } -    AcpiGbl_RegMethodsExecuted = TRUE; -      (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);      return_ACPI_STATUS (Status);  } @@ -138,6 +137,12 @@ AcpiEvInitializeOpRegions (   * DESCRIPTION: Dispatch an address space or operation region access to   *              a previously installed handler.   * + * NOTE: During early initialization, we always install the default region + * handlers for Memory, I/O and PCI_Config. This ensures that these operation + * region address spaces are always available as per the ACPI specification. + * This is especially needed in order to support the execution of + * module-level AML code during loading of the ACPI tables. + *   ******************************************************************************/  ACPI_STATUS @@ -320,7 +325,7 @@ AcpiEvAddressSpaceDispatch (           * We just returned from a non-default handler, we must re-enter the           * interpreter           */ -       AcpiExEnterInterpreter (); +        AcpiExEnterInterpreter ();      }      return_ACPI_STATUS (Status); @@ -342,7 +347,7 @@ AcpiEvAddressSpaceDispatch (   ******************************************************************************/  void -AcpiEvDetachRegion( +AcpiEvDetachRegion (      ACPI_OPERAND_OBJECT     *RegionObj,      BOOLEAN                 AcpiNsIsLocked)  { @@ -521,6 +526,13 @@ AcpiEvAttachRegion (      ACPI_FUNCTION_TRACE (EvAttachRegion); +    /* Install the region's handler */ + +    if (RegionObj->Region.Handler) +    { +        return_ACPI_STATUS (AE_ALREADY_EXISTS); +    } +      ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,          "Adding Region [%4.4s] %p to address handler %p [%s]\n",          AcpiUtGetNodeName (RegionObj->Region.Node), @@ -531,18 +543,62 @@ AcpiEvAttachRegion (      RegionObj->Region.Next = HandlerObj->AddressSpace.RegionList;      HandlerObj->AddressSpace.RegionList = RegionObj; +    RegionObj->Region.Handler = HandlerObj; +    AcpiUtAddReference (HandlerObj); -    /* Install the region's handler */ +    return_ACPI_STATUS (AE_OK); +} -    if (RegionObj->Region.Handler) + +/******************************************************************************* + * + * FUNCTION:    AcpiEvAssociateRegMethod + * + * PARAMETERS:  RegionObj           - Region object + * + * RETURN:      Status + * + * DESCRIPTION: Find and associate _REG method to a region + * + ******************************************************************************/ + +void +AcpiEvAssociateRegMethod ( +    ACPI_OPERAND_OBJECT     *RegionObj) +{ +    ACPI_NAME               *RegNamePtr = (ACPI_NAME *) METHOD_NAME__REG; +    ACPI_NAMESPACE_NODE     *MethodNode; +    ACPI_NAMESPACE_NODE     *Node; +    ACPI_OPERAND_OBJECT     *RegionObj2; +    ACPI_STATUS             Status; + + +    ACPI_FUNCTION_TRACE (EvAssociateRegMethod); + + +    RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); +    if (!RegionObj2)      { -        return_ACPI_STATUS (AE_ALREADY_EXISTS); +        return_VOID;      } -    RegionObj->Region.Handler = HandlerObj; -    AcpiUtAddReference (HandlerObj); +    Node = RegionObj->Region.Node->Parent; -    return_ACPI_STATUS (AE_OK); +    /* Find any "_REG" method associated with this region definition */ + +    Status = AcpiNsSearchOneScope ( +        *RegNamePtr, Node, ACPI_TYPE_METHOD, &MethodNode); +    if (ACPI_SUCCESS (Status)) +    { +        /* +         * The _REG method is optional and there can be only one per region +         * definition. This will be executed when the handler is attached +         * or removed +         */ +        RegionObj2->Extra.Method_REG = MethodNode; +    } + +    return_VOID;  } @@ -579,7 +635,19 @@ AcpiEvExecuteRegMethod (          return_ACPI_STATUS (AE_NOT_EXIST);      } -    if (RegionObj2->Extra.Method_REG == NULL) +    if (RegionObj2->Extra.Method_REG == NULL || +        RegionObj->Region.Handler == NULL || +        !AcpiGbl_RegMethodsEnabled) +    { +        return_ACPI_STATUS (AE_OK); +    } + +    /* _REG(DISCONNECT) should be paired with _REG(CONNECT) */ + +    if ((Function == ACPI_REG_CONNECT && +        RegionObj->Common.Flags & AOPOBJ_REG_CONNECTED) || +        (Function == ACPI_REG_DISCONNECT && +         !(RegionObj->Common.Flags & AOPOBJ_REG_CONNECTED)))      {          return_ACPI_STATUS (AE_OK);      } @@ -631,6 +699,20 @@ AcpiEvExecuteRegMethod (      Status = AcpiNsEvaluate (Info);      AcpiUtRemoveReference (Args[1]); +    if (ACPI_FAILURE (Status)) +    { +        goto Cleanup2; +    } + +    if (Function == ACPI_REG_CONNECT) +    { +        RegionObj->Common.Flags |= AOPOBJ_REG_CONNECTED; +    } +    else +    { +        RegionObj->Common.Flags &= ~AOPOBJ_REG_CONNECTED; +    } +  Cleanup2:      AcpiUtRemoveReference (Args[0]); @@ -646,26 +728,28 @@ Cleanup1:   *   * PARAMETERS:  Node            - Namespace node for the device   *              SpaceId         - The address space ID + *              Function        - Passed to _REG: On (1) or Off (0)   * - * RETURN:      Status + * RETURN:      None   *   * DESCRIPTION: Run all _REG methods for the input Space ID;   *              Note: assumes namespace is locked, or system init time.   *   ******************************************************************************/ -ACPI_STATUS +void  AcpiEvExecuteRegMethods (      ACPI_NAMESPACE_NODE     *Node, -    ACPI_ADR_SPACE_TYPE     SpaceId) +    ACPI_ADR_SPACE_TYPE     SpaceId, +    UINT32                  Function)  { -    ACPI_STATUS             Status;      ACPI_REG_WALK_INFO      Info;      ACPI_FUNCTION_TRACE (EvExecuteRegMethods);      Info.SpaceId = SpaceId; +    Info.Function = Function;      Info.RegRunCount = 0;      ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, @@ -678,7 +762,7 @@ AcpiEvExecuteRegMethods (       * regions and _REG methods. (i.e. handlers must be installed for all       * regions of this Space ID before we can run any _REG methods)       */ -    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX, +    (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX,          ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, NULL, &Info, NULL);      /* Special case for EC: handle "orphan" _REG methods with no region */ @@ -692,7 +776,7 @@ AcpiEvExecuteRegMethods (          "    Executed %u _REG methods for SpaceId %s\n",          Info.RegRunCount, AcpiUtGetRegionName (Info.SpaceId))); -    return_ACPI_STATUS (Status); +    return_VOID;  } @@ -759,7 +843,7 @@ AcpiEvRegRun (      }      Info->RegRunCount++; -    Status = AcpiEvExecuteRegMethod (ObjDesc, ACPI_REG_CONNECT); +    Status = AcpiEvExecuteRegMethod (ObjDesc, Info->Function);      return (Status);  } diff --git a/source/components/events/evrgnini.c b/source/components/events/evrgnini.c index cc0240d9de17..6bb0e6e5bdff 100644 --- a/source/components/events/evrgnini.c +++ b/source/components/events/evrgnini.c @@ -567,9 +567,6 @@ AcpiEvInitializeRegion (      ACPI_ADR_SPACE_TYPE     SpaceId;      ACPI_NAMESPACE_NODE     *Node;      ACPI_STATUS             Status; -    ACPI_NAMESPACE_NODE     *MethodNode; -    ACPI_NAME               *RegNamePtr = (ACPI_NAME *) METHOD_NAME__REG; -    ACPI_OPERAND_OBJECT     *RegionObj2;      ACPI_FUNCTION_TRACE_U32 (EvInitializeRegion, AcpiNsLocked); @@ -585,39 +582,15 @@ AcpiEvInitializeRegion (          return_ACPI_STATUS (AE_OK);      } -    RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); -    if (!RegionObj2) -    { -        return_ACPI_STATUS (AE_NOT_EXIST); -    } +    AcpiEvAssociateRegMethod (RegionObj); +    RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;      Node = RegionObj->Region.Node->Parent;      SpaceId = RegionObj->Region.SpaceId; -    /* Setup defaults */ - -    RegionObj->Region.Handler = NULL; -    RegionObj2->Extra.Method_REG = NULL; -    RegionObj->Common.Flags &= ~(AOPOBJ_SETUP_COMPLETE); -    RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED; - -    /* Find any "_REG" method associated with this region definition */ - -    Status = AcpiNsSearchOneScope ( -        *RegNamePtr, Node, ACPI_TYPE_METHOD, &MethodNode); -    if (ACPI_SUCCESS (Status)) -    { -        /* -         * The _REG method is optional and there can be only one per region -         * definition. This will be executed when the handler is attached -         * or removed -         */ -        RegionObj2->Extra.Method_REG = MethodNode; -    } -      /*       * The following loop depends upon the root Node having no parent -     * ie: AcpiGbl_RootNode->ParentEntry being set to NULL +     * ie: AcpiGbl_RootNode->Parent being set to NULL       */      while (Node)      { @@ -632,18 +605,10 @@ AcpiEvInitializeRegion (              switch (Node->Type)              {              case ACPI_TYPE_DEVICE: - -                HandlerObj = ObjDesc->Device.Handler; -                break; -              case ACPI_TYPE_PROCESSOR: - -                HandlerObj = ObjDesc->Processor.Handler; -                break; -              case ACPI_TYPE_THERMAL: -                HandlerObj = ObjDesc->ThermalZone.Handler; +                HandlerObj = ObjDesc->CommonNotify.Handler;                  break;              case ACPI_TYPE_METHOD: @@ -667,51 +632,43 @@ AcpiEvInitializeRegion (                  break;              } -            while (HandlerObj) +            HandlerObj = AcpiEvFindRegionHandler (SpaceId, HandlerObj); +            if (HandlerObj)              { -                /* Is this handler of the correct type? */ - -                if (HandlerObj->AddressSpace.SpaceId == SpaceId) -                { -                    /* Found correct handler */ +                /* Found correct handler */ -                    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, -                        "Found handler %p for region %p in obj %p\n", -                        HandlerObj, RegionObj, ObjDesc)); +                ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, +                    "Found handler %p for region %p in obj %p\n", +                    HandlerObj, RegionObj, ObjDesc)); -                    Status = AcpiEvAttachRegion (HandlerObj, RegionObj, -                        AcpiNsLocked); +                Status = AcpiEvAttachRegion (HandlerObj, RegionObj, +                    AcpiNsLocked); -                    /* -                     * Tell all users that this region is usable by -                     * running the _REG method -                     */ -                    if (AcpiNsLocked) +                /* +                 * Tell all users that this region is usable by +                 * running the _REG method +                 */ +                if (AcpiNsLocked) +                { +                    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); +                    if (ACPI_FAILURE (Status))                      { -                        Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); -                        if (ACPI_FAILURE (Status)) -                        { -                            return_ACPI_STATUS (Status); -                        } +                        return_ACPI_STATUS (Status);                      } +                } -                    Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT); +                Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT); -                    if (AcpiNsLocked) +                if (AcpiNsLocked) +                { +                    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); +                    if (ACPI_FAILURE (Status))                      { -                        Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); -                        if (ACPI_FAILURE (Status)) -                        { -                            return_ACPI_STATUS (Status); -                        } +                        return_ACPI_STATUS (Status);                      } - -                    return_ACPI_STATUS (AE_OK);                  } -                /* Try next handler in the list */ - -                HandlerObj = HandlerObj->AddressSpace.Next; +                return_ACPI_STATUS (AE_OK);              }          } diff --git a/source/components/events/evxfregn.c b/source/components/events/evxfregn.c index d26f3bf053dd..7c6e1cbc33c0 100644 --- a/source/components/events/evxfregn.c +++ b/source/components/events/evxfregn.c @@ -121,43 +121,9 @@ AcpiInstallAddressSpaceHandler (          goto UnlockAndExit;      } -    /* -     * For the default SpaceIDs, (the IDs for which there are default region handlers -     * installed) Only execute the _REG methods if the global initialization _REG -     * methods have already been run (via AcpiInitializeObjects). In other words, -     * we will defer the execution of the _REG methods for these SpaceIDs until -     * execution of AcpiInitializeObjects. This is done because we need the handlers -     * for the default spaces (mem/io/pci/table) to be installed before we can run -     * any control methods (or _REG methods). There is known BIOS code that depends -     * on this. -     * -     * For all other SpaceIDs, we can safely execute the _REG methods immediately. -     * This means that for IDs like EmbeddedController, this function should be called -     * only after AcpiEnableSubsystem has been called. -     */ -    switch (SpaceId) -    { -    case ACPI_ADR_SPACE_SYSTEM_MEMORY: -    case ACPI_ADR_SPACE_SYSTEM_IO: -    case ACPI_ADR_SPACE_PCI_CONFIG: -    case ACPI_ADR_SPACE_DATA_TABLE: - -        if (!AcpiGbl_RegMethodsExecuted) -        { -            /* We will defer execution of the _REG methods for this space */ - -            goto UnlockAndExit; -        } -        break; - -    default: - -        break; -    } -      /* Run all _REG methods for this address space */ -    Status = AcpiEvExecuteRegMethods (Node, SpaceId); +    AcpiEvExecuteRegMethods (Node, SpaceId, ACPI_REG_CONNECT);  UnlockAndExit: @@ -236,8 +202,8 @@ AcpiRemoveAddressSpaceHandler (      /* Find the address handler the user requested */ -    HandlerObj = ObjDesc->Device.Handler; -    LastObjPtr = &ObjDesc->Device.Handler; +    HandlerObj = ObjDesc->CommonNotify.Handler; +    LastObjPtr = &ObjDesc->CommonNotify.Handler;      while (HandlerObj)      {          /* We have a handler, see if user requested this one */ diff --git a/source/components/executer/excreate.c b/source/components/executer/excreate.c index 5e67346091d7..82e7e767491b 100644 --- a/source/components/executer/excreate.c +++ b/source/components/executer/excreate.c @@ -350,9 +350,10 @@ AcpiExCreateRegion (       * Remember location in AML stream of address & length       * operands since they need to be evaluated at run time.       */ -    RegionObj2 = ObjDesc->Common.NextObject; +    RegionObj2 = AcpiNsGetSecondaryObject (ObjDesc);      RegionObj2->Extra.AmlStart = AmlStart;      RegionObj2->Extra.AmlLength = AmlLength; +    RegionObj2->Extra.Method_REG = NULL;      if (WalkState->ScopeInfo)      {          RegionObj2->Extra.ScopeNode = WalkState->ScopeInfo->Scope.Node; @@ -368,6 +369,10 @@ AcpiExCreateRegion (      ObjDesc->Region.Address = 0;      ObjDesc->Region.Length = 0;      ObjDesc->Region.Node = Node; +    ObjDesc->Region.Handler = NULL; +    ObjDesc->Common.Flags &= +        ~(AOPOBJ_SETUP_COMPLETE | AOPOBJ_REG_CONNECTED | +          AOPOBJ_OBJECT_INITIALIZED);      /* Install the new region object in the parent Node */ diff --git a/source/components/executer/exdebug.c b/source/components/executer/exdebug.c index 4d97cda0d372..982760b91c07 100644 --- a/source/components/executer/exdebug.c +++ b/source/components/executer/exdebug.c @@ -96,13 +96,20 @@ AcpiExDoDebugObject (          return_VOID;      } -    /* -     * We will emit the current timer value (in microseconds) with each -     * debug output. Only need the lower 26 bits. This allows for 67 -     * million microseconds or 67 seconds before rollover. -     */ -    Timer = ((UINT32) AcpiOsGetTimer () / 10); /* (100 nanoseconds to microseconds) */ -    Timer &= 0x03FFFFFF; +    /* Null string or newline -- don't emit the line header */ + +    if (SourceDesc && +        (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND) && +        (SourceDesc->Common.Type == ACPI_TYPE_STRING)) +    { +        if ((SourceDesc->String.Length == 0) || +                ((SourceDesc->String.Length == 1) && +                (*SourceDesc->String.Pointer == '\n'))) +        { +            AcpiOsPrintf ("\n"); +            return_VOID; +        } +    }      /*       * Print line header as long as we are not in the middle of an @@ -110,14 +117,31 @@ AcpiExDoDebugObject (       */      if (!((Level > 0) && Index == 0))      { -        AcpiOsPrintf ("[ACPI Debug %.8u] %*s", Timer, Level, " "); +        if (AcpiGbl_DisplayDebugTimer) +        { +            /* +             * We will emit the current timer value (in microseconds) with each +             * debug output. Only need the lower 26 bits. This allows for 67 +             * million microseconds or 67 seconds before rollover. +             * +             * Convert 100 nanosecond units to microseconds +             */ +            Timer = ((UINT32) AcpiOsGetTimer () / 10); +            Timer &= 0x03FFFFFF; + +            AcpiOsPrintf ("[ACPI Debug T=0x%8.8X] %*s", Timer, Level, " "); +        } +        else +        { +            AcpiOsPrintf ("[ACPI Debug] %*s", Level, " "); +        }      }      /* Display the index for package output only */      if (Index > 0)      { -       AcpiOsPrintf ("(%.2u) ", Index-1); +       AcpiOsPrintf ("(%.2u) ", Index - 1);      }      if (!SourceDesc) @@ -128,7 +152,13 @@ AcpiExDoDebugObject (      if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND)      { -        AcpiOsPrintf ("%s ", AcpiUtGetObjectTypeName (SourceDesc)); +        /* No object type prefix needed for integers and strings */ + +        if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER) && +            (SourceDesc->Common.Type != ACPI_TYPE_STRING)) +        { +            AcpiOsPrintf ("%s  ", AcpiUtGetObjectTypeName (SourceDesc)); +        }          if (!AcpiUtValidInternalObject (SourceDesc))          { @@ -138,7 +168,7 @@ AcpiExDoDebugObject (      }      else if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)      { -        AcpiOsPrintf ("%s: %p\n", +        AcpiOsPrintf ("%s  (Node %p)\n",              AcpiUtGetTypeName (((ACPI_NAMESPACE_NODE *) SourceDesc)->Type),                  SourceDesc);          return_VOID; @@ -178,13 +208,12 @@ AcpiExDoDebugObject (      case ACPI_TYPE_STRING: -        AcpiOsPrintf ("[0x%.2X] \"%s\"\n", -            SourceDesc->String.Length, SourceDesc->String.Pointer); +        AcpiOsPrintf ("\"%s\"\n", SourceDesc->String.Pointer);          break;      case ACPI_TYPE_PACKAGE: -        AcpiOsPrintf ("[Contains 0x%.2X Elements]\n", +        AcpiOsPrintf ("(Contains 0x%.2X Elements):\n",              SourceDesc->Package.Count);          /* Output the entire contents of the package */ @@ -263,8 +292,10 @@ AcpiExDoDebugObject (              if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Object) ==                  ACPI_DESC_TYPE_NAMED)              { -                AcpiExDoDebugObject (((ACPI_NAMESPACE_NODE *) -                    SourceDesc->Reference.Object)->Object, +                /* Reference object is a namespace node */ + +                AcpiExDoDebugObject (ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, +                    SourceDesc->Reference.Object),                      Level + 4, 0);              }              else @@ -290,8 +321,15 @@ AcpiExDoDebugObject (                  case ACPI_TYPE_PACKAGE:                      AcpiOsPrintf ("Package[%u] = ", Value); -                    AcpiExDoDebugObject (*SourceDesc->Reference.Where, -                        Level+4, 0); +                    if (!(*SourceDesc->Reference.Where)) +                    { +                        AcpiOsPrintf ("[Uninitialized Package Element]\n"); +                    } +                    else +                    { +                        AcpiExDoDebugObject (*SourceDesc->Reference.Where, +                            Level+4, 0); +                    }                      break;                  default: @@ -306,7 +344,7 @@ AcpiExDoDebugObject (      default: -        AcpiOsPrintf ("%p\n", SourceDesc); +        AcpiOsPrintf ("(Descriptor %p)\n", SourceDesc);          break;      } diff --git a/source/components/executer/exdump.c b/source/components/executer/exdump.c index ebd78d9af5fd..a09d779c24cc 100644 --- a/source/components/executer/exdump.c +++ b/source/components/executer/exdump.c @@ -522,7 +522,8 @@ AcpiExDumpObject (              if (Next)              {                  AcpiOsPrintf ("(%s %2.2X)", -                    AcpiUtGetObjectTypeName (Next), Next->Common.Type); +                    AcpiUtGetObjectTypeName (Next), +                    Next->AddressSpace.SpaceId);                  while (Next->AddressSpace.Next)                  { @@ -534,7 +535,8 @@ AcpiExDumpObject (                      Next = Next->AddressSpace.Next;                      AcpiOsPrintf ("->%p(%s %2.2X)", Next, -                        AcpiUtGetObjectTypeName (Next), Next->Common.Type); +                        AcpiUtGetObjectTypeName (Next), +                        Next->AddressSpace.SpaceId);                      if ((Next == Start) || (Next == Data))                      { diff --git a/source/components/executer/exmisc.c b/source/components/executer/exmisc.c index ab01f6ea50dd..b56645cc33d7 100644 --- a/source/components/executer/exmisc.c +++ b/source/components/executer/exmisc.c @@ -107,9 +107,9 @@ AcpiExGetObjectReference (          default: -            ACPI_ERROR ((AE_INFO, "Unknown Reference Class 0x%2.2X", +            ACPI_ERROR ((AE_INFO, "Invalid Reference Class 0x%2.2X",                  ObjDesc->Reference.Class)); -            return_ACPI_STATUS (AE_AML_INTERNAL); +            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);          }          break; @@ -265,6 +265,7 @@ AcpiExDoConcatenate (      ACPI_OPERAND_OBJECT     *LocalOperand1 = Operand1;      ACPI_OPERAND_OBJECT     *ReturnDesc;      char                    *NewBuf; +    const char              *TypeString;      ACPI_STATUS             Status; @@ -286,9 +287,42 @@ AcpiExDoConcatenate (          break;      case ACPI_TYPE_STRING: +        /* +         * Per the ACPI spec, Concatenate only supports int/str/buf. +         * However, we support all objects here as an extension. +         * This improves the usefulness of the Printf() macro. +         * 12/2015. +         */ +        switch (Operand1->Common.Type) +        { +        case ACPI_TYPE_INTEGER: +        case ACPI_TYPE_STRING: +        case ACPI_TYPE_BUFFER: -        Status = AcpiExConvertToString ( -            Operand1, &LocalOperand1, ACPI_IMPLICIT_CONVERT_HEX); +            Status = AcpiExConvertToString ( +                Operand1, &LocalOperand1, ACPI_IMPLICIT_CONVERT_HEX); +            break; + +        default: +            /* +             * Just emit a string containing the object type. +             */ +            TypeString = AcpiUtGetTypeName (Operand1->Common.Type); + +            LocalOperand1 = AcpiUtCreateStringObject ( +                ((ACPI_SIZE) strlen (TypeString) + 9)); /* 9 For "[Object]" */ +            if (!LocalOperand1) +            { +                Status = AE_NO_MEMORY; +                goto Cleanup; +            } + +            strcpy (LocalOperand1->String.Pointer, "["); +            strcat (LocalOperand1->String.Pointer, TypeString); +            strcat (LocalOperand1->String.Pointer, " Object]"); +            Status = AE_OK; +            break; +        }          break;      case ACPI_TYPE_BUFFER: @@ -367,8 +401,7 @@ AcpiExDoConcatenate (          /* Concatenate the strings */          strcpy (NewBuf, Operand0->String.Pointer); -        strcpy (NewBuf + Operand0->String.Length, -            LocalOperand1->String.Pointer); +        strcat (NewBuf, LocalOperand1->String.Pointer);          break;      case ACPI_TYPE_BUFFER: diff --git a/source/components/executer/exoparg1.c b/source/components/executer/exoparg1.c index 4d2d88f64862..efaa82770193 100644 --- a/source/components/executer/exoparg1.c +++ b/source/components/executer/exoparg1.c @@ -724,7 +724,7 @@ AcpiExOpcode_1A_0T_1R (          Status = AcpiExStore (ReturnDesc, Operand[0], WalkState);          break; -    case AML_TYPE_OP:               /* ObjectType (SourceObject) */ +    case AML_OBJECT_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 diff --git a/source/components/namespace/nsconvert.c b/source/components/namespace/nsconvert.c index 84eeec1fa48a..5d3eb033e713 100644 --- a/source/components/namespace/nsconvert.c +++ b/source/components/namespace/nsconvert.c @@ -332,7 +332,8 @@ AcpiNsConvertToBuffer (   *   * FUNCTION:    AcpiNsConvertToUnicode   * - * PARAMETERS:  OriginalObject      - ASCII String Object to be converted + * PARAMETERS:  Scope               - Namespace node for the method/object + *              OriginalObject      - ASCII String Object to be converted   *              ReturnObject        - Where the new converted object is returned   *   * RETURN:      Status. AE_OK if conversion was successful. @@ -343,6 +344,7 @@ AcpiNsConvertToBuffer (  ACPI_STATUS  AcpiNsConvertToUnicode ( +    ACPI_NAMESPACE_NODE     *Scope,      ACPI_OPERAND_OBJECT     *OriginalObject,      ACPI_OPERAND_OBJECT     **ReturnObject)  { @@ -404,7 +406,8 @@ AcpiNsConvertToUnicode (   *   * FUNCTION:    AcpiNsConvertToResource   * - * PARAMETERS:  OriginalObject      - Object to be converted + * PARAMETERS:  Scope               - Namespace node for the method/object + *              OriginalObject      - Object to be converted   *              ReturnObject        - Where the new converted object is returned   *   * RETURN:      Status. AE_OK if conversion was successful @@ -416,6 +419,7 @@ AcpiNsConvertToUnicode (  ACPI_STATUS  AcpiNsConvertToResource ( +    ACPI_NAMESPACE_NODE     *Scope,      ACPI_OPERAND_OBJECT     *OriginalObject,      ACPI_OPERAND_OBJECT     **ReturnObject)  { @@ -482,3 +486,81 @@ AcpiNsConvertToResource (      *ReturnObject = NewObject;      return (AE_OK);  } + + +/******************************************************************************* + * + * FUNCTION:    AcpiNsConvertToReference + * + * PARAMETERS:  Scope               - Namespace node for the method/object + *              OriginalObject      - Object to be converted + *              ReturnObject        - Where the new converted object is returned + * + * RETURN:      Status. AE_OK if conversion was successful + * + * DESCRIPTION: Attempt to convert a Integer object to a ObjectReference. + *              Buffer. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiNsConvertToReference ( +    ACPI_NAMESPACE_NODE     *Scope, +    ACPI_OPERAND_OBJECT     *OriginalObject, +    ACPI_OPERAND_OBJECT     **ReturnObject) +{ +    ACPI_OPERAND_OBJECT     *NewObject = NULL; +    ACPI_STATUS             Status; +    ACPI_NAMESPACE_NODE     *Node; +    ACPI_GENERIC_STATE      ScopeInfo; +    char                    *Name; + + +    ACPI_FUNCTION_NAME (NsConvertToReference); + + +    /* Convert path into internal presentation */ + +    Status = AcpiNsInternalizeName (OriginalObject->String.Pointer, &Name); +    if (ACPI_FAILURE (Status)) +    { +        return_ACPI_STATUS (Status); +    } + +    /* Find the namespace node */ + +    ScopeInfo.Scope.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Scope); +    Status = AcpiNsLookup (&ScopeInfo, Name, +        ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, +        ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node); +    if (ACPI_FAILURE (Status)) +    { +        /* Check if we are resolving a named reference within a package */ + +        ACPI_ERROR_NAMESPACE (OriginalObject->String.Pointer, Status); +        goto ErrorExit; +    } + +    /* Create and init a new internal ACPI object */ + +    NewObject = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE); +    if (!NewObject) +    { +        Status = AE_NO_MEMORY; +        goto ErrorExit; +    } +    NewObject->Reference.Node = Node; +    NewObject->Reference.Object = Node->Object; +    NewObject->Reference.Class = ACPI_REFCLASS_NAME; + +    /* +     * Increase reference of the object if needed (the object is likely a +     * null for device nodes). +     */ +    AcpiUtAddReference (Node->Object); + +ErrorExit: +    ACPI_FREE (Name); +    *ReturnObject = NewObject; +    return (AE_OK); +} diff --git a/source/components/namespace/nseval.c b/source/components/namespace/nseval.c index 0509c80e7a0c..a4819947dae4 100644 --- a/source/components/namespace/nseval.c +++ b/source/components/namespace/nseval.c @@ -418,7 +418,7 @@ AcpiNsExecModuleCodeList (   *   * DESCRIPTION: Execute a control method containing a block of module-level   *              executable AML code. The control method is temporarily - *              installed to the root node, then evaluated. + *              installed to a local copy of the root node, then evaluated.   *   ******************************************************************************/ @@ -427,10 +427,9 @@ AcpiNsExecModuleCode (      ACPI_OPERAND_OBJECT     *MethodObj,      ACPI_EVALUATE_INFO      *Info)  { -    ACPI_OPERAND_OBJECT     *ParentObj; -    ACPI_NAMESPACE_NODE     *ParentNode; -    ACPI_OBJECT_TYPE        Type;      ACPI_STATUS             Status; +    ACPI_NAMESPACE_NODE     *TempNode; +    ACPI_NAMESPACE_NODE     *ParentNode;      ACPI_FUNCTION_TRACE (NsExecModuleCode); @@ -442,21 +441,18 @@ AcpiNsExecModuleCode (       */      ParentNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,          MethodObj->Method.NextObject); -    Type = AcpiNsGetType (ParentNode); -    /* -     * Get the region handler and save it in the method object. We may need -     * this if an operation region declaration causes a _REG method to be run. -     * -     * We can't do this in AcpiPsLinkModuleCode because -     * AcpiGbl_RootNode->Object is NULL at PASS1. -     */ -    if ((Type == ACPI_TYPE_DEVICE) && ParentNode->Object) +    /* Take a copy of the parent node to act as parent of this method */ + +    TempNode = ACPI_ALLOCATE (sizeof (ACPI_NAMESPACE_NODE)); +    if (!TempNode)      { -        MethodObj->Method.Dispatch.Handler = -            ParentNode->Object->Device.Handler; +        return_VOID;      } +    memcpy (TempNode, ParentNode, sizeof (ACPI_NAMESPACE_NODE)); +    TempNode->Object = NULL; /* Clear the subobject */ +      /* Must clear NextObject (AcpiNsAttachObject needs the field) */      MethodObj->Method.NextObject = NULL; @@ -464,26 +460,14 @@ AcpiNsExecModuleCode (      /* Initialize the evaluation information block */      memset (Info, 0, sizeof (ACPI_EVALUATE_INFO)); -    Info->PrefixNode = ParentNode; - -    /* -     * Get the currently attached parent object. Add a reference, because the -     * ref count will be decreased when the method object is installed to -     * the parent node. -     */ -    ParentObj = AcpiNsGetAttachedObject (ParentNode); -    if (ParentObj) -    { -        AcpiUtAddReference (ParentObj); -    } +    Info->PrefixNode = TempNode;      /* Install the method (module-level code) in the parent node */ -    Status = AcpiNsAttachObject (ParentNode, MethodObj, -        ACPI_TYPE_METHOD); +    Status = AcpiNsAttachObject (TempNode, MethodObj, ACPI_TYPE_METHOD);      if (ACPI_FAILURE (Status))      { -        goto Exit; +        goto Cleanup;      }      /* Execute the parent node as a control method */ @@ -501,25 +485,7 @@ AcpiNsExecModuleCode (          AcpiUtRemoveReference (Info->ReturnObject);      } -    /* Detach the temporary method object */ - -    AcpiNsDetachObject (ParentNode); - -    /* Restore the original parent object */ - -    if (ParentObj) -    { -        Status = AcpiNsAttachObject (ParentNode, ParentObj, Type); -    } -    else -    { -        ParentNode->Type = (UINT8) Type; -    } - -Exit: -    if (ParentObj) -    { -        AcpiUtRemoveReference (ParentObj); -    } +Cleanup: +    ACPI_FREE (TempNode);      return_VOID;  } diff --git a/source/components/namespace/nsload.c b/source/components/namespace/nsload.c index b1b6afa70615..edd79327ff93 100644 --- a/source/components/namespace/nsload.c +++ b/source/components/namespace/nsload.c @@ -167,6 +167,24 @@ Unlock:      ACPI_DEBUG_PRINT ((ACPI_DB_INFO,          "**** Completed Table Object Initialization\n")); +    /* +     * Execute any module-level code that was detected during the table load +     * phase. Although illegal since ACPI 2.0, there are many machines that +     * contain this type of code. Each block of detected executable AML code +     * outside of any control method is wrapped with a temporary control +     * method object and placed on a global list. The methods on this list +     * are executed below. +     * +     * This case executes the module-level code for each table immediately +     * after the table has been loaded. This provides compatibility with +     * other ACPI implementations. Optionally, the execution can be deferred +     * until later, see AcpiInitializeObjects. +     */ +    if (!AcpiGbl_GroupModuleLevelCode) +    { +        AcpiNsExecModuleCodeList (); +    } +      return_ACPI_STATUS (Status);  } diff --git a/source/components/namespace/nsrepair.c b/source/components/namespace/nsrepair.c index d98e11022eef..bb4b8a2fd720 100644 --- a/source/components/namespace/nsrepair.c +++ b/source/components/namespace/nsrepair.c @@ -114,6 +114,11 @@ static const ACPI_SIMPLE_REPAIR_INFO    AcpiObjectRepairInfo[] =                  ACPI_NOT_PACKAGE_ELEMENT,                  AcpiNsConvertToResource }, +    /* Object reference conversions */ + +    { "_DEP", ACPI_RTYPE_STRING, ACPI_ALL_PACKAGE_ELEMENTS, +                AcpiNsConvertToReference }, +      /* Unicode conversions */      { "_MLS", ACPI_RTYPE_STRING, 1, @@ -174,7 +179,8 @@ AcpiNsSimpleRepair (                  ACPI_WARN_ALWAYS, "Missing expected return value"));          } -        Status = Predefined->ObjectConverter (ReturnObject, &NewObject); +        Status = Predefined->ObjectConverter (Info->Node, ReturnObject, +            &NewObject);          if (ACPI_FAILURE (Status))          {              /* A fatal error occurred during a conversion */ @@ -373,7 +379,8 @@ AcpiNsMatchSimpleRepair (              /* Check if we can actually repair this name/type combination */              if ((ReturnBtype & ThisName->UnexpectedBtypes) && -                (PackageIndex == ThisName->PackageIndex)) +                (ThisName->PackageIndex == ACPI_ALL_PACKAGE_ELEMENTS || +                 PackageIndex == ThisName->PackageIndex))              {                  return (ThisName);              } diff --git a/source/components/parser/psargs.c b/source/components/parser/psargs.c index 7876a0eb4988..deab704bea88 100644 --- a/source/components/parser/psargs.c +++ b/source/components/parser/psargs.c @@ -298,7 +298,7 @@ AcpiPsGetNextNamepath (          PossibleMethodCall &&          (Node->Type == ACPI_TYPE_METHOD))      { -        if (WalkState->Opcode == AML_UNLOAD_OP) +        if (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) == ARGP_SUPERNAME)          {              /*               * AcpiPsGetNextNamestring has increased the AML pointer, @@ -744,7 +744,7 @@ AcpiPsGetNextField (   *   * PARAMETERS:  WalkState           - Current state   *              ParserState         - Current parser state object - *              ArgType             - The argument type (AML_*_ARG) + *              ArgType             - The parser argument type (ARGP_*)   *              ReturnArg           - Where the next arg is returned   *   * RETURN:      Status, and an op object containing the next argument. @@ -857,6 +857,7 @@ AcpiPsGetNextArg (      case ARGP_TARGET:      case ARGP_SUPERNAME:      case ARGP_SIMPLENAME: +    case ARGP_NAME_OR_REF:          Subop = AcpiPsPeekOpcode (ParserState);          if (Subop == 0                  || @@ -872,15 +873,16 @@ AcpiPsGetNextArg (                  return_ACPI_STATUS (AE_NO_MEMORY);              } -            /* To support SuperName arg of Unload */ +            /* SuperName allows argument to be a method call */ -            if (WalkState->Opcode == AML_UNLOAD_OP) +            if (ArgType == ARGP_SUPERNAME)              { -                Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 1); +                Status = AcpiPsGetNextNamepath (WalkState, ParserState, +                    Arg, ACPI_POSSIBLE_METHOD_CALL);                  /* -                 * If the SuperName arg of Unload is a method call, -                 * we have restored the AML pointer, just free this Arg +                 * 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)                  { @@ -890,7 +892,8 @@ AcpiPsGetNextArg (              }              else              { -                Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 0); +                Status = AcpiPsGetNextNamepath (WalkState, ParserState, +                    Arg, ACPI_NOT_METHOD_CALL);              }          }          else diff --git a/source/components/parser/psloop.c b/source/components/parser/psloop.c index 044cf9d3e77e..f1bd607ab206 100644 --- a/source/components/parser/psloop.c +++ b/source/components/parser/psloop.c @@ -120,8 +120,8 @@ AcpiPsGetArguments (      case AML_INT_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */ -        Status = AcpiPsGetNextNamepath ( -            WalkState, &(WalkState->ParserState), Op, 1); +        Status = AcpiPsGetNextNamepath (WalkState, +            &(WalkState->ParserState), Op, ACPI_POSSIBLE_METHOD_CALL);          if (ACPI_FAILURE (Status))          {              return_ACPI_STATUS (Status); diff --git a/source/components/parser/psopcode.c b/source/components/parser/psopcode.c index 0376da55b8ef..9961a63319f3 100644 --- a/source/components/parser/psopcode.c +++ b/source/components/parser/psopcode.c @@ -245,7 +245,7 @@ const ACPI_OPCODE_INFO    AcpiGbl_AmlOpInfo[AML_NUM_OPCODES] =  /* 34 */ ACPI_OP ("CreateWordField",    ARGP_CREATE_WORD_FIELD_OP, ARGI_CREATE_WORD_FIELD_OP,  ACPI_TYPE_BUFFER_FIELD,      AML_CLASS_CREATE,          AML_TYPE_CREATE_FIELD,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),  /* 35 */ ACPI_OP ("CreateByteField",    ARGP_CREATE_BYTE_FIELD_OP, ARGI_CREATE_BYTE_FIELD_OP,  ACPI_TYPE_BUFFER_FIELD,      AML_CLASS_CREATE,          AML_TYPE_CREATE_FIELD,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),  /* 36 */ ACPI_OP ("CreateBitField",     ARGP_CREATE_BIT_FIELD_OP,  ARGI_CREATE_BIT_FIELD_OP,   ACPI_TYPE_BUFFER_FIELD,      AML_CLASS_CREATE,          AML_TYPE_CREATE_FIELD,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE), -/* 37 */ ACPI_OP ("ObjectType",         ARGP_TYPE_OP,              ARGI_TYPE_OP,               ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE), +/* 37 */ ACPI_OP ("ObjectType",         ARGP_OBJECT_TYPE_OP,       ARGI_OBJECT_TYPE_OP,        ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),  /* 38 */ ACPI_OP ("LAnd",               ARGP_LAND_OP,              ARGI_LAND_OP,               ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_0T_1R,   AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),  /* 39 */ ACPI_OP ("LOr",                ARGP_LOR_OP,               ARGI_LOR_OP,                ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_0T_1R,   AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),  /* 3A */ ACPI_OP ("LNot",               ARGP_LNOT_OP,              ARGI_LNOT_OP,               ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT), diff --git a/source/components/tables/tbutils.c b/source/components/tables/tbutils.c index 19daea867e35..910854997bb4 100644 --- a/source/components/tables/tbutils.c +++ b/source/components/tables/tbutils.c @@ -419,7 +419,7 @@ NextTable:   *   * PARAMETERS:  Signature           - Sig string to be validated   * - * RETURN:      TRUE if signature is correct length and has valid characters + * RETURN:      TRUE if signature is has 4 valid ACPI characters   *   * DESCRIPTION: Validate an ACPI table signature.   * @@ -432,13 +432,6 @@ AcpiIsValidSignature (      UINT32                  i; -    /* Validate the signature length */ - -    if (strlen (Signature) != ACPI_NAME_SIZE) -    { -        return (FALSE); -    } -      /* Validate each character in the signature */      for (i = 0; i < ACPI_NAME_SIZE; i++) diff --git a/source/components/utilities/utinit.c b/source/components/utilities/utinit.c index 9689abb43516..2c7061678d35 100644 --- a/source/components/utilities/utinit.c +++ b/source/components/utilities/utinit.c @@ -226,7 +226,6 @@ AcpiUtInitGlobals (      AcpiGbl_NextOwnerIdOffset           = 0;      AcpiGbl_DebuggerConfiguration       = DEBUGGER_THREADING;      AcpiGbl_OsiMutex                    = NULL; -    AcpiGbl_RegMethodsExecuted          = FALSE;      AcpiGbl_MaxLoopIterations           = 0xFFFF;      /* Hardware oriented */ diff --git a/source/components/utilities/utstring.c b/source/components/utilities/utstring.c index c8b41f10ad78..5c761b785b14 100644 --- a/source/components/utilities/utstring.c +++ b/source/components/utilities/utstring.c @@ -271,6 +271,15 @@ AcpiUtRepairName (      ACPI_FUNCTION_NAME (UtRepairName); +    /* +     * Special case for the root node. This can happen if we get an +     * error during the execution of module-level code. +     */ +    if (ACPI_COMPARE_NAME (Name, "\\___")) +    { +        return; +    } +      ACPI_MOVE_NAME (&OriginalName, Name);      /* Check each character in the name */ diff --git a/source/components/utilities/utxfinit.c b/source/components/utilities/utxfinit.c index 7502c61f0789..0efd35bda753 100644 --- a/source/components/utilities/utxfinit.c +++ b/source/components/utilities/utxfinit.c @@ -132,6 +132,25 @@ AcpiInitializeSubsystem (          return_ACPI_STATUS (Status);      } +    if (!AcpiGbl_OverrideDefaultRegionHandlers) +    { +        /* +         * Install the default operation region handlers. These are the +         * handlers that are defined by the ACPI specification to be +         * "always accessible" -- namely, SystemMemory, SystemIO, and +         * PCI_Config. This also means that no _REG methods need to be +         * run for these address spaces. We need to have these handlers +         * installed before any AML code can be executed, especially any +         * module-level code (11/2015). +         */ +        Status = AcpiEvInstallRegionHandlers (); +        if (ACPI_FAILURE (Status)) +        { +            ACPI_EXCEPTION ((AE_INFO, Status, "During Region initialization")); +            return_ACPI_STATUS (Status); +        } +    } +      return_ACPI_STATUS (AE_OK);  } @@ -161,6 +180,33 @@ AcpiEnableSubsystem (      ACPI_FUNCTION_TRACE (AcpiEnableSubsystem); +    /* +     * The early initialization phase is complete. The namespace is loaded, +     * and we can now support address spaces other than Memory, I/O, and +     * PCI_Config. +     */ +    AcpiGbl_EarlyInitialization = FALSE; + +    if (AcpiGbl_OverrideDefaultRegionHandlers) +    { +        /* +         * Install the default operation region handlers. These are the +         * handlers that are defined by the ACPI specification to be +         * "always accessible" -- namely, SystemMemory, SystemIO, and +         * PCI_Config. This also means that no _REG methods need to be +         * run for these address spaces. We need to have these handlers +         * installed before any AML code can be executed, especially any +         * module-level code (11/2015). +         */ +        Status = AcpiEvInstallRegionHandlers (); +        if (ACPI_FAILURE (Status)) +        { +            ACPI_EXCEPTION ((AE_INFO, Status, "During Region initialization")); +            return_ACPI_STATUS (Status); +        } +    } + +  #if (!ACPI_REDUCED_HARDWARE)      /* Enable ACPI mode */ @@ -193,26 +239,6 @@ AcpiEnableSubsystem (          }      } -#endif /* !ACPI_REDUCED_HARDWARE */ - -    /* -     * Install the default OpRegion handlers. These are installed unless -     * other handlers have already been installed via the -     * InstallAddressSpaceHandler interface. -     */ -    if (!(Flags & ACPI_NO_ADDRESS_SPACE_INIT)) -    { -        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, -            "[Init] Installing default address space handlers\n")); - -        Status = AcpiEvInstallRegionHandlers (); -        if (ACPI_FAILURE (Status)) -        { -            return_ACPI_STATUS (Status); -        } -    } - -#if (!ACPI_REDUCED_HARDWARE)      /*       * Initialize ACPI Event handling (Fixed and General Purpose)       * @@ -320,8 +346,15 @@ AcpiInitializeObjects (       * outside of any control method is wrapped with a temporary control       * method object and placed on a global list. The methods on this list       * are executed below. +     * +     * This case executes the module-level code for all tables only after +     * all of the tables have been loaded. It is a legacy option and is +     * not compatible with other ACPI implementations. See AcpiNsLoadTable.       */ -    AcpiNsExecModuleCodeList (); +    if (AcpiGbl_GroupModuleLevelCode) +    { +        AcpiNsExecModuleCodeList (); +    }      /*       * Initialize the objects that remain uninitialized. This runs the diff --git a/source/include/acapps.h b/source/include/acapps.h index 6652cefcd596..31d088b26e0c 100644 --- a/source/include/acapps.h +++ b/source/include/acapps.h @@ -91,7 +91,7 @@      AcpiOsPrintf (Description);  #define ACPI_OPTION(Name, Description) \ -    AcpiOsPrintf ("  %-18s%s\n", Name, Description); +    AcpiOsPrintf ("  %-20s%s\n", Name, Description);  /* Check for unexpected exceptions */ @@ -115,11 +115,21 @@  /* acfileio */  ACPI_STATUS -AcpiAcGetAllTablesFromFile ( +AcGetAllTablesFromFile (      char                    *Filename,      UINT8                   GetOnlyAmlTables,      ACPI_NEW_TABLE_DESC     **ReturnListHead); +BOOLEAN +AcIsFileBinary ( +    FILE                    *File); + +ACPI_STATUS +AcValidateTableHeader ( +    FILE                    *File, +    long                    TableOffset); + +  /* Values for GetOnlyAmlTables */  #define ACPI_GET_ONLY_AML_TABLES    TRUE diff --git a/source/include/acevents.h b/source/include/acevents.h index 2ae0aca81a55..9dcb545c6e57 100644 --- a/source/include/acevents.h +++ b/source/include/acevents.h @@ -222,6 +222,11 @@ AcpiEvDeleteGpeHandlers (  /*   * evhandler - Address space handling   */ +ACPI_OPERAND_OBJECT * +AcpiEvFindRegionHandler ( +    ACPI_ADR_SPACE_TYPE     SpaceId, +    ACPI_OPERAND_OBJECT     *HandlerObj); +  BOOLEAN  AcpiEvHasDefaultHandler (      ACPI_NAMESPACE_NODE     *Node, @@ -264,17 +269,22 @@ AcpiEvAttachRegion (  void  AcpiEvDetachRegion ( -    ACPI_OPERAND_OBJECT    *RegionObj, +    ACPI_OPERAND_OBJECT     *RegionObj,      BOOLEAN                 AcpiNsIsLocked); -ACPI_STATUS +void +AcpiEvAssociateRegMethod ( +    ACPI_OPERAND_OBJECT     *RegionObj); + +void  AcpiEvExecuteRegMethods (      ACPI_NAMESPACE_NODE     *Node, -    ACPI_ADR_SPACE_TYPE     SpaceId); +    ACPI_ADR_SPACE_TYPE     SpaceId, +    UINT32                  Function);  ACPI_STATUS  AcpiEvExecuteRegMethod ( -    ACPI_OPERAND_OBJECT    *RegionObj, +    ACPI_OPERAND_OBJECT     *RegionObj,      UINT32                  Function); diff --git a/source/include/acexcep.h b/source/include/acexcep.h index f021eaf3d2fe..f915c60e040c 100644 --- a/source/include/acexcep.h +++ b/source/include/acexcep.h @@ -128,8 +128,9 @@ typedef struct acpi_exception_info  #define AE_OWNER_ID_LIMIT               EXCEP_ENV (0x001B)  #define AE_NOT_CONFIGURED               EXCEP_ENV (0x001C)  #define AE_ACCESS                       EXCEP_ENV (0x001D) +#define AE_IO_ERROR                     EXCEP_ENV (0x001E) -#define AE_CODE_ENV_MAX                 0x001D +#define AE_CODE_ENV_MAX                 0x001E  /* @@ -262,7 +263,8 @@ static const ACPI_EXCEPTION_INFO    AcpiGbl_ExceptionNames_Env[] =      EXCEP_TXT ("AE_NO_HANDLER",                 "A handler for the operation is not installed"),      EXCEP_TXT ("AE_OWNER_ID_LIMIT",             "There are no more Owner IDs available for ACPI tables or control methods"),      EXCEP_TXT ("AE_NOT_CONFIGURED",             "The interface is not part of the current subsystem configuration"), -    EXCEP_TXT ("AE_ACCESS",                     "Permission denied for the requested operation") +    EXCEP_TXT ("AE_ACCESS",                     "Permission denied for the requested operation"), +    EXCEP_TXT ("AE_IO_ERROR",                   "An I/O error occurred")  };  static const ACPI_EXCEPTION_INFO    AcpiGbl_ExceptionNames_Pgm[] = diff --git a/source/include/acglobal.h b/source/include/acglobal.h index f98401d28f00..2a3950c27cef 100644 --- a/source/include/acglobal.h +++ b/source/include/acglobal.h @@ -86,6 +86,8 @@ ACPI_GLOBAL (UINT8,                     AcpiGbl_IntegerBitWidth);  ACPI_GLOBAL (UINT8,                     AcpiGbl_IntegerByteWidth);  ACPI_GLOBAL (UINT8,                     AcpiGbl_IntegerNybbleWidth); +ACPI_INIT_GLOBAL (UINT8,                AcpiGbl_GroupModuleLevelCode, FALSE); +  /*****************************************************************************   * @@ -148,6 +150,7 @@ ACPI_GLOBAL (ACPI_CACHE_T *,            AcpiGbl_OperandCache);  ACPI_INIT_GLOBAL (UINT32,               AcpiGbl_StartupFlags, 0);  ACPI_INIT_GLOBAL (BOOLEAN,              AcpiGbl_Shutdown, TRUE); +ACPI_INIT_GLOBAL (BOOLEAN,              AcpiGbl_EarlyInitialization, TRUE);  /* Global handlers */ @@ -167,7 +170,7 @@ ACPI_GLOBAL (UINT8,                     AcpiGbl_NextOwnerIdOffset);  /* Initialization sequencing */ -ACPI_GLOBAL (BOOLEAN,                   AcpiGbl_RegMethodsExecuted); +ACPI_INIT_GLOBAL (BOOLEAN,              AcpiGbl_RegMethodsEnabled, FALSE);  /* Misc */ diff --git a/source/include/aclocal.h b/source/include/aclocal.h index d618055d4189..6c2be99f0c1a 100644 --- a/source/include/aclocal.h +++ b/source/include/aclocal.h @@ -453,6 +453,7 @@ typedef union acpi_predefined_info  /* Return object auto-repair info */  typedef ACPI_STATUS (*ACPI_OBJECT_CONVERTER) ( +    struct acpi_namespace_node  *Scope,      union acpi_operand_object   *OriginalObject,      union acpi_operand_object   **ConvertedObject); @@ -488,6 +489,7 @@ typedef struct acpi_simple_repair_info  typedef struct acpi_reg_walk_info  {      ACPI_ADR_SPACE_TYPE     SpaceId; +    UINT32                  Function;      UINT32                  RegRunCount;  } ACPI_REG_WALK_INFO; @@ -1040,6 +1042,7 @@ typedef struct acpi_parse_state  #define ACPI_PARSEOP_CLOSING_PAREN      0x10  #define ACPI_PARSEOP_COMPOUND           0x20  #define ACPI_PARSEOP_ASSIGNMENT         0x40 +#define ACPI_PARSEOP_ELSEIF             0x80  /***************************************************************************** diff --git a/source/include/acnamesp.h b/source/include/acnamesp.h index bea4ebf0ad7c..d9f54eb41649 100644 --- a/source/include/acnamesp.h +++ b/source/include/acnamesp.h @@ -78,6 +78,7 @@  /* Object is not a package element */  #define ACPI_NOT_PACKAGE_ELEMENT    ACPI_UINT32_MAX +#define ACPI_ALL_PACKAGE_ELEMENTS   (ACPI_UINT32_MAX-1)  /* Always emit warning message, not dependent on node flags */ @@ -224,11 +225,19 @@ AcpiNsConvertToBuffer (  ACPI_STATUS  AcpiNsConvertToUnicode ( +    ACPI_NAMESPACE_NODE     *Scope,      ACPI_OPERAND_OBJECT     *OriginalObject,      ACPI_OPERAND_OBJECT     **ReturnObject);  ACPI_STATUS  AcpiNsConvertToResource ( +    ACPI_NAMESPACE_NODE     *Scope, +    ACPI_OPERAND_OBJECT     *OriginalObject, +    ACPI_OPERAND_OBJECT     **ReturnObject); + +ACPI_STATUS +AcpiNsConvertToReference ( +    ACPI_NAMESPACE_NODE     *Scope,      ACPI_OPERAND_OBJECT     *OriginalObject,      ACPI_OPERAND_OBJECT     **ReturnObject); diff --git a/source/include/acobject.h b/source/include/acobject.h index adeb41403412..64519fc5fe8a 100644 --- a/source/include/acobject.h +++ b/source/include/acobject.h @@ -94,9 +94,10 @@  #define AOPOBJ_AML_CONSTANT         0x01    /* Integer is an AML constant */  #define AOPOBJ_STATIC_POINTER       0x02    /* Data is part of an ACPI table, don't delete */  #define AOPOBJ_DATA_VALID           0x04    /* Object is initialized and data is valid */ -#define AOPOBJ_OBJECT_INITIALIZED   0x08    /* Region is initialized, _REG was run */ -#define AOPOBJ_SETUP_COMPLETE       0x10    /* Region setup is complete */ -#define AOPOBJ_INVALID              0x20    /* Host OS won't allow a Region address */ +#define AOPOBJ_OBJECT_INITIALIZED   0x08    /* Region is initialized */ +#define AOPOBJ_REG_CONNECTED        0x10    /* _REG was run */ +#define AOPOBJ_SETUP_COMPLETE       0x20    /* Region setup is complete */ +#define AOPOBJ_INVALID              0x40    /* Host OS won't allow a Region address */  /****************************************************************************** diff --git a/source/include/acopcode.h b/source/include/acopcode.h index a2d8d3c2aa13..92c1efcf1e87 100644 --- a/source/include/acopcode.h +++ b/source/include/acopcode.h @@ -93,7 +93,7 @@  #define ARGP_BYTELIST_OP                ARGP_LIST1 (ARGP_NAMESTRING)  #define ARGP_CONCAT_OP                  ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)  #define ARGP_CONCAT_RES_OP              ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET) -#define ARGP_COND_REF_OF_OP             ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_SUPERNAME) +#define ARGP_COND_REF_OF_OP             ARGP_LIST2 (ARGP_NAME_OR_REF,ARGP_TARGET)  #define ARGP_CONNECTFIELD_OP            ARGP_LIST1 (ARGP_NAMESTRING)  #define ARGP_CONTINUE_OP                ARG_NONE  #define ARGP_COPY_OP                    ARGP_LIST2 (ARGP_TERMARG,    ARGP_SIMPLENAME) @@ -153,13 +153,14 @@  #define ARGP_NAMEPATH_OP                ARGP_LIST1 (ARGP_NAMESTRING)  #define ARGP_NOOP_OP                    ARG_NONE  #define ARGP_NOTIFY_OP                  ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_TERMARG) +#define ARGP_OBJECT_TYPE_OP             ARGP_LIST1 (ARGP_NAME_OR_REF)  #define ARGP_ONE_OP                     ARG_NONE  #define ARGP_ONES_OP                    ARG_NONE  #define ARGP_PACKAGE_OP                 ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_BYTEDATA,      ARGP_DATAOBJLIST)  #define ARGP_POWER_RES_OP               ARGP_LIST5 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_BYTEDATA,  ARGP_WORDDATA,  ARGP_OBJLIST)  #define ARGP_PROCESSOR_OP               ARGP_LIST6 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_BYTEDATA,  ARGP_DWORDDATA, ARGP_BYTEDATA,  ARGP_OBJLIST)  #define ARGP_QWORD_OP                   ARGP_LIST1 (ARGP_QWORDDATA) -#define ARGP_REF_OF_OP                  ARGP_LIST1 (ARGP_SUPERNAME) +#define ARGP_REF_OF_OP                  ARGP_LIST1 (ARGP_NAME_OR_REF)  #define ARGP_REGION_OP                  ARGP_LIST4 (ARGP_NAME,       ARGP_BYTEDATA,      ARGP_TERMARG,   ARGP_TERMARG)  #define ARGP_RELEASE_OP                 ARGP_LIST1 (ARGP_SUPERNAME)  #define ARGP_RESERVEDFIELD_OP           ARGP_LIST1 (ARGP_NAMESTRING) @@ -186,7 +187,6 @@  #define ARGP_TO_HEX_STR_OP              ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)  #define ARGP_TO_INTEGER_OP              ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)  #define ARGP_TO_STRING_OP               ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET) -#define ARGP_TYPE_OP                    ARGP_LIST1 (ARGP_SUPERNAME)  #define ARGP_UNLOAD_OP                  ARGP_LIST1 (ARGP_SUPERNAME)  #define ARGP_VAR_PACKAGE_OP             ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_TERMARG,       ARGP_DATAOBJLIST)  #define ARGP_WAIT_OP                    ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_TERMARG) @@ -225,7 +225,7 @@  #define ARGI_BUFFER_OP                  ARGI_LIST1 (ARGI_INTEGER)  #define ARGI_BYTE_OP                    ARGI_INVALID_OPCODE  #define ARGI_BYTELIST_OP                ARGI_INVALID_OPCODE -#define ARGI_CONCAT_OP                  ARGI_LIST3 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA,   ARGI_TARGETREF) +#define ARGI_CONCAT_OP                  ARGI_LIST3 (ARGI_ANYTYPE,    ARGI_ANYTYPE,       ARGI_TARGETREF)  #define ARGI_CONCAT_RES_OP              ARGI_LIST3 (ARGI_BUFFER,     ARGI_BUFFER,        ARGI_TARGETREF)  #define ARGI_COND_REF_OF_OP             ARGI_LIST2 (ARGI_OBJECT_REF, ARGI_TARGETREF)  #define ARGI_CONNECTFIELD_OP            ARGI_INVALID_OPCODE @@ -287,6 +287,7 @@  #define ARGI_NAMEPATH_OP                ARGI_INVALID_OPCODE  #define ARGI_NOOP_OP                    ARG_NONE  #define ARGI_NOTIFY_OP                  ARGI_LIST2 (ARGI_DEVICE_REF, ARGI_INTEGER) +#define ARGI_OBJECT_TYPE_OP             ARGI_LIST1 (ARGI_ANYTYPE)  #define ARGI_ONE_OP                     ARG_NONE  #define ARGI_ONES_OP                    ARG_NONE  #define ARGI_PACKAGE_OP                 ARGI_LIST1 (ARGI_INTEGER) @@ -320,7 +321,6 @@  #define ARGI_TO_HEX_STR_OP              ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)  #define ARGI_TO_INTEGER_OP              ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)  #define ARGI_TO_STRING_OP               ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_FIXED_TARGET) -#define ARGI_TYPE_OP                    ARGI_LIST1 (ARGI_ANYTYPE)  #define ARGI_UNLOAD_OP                  ARGI_LIST1 (ARGI_DDBHANDLE)  #define ARGI_VAR_PACKAGE_OP             ARGI_LIST1 (ARGI_INTEGER)  #define ARGI_WAIT_OP                    ARGI_LIST2 (ARGI_EVENT,      ARGI_INTEGER) diff --git a/source/include/acparser.h b/source/include/acparser.h index a89c5c4c4635..1fbd0cc40aa3 100644 --- a/source/include/acparser.h +++ b/source/include/acparser.h @@ -106,7 +106,12 @@ AcpiPsGetNextNamepath (      ACPI_WALK_STATE         *WalkState,      ACPI_PARSE_STATE        *ParserState,      ACPI_PARSE_OBJECT       *Arg, -    BOOLEAN                 MethodCall); +    BOOLEAN                 PossibleMethodCall); + +/* Values for BOOLEAN above */ + +#define ACPI_NOT_METHOD_CALL            FALSE +#define ACPI_POSSIBLE_METHOD_CALL       TRUE  ACPI_STATUS  AcpiPsGetNextArg ( diff --git a/source/include/acpixf.h b/source/include/acpixf.h index 80465d3c5aa2..1ecceff5a676 100644 --- a/source/include/acpixf.h +++ b/source/include/acpixf.h @@ -46,7 +46,7 @@  /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION                 0x20151124 +#define ACPI_CA_VERSION                 0x20151218  #include "acconfig.h"  #include "actypes.h" @@ -192,6 +192,11 @@ ACPI_INIT_GLOBAL (UINT8,            AcpiGbl_CopyDsdtLocally, FALSE);  ACPI_INIT_GLOBAL (UINT8,            AcpiGbl_DoNotUseXsdt, FALSE);  /* + * Optionally allow default region handlers to be overridden. + */ +ACPI_INIT_GLOBAL (UINT8,            AcpiGbl_OverrideDefaultRegionHandlers, FALSE); + +/*   * Optionally use 32-bit FADT addresses if and when there is a conflict   * (address mismatch) between the 32-bit and 64-bit versions of the   * address. Although ACPICA adheres to the ACPI specification which @@ -269,6 +274,10 @@ ACPI_INIT_GLOBAL (UINT32,           AcpiDbgLevel, ACPI_NORMAL_DEFAULT);  #endif  ACPI_INIT_GLOBAL (UINT32,           AcpiDbgLayer, ACPI_COMPONENT_DEFAULT); +/* Optionally enable timer output with Debug Object output */ + +ACPI_INIT_GLOBAL (UINT8,            AcpiGbl_DisplayDebugTimer, FALSE); +  /*   * Other miscellaneous globals   */ diff --git a/source/include/amlcode.h b/source/include/amlcode.h index b9b8ad5617ae..c0388eb6ffef 100644 --- a/source/include/amlcode.h +++ b/source/include/amlcode.h @@ -120,7 +120,7 @@  #define AML_CREATE_WORD_FIELD_OP    (UINT16) 0x8b  #define AML_CREATE_BYTE_FIELD_OP    (UINT16) 0x8c  #define AML_CREATE_BIT_FIELD_OP     (UINT16) 0x8d -#define AML_TYPE_OP                 (UINT16) 0x8e +#define AML_OBJECT_TYPE_OP          (UINT16) 0x8e  #define AML_CREATE_QWORD_FIELD_OP   (UINT16) 0x8f     /* ACPI 2.0 */  #define AML_LAND_OP                 (UINT16) 0x90  #define AML_LOR_OP                  (UINT16) 0x91 @@ -241,7 +241,8 @@  #define ARGP_TERMLIST               0x0F  #define ARGP_WORDDATA               0x10  #define ARGP_QWORDDATA              0x11 -#define ARGP_SIMPLENAME             0x12 +#define ARGP_SIMPLENAME             0x12 /* NameString | LocalTerm | ArgTerm */ +#define ARGP_NAME_OR_REF            0x13 /* For ObjectType only */  /*   * Resolved argument types for the AML Interpreter diff --git a/source/tools/acpibin/abmain.c b/source/tools/acpibin/abmain.c index 85f204527e8e..f5671891c984 100644 --- a/source/tools/acpibin/abmain.c +++ b/source/tools/acpibin/abmain.c @@ -76,8 +76,9 @@ AbDisplayUsage (      ACPI_USAGE_HEADER ("acpibin [options]"); -    ACPI_OPTION ("-c <File1><File2>",       "Compare two binary AML files"); -    ACPI_OPTION ("-d <In><Out>",            "Dump AML binary to text file"); +    ACPI_OPTION ("-c <File1> <File2>",      "Compare two binary AML files"); +    ACPI_OPTION ("-d <In> <Out>",           "Dump AML binary to text file"); +    ACPI_OPTION ("-e <Sig> <In> <Out>",     "Extract binary AML table from acpidump file");      ACPI_OPTION ("-h <File>",               "Display table header for binary AML file");      ACPI_OPTION ("-s <File>",               "Update checksum for binary AML file");      ACPI_OPTION ("-t",                      "Terse mode"); diff --git a/source/tools/acpiexec/aecommon.h b/source/tools/acpiexec/aecommon.h index bc30acf0ea11..6184c6b62b40 100644 --- a/source/tools/acpiexec/aecommon.h +++ b/source/tools/acpiexec/aecommon.h @@ -113,6 +113,10 @@ ACPI_STATUS  AeInstallTables (      void); +ACPI_STATUS +AeLoadTables ( +    void); +  void  AeDumpNamespace (      void); diff --git a/source/tools/acpiexec/aehandlers.c b/source/tools/acpiexec/aehandlers.c index 625cf5704d4f..ba461dd453b1 100644 --- a/source/tools/acpiexec/aehandlers.c +++ b/source/tools/acpiexec/aehandlers.c @@ -693,7 +693,39 @@ AeInstallLateHandlers (      void)  {      ACPI_STATUS             Status; +    ACPI_HANDLE             Handle; + + +    Status = AcpiGetHandle (NULL, "\\_TZ.TZ1", &Handle); +    if (ACPI_SUCCESS (Status)) +    { +        Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, +            AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567)); + +        Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, +            AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF)); + +        Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY, +            AeNotifyHandler1); +        Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY, +            AeNotifyHandler2); +        Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, +            AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF)); + +        Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, +            AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567)); +    } + +    Status = AcpiGetHandle (NULL, "\\_PR.CPU0", &Handle); +    if (ACPI_SUCCESS (Status)) +    { +        Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, +            AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567)); + +        Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY, +            AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF)); +    }  #if (!ACPI_REDUCED_HARDWARE)      if (!AcpiGbl_ReducedHardware) @@ -879,37 +911,6 @@ AeInstallEarlyHandlers (          printf ("No _SB_ found, %s\n", AcpiFormatException (Status));      } -    Status = AcpiGetHandle (NULL, "\\_TZ.TZ1", &Handle); -    if (ACPI_SUCCESS (Status)) -    { -        Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, -            AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567)); - -        Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, -            AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF)); - -        Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY, -            AeNotifyHandler1); -        Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY, -            AeNotifyHandler2); - -        Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, -            AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF)); - -        Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, -            AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567)); -    } - -    Status = AcpiGetHandle (NULL, "\\_PR.CPU0", &Handle); -    if (ACPI_SUCCESS (Status)) -    { -        Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, -            AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567)); - -        Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY, -            AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF)); -    } -      /*       * Install handlers that will override the default handlers for some of       * the space IDs. diff --git a/source/tools/acpiexec/aemain.c b/source/tools/acpiexec/aemain.c index bc35036df4b4..a5f168c237b0 100644 --- a/source/tools/acpiexec/aemain.c +++ b/source/tools/acpiexec/aemain.c @@ -152,9 +152,11 @@ usage (      ACPI_OPTION ("-dt",                 "Disable allocation tracking (performance)");      printf ("\n"); +    ACPI_OPTION ("-ed",                 "Enable timer output for Debug Object");      ACPI_OPTION ("-ef",                 "Enable display of final memory statistics");      ACPI_OPTION ("-ei",                 "Enable additional tests for ACPICA interfaces");      ACPI_OPTION ("-el",                 "Enable loading of additional test tables"); +    ACPI_OPTION ("-em",                 "Enable grouping of module-level code");      ACPI_OPTION ("-es",                 "Enable Interpreter Slack Mode");      ACPI_OPTION ("-et",                 "Enable debug semaphore timeout");      printf ("\n"); @@ -258,6 +260,11 @@ AeDoOptions (          switch (AcpiGbl_Optarg[0])          { +        case 'd': + +            AcpiGbl_DisplayDebugTimer = TRUE; +            break; +          case 'f':              #ifdef ACPI_DBG_TRACK_ALLOCATIONS @@ -275,6 +282,11 @@ AeDoOptions (              AcpiGbl_LoadTestTables = TRUE;              break; +        case 'm': + +            AcpiGbl_GroupModuleLevelCode = TRUE; +            break; +          case 's':              AcpiGbl_EnableInterpreterSlack = TRUE; @@ -456,6 +468,7 @@ main (      /* Init ACPICA and start debugger thread */ +    AcpiGbl_OverrideDefaultRegionHandlers = TRUE;      Status = AcpiInitializeSubsystem ();      ACPI_CHECK_OK (AcpiInitializeSubsystem, Status);      if (ACPI_FAILURE (Status)) @@ -513,7 +526,7 @@ main (      {          /* Get all ACPI AML tables in this file */ -        Status = AcpiAcGetAllTablesFromFile (argv[AcpiGbl_Optind], +        Status = AcGetAllTablesFromFile (argv[AcpiGbl_Optind],              ACPI_GET_ONLY_AML_TABLES, &ListHead);          if (ACPI_FAILURE (Status))          { @@ -534,28 +547,21 @@ main (          goto ErrorExit;      } -    Status = AeInstallTables (); +    /* Install all of the ACPI tables */ -    /* -     * Exit namespace initialization for the "load namespace only" option. -     * No control methods will be executed. However, still enter the -     * the debugger. -     */ -    if (AcpiGbl_AeLoadOnly) -    { -        goto EnterDebugger; -    } +    Status = AeInstallTables ();      if (ACPI_FAILURE (Status))      { -        printf ("**** Could not load ACPI tables, %s\n", +        printf ("**** Could not install ACPI tables, %s\n",              AcpiFormatException (Status));          goto EnterDebugger;      }      /* -     * Install most of the handlers. -     * Override some default region handlers, especially SystemMemory +     * Install most of the handlers (Regions, Notify, Table, etc.) +     * Override the default region handlers, especially SystemMemory, +     * which is simulated in this utility.       */      Status = AeInstallEarlyHandlers ();      if (ACPI_FAILURE (Status)) @@ -583,6 +589,25 @@ main (          goto EnterDebugger;      } +    Status = AeLoadTables (); + +    /* +     * Exit namespace initialization for the "load namespace only" option. +     * No control methods will be executed. However, still enter the +     * the debugger. +     */ +    if (AcpiGbl_AeLoadOnly) +    { +        goto EnterDebugger; +    } + +    if (ACPI_FAILURE (Status)) +    { +        printf ("**** Could not load ACPI tables, %s\n", +            AcpiFormatException (Status)); +        goto EnterDebugger; +    } +      /*       * Install handlers for "device driver" space IDs (EC,SMBus, etc.)       * and fixed event handlers @@ -637,6 +662,7 @@ EnterDebugger:          break;      } +    (void) AcpiOsTerminate ();      return (0); diff --git a/source/tools/acpiexec/aeregion.c b/source/tools/acpiexec/aeregion.c index a33e9e70def1..31b4202974b0 100644 --- a/source/tools/acpiexec/aeregion.c +++ b/source/tools/acpiexec/aeregion.c @@ -149,59 +149,87 @@ AeRegionInit (  } +/****************************************************************************** + * + * FUNCTION:    AeOverrideRegionHandlers + * + * PARAMETERS:  None + * + * RETURN:      None + * + * DESCRIPTION: Override the default region handlers for memory, i/o, and + *              pci_config. Also install a handler for EC. This is part of + *              the "install early handlers" functionality. + * + *****************************************************************************/ +  void -AeInstallRegionHandlers ( +AeOverrideRegionHandlers (      void)  {      UINT32                  i;      ACPI_STATUS             Status;      /* -     * Install handlers for some of the "device driver" address spaces -     * such as SMBus, etc. +     * Install handlers that will override the default handlers for some of +     * the space IDs.       */ -    for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++) +    for (i = 0; i < ACPI_ARRAY_LENGTH (DefaultSpaceIdList); i++)      {          /* Install handler at the root object */          Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT, -            SpaceIdList[i], AeRegionHandler, +            DefaultSpaceIdList[i], AeRegionHandler,              AeRegionInit, &AeMyContext); +          if (ACPI_FAILURE (Status))          {              ACPI_EXCEPTION ((AE_INFO, Status,                  "Could not install an OpRegion handler for %s space(%u)", -                AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i])); -            return; +                AcpiUtGetRegionName ((UINT8) DefaultSpaceIdList[i]), +                DefaultSpaceIdList[i]));          }      }  } +/****************************************************************************** + * + * FUNCTION:    AeInstallRegionHandlers + * + * PARAMETERS:  None + * + * RETURN:      None + * + * DESCRIPTION: Install handlers for the address spaces other than memory, + *              i/o, and pci_config. + * + *****************************************************************************/ +  void -AeOverrideRegionHandlers ( +AeInstallRegionHandlers (      void)  {      UINT32                  i;      ACPI_STATUS             Status;      /* -     * Install handlers that will override the default handlers for some of -     * the space IDs. +     * Install handlers for some of the "device driver" address spaces +     * such as SMBus, etc.       */ -    for (i = 0; i < ACPI_ARRAY_LENGTH (DefaultSpaceIdList); i++) +    for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++)      {          /* Install handler at the root object */          Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT, -            DefaultSpaceIdList[i], AeRegionHandler, +            SpaceIdList[i], AeRegionHandler,              AeRegionInit, &AeMyContext); +          if (ACPI_FAILURE (Status))          {              ACPI_EXCEPTION ((AE_INFO, Status, -                "Could not install a default OpRegion handler for %s space(%u)", -                AcpiUtGetRegionName ((UINT8) DefaultSpaceIdList[i]), -                DefaultSpaceIdList[i])); +                "Could not install an OpRegion handler for %s space(%u)", +                AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i]));              return;          }      } diff --git a/source/tools/acpiexec/aetables.c b/source/tools/acpiexec/aetables.c index 7e81fc3cefd0..a5129b896cdb 100644 --- a/source/tools/acpiexec/aetables.c +++ b/source/tools/acpiexec/aetables.c @@ -229,9 +229,6 @@ AeBuildLocalTables (      /*       * Install the user tables. The DSDT must be installed in the FADT.       * All other tables are installed directly into the XSDT. -     * -     * Note: The tables are loaded in reverse order from the incoming -     * input, which makes it match the command line order.       */      NextTable = ListHead;      while (NextTable) @@ -262,7 +259,7 @@ AeBuildLocalTables (          {              /* Install the table in the XSDT */ -            LocalXSDT->TableOffsetEntry[TableCount - NextIndex + 1] = +            LocalXSDT->TableOffsetEntry[NextIndex] =                  ACPI_PTR_TO_PHYSADDR (NextTable->Table);              NextIndex++;          } @@ -493,27 +490,6 @@ AeInstallTables (      Status = AcpiInitializeTables (NULL, ACPI_MAX_INIT_TABLES, TRUE);      ACPI_CHECK_OK (AcpiInitializeTables, Status); -    Status = AcpiLoadTables (); -    ACPI_CHECK_OK (AcpiLoadTables, Status); - -    /* -     * Test run-time control method installation. Do it twice to test code -     * for an existing name. -     */ -    Status = AcpiInstallMethod (MethodCode); -    if (ACPI_FAILURE (Status)) -    { -        AcpiOsPrintf ("%s, Could not install method\n", -            AcpiFormatException (Status)); -    } - -    Status = AcpiInstallMethod (MethodCode); -    if (ACPI_FAILURE (Status)) -    { -        AcpiOsPrintf ("%s, Could not install method\n", -            AcpiFormatException (Status)); -    } -      if (AcpiGbl_LoadTestTables)      {          /* Test multiple table/UEFI support. First, get the headers */ @@ -558,6 +534,50 @@ AeInstallTables (  /******************************************************************************   * + * FUNCTION:    AeLoadTables + * + * PARAMETERS:  None + * + * RETURN:      Status + * + * DESCRIPTION: Load the definition block ACPI tables + * + *****************************************************************************/ + +ACPI_STATUS +AeLoadTables ( +    void) +{ +    ACPI_STATUS             Status; + + +    Status = AcpiLoadTables (); +    ACPI_CHECK_OK (AcpiLoadTables, Status); + +    /* +     * Test run-time control method installation. Do it twice to test code +     * for an existing name. +     */ +    Status = AcpiInstallMethod (MethodCode); +    if (ACPI_FAILURE (Status)) +    { +        AcpiOsPrintf ("%s, Could not install method\n", +            AcpiFormatException (Status)); +    } + +    Status = AcpiInstallMethod (MethodCode); +    if (ACPI_FAILURE (Status)) +    { +        AcpiOsPrintf ("%s, Could not install method\n", +            AcpiFormatException (Status)); +    } + +    return (AE_OK); +} + + +/****************************************************************************** + *   * FUNCTION:    AcpiOsGetRootPointer   *   * PARAMETERS:  Flags       - not used diff --git a/source/tools/acpinames/anmain.c b/source/tools/acpinames/anmain.c index 8b0e0220aa01..9eaed3b0dccd 100644 --- a/source/tools/acpinames/anmain.c +++ b/source/tools/acpinames/anmain.c @@ -175,7 +175,7 @@ main (      {          /* Get all ACPI AML tables in this file */ -        Status = AcpiAcGetAllTablesFromFile (argv[AcpiGbl_Optind], +        Status = AcGetAllTablesFromFile (argv[AcpiGbl_Optind],              ACPI_GET_ONLY_AML_TABLES, &ListHead);          if (ACPI_FAILURE (Status))          { diff --git a/source/tools/examples/examples.c b/source/tools/examples/examples.c index 98d7bbcb908b..4b1d9fcc107f 100644 --- a/source/tools/examples/examples.c +++ b/source/tools/examples/examples.c @@ -176,6 +176,7 @@ InitializeFullAcpica (void)      /* Initialize the ACPICA subsystem */ +    AcpiGbl_OverrideDefaultRegionHandlers = TRUE;      Status = AcpiInitializeSubsystem ();      if (ACPI_FAILURE (Status))      { @@ -194,15 +195,6 @@ InitializeFullAcpica (void)          return (Status);      } -    /* Create the ACPI namespace from ACPI tables */ - -    Status = AcpiLoadTables (); -    if (ACPI_FAILURE (Status)) -    { -        ACPI_EXCEPTION ((AE_INFO, Status, "While loading ACPI tables")); -        return (Status); -    } -      /* Install local handlers */      Status = InstallHandlers (); @@ -221,6 +213,15 @@ InitializeFullAcpica (void)          return (Status);      } +    /* Create the ACPI namespace from ACPI tables */ + +    Status = AcpiLoadTables (); +    if (ACPI_FAILURE (Status)) +    { +        ACPI_EXCEPTION ((AE_INFO, Status, "While loading ACPI tables")); +        return (Status); +    } +      /* Complete the ACPI namespace object initialization */      Status = AcpiInitializeObjects (ACPI_FULL_INITIALIZATION); @@ -283,6 +284,7 @@ InitializeAcpi (      /* Initialize the ACPICA subsystem */ +    AcpiGbl_OverrideDefaultRegionHandlers = TRUE;      Status = AcpiInitializeSubsystem ();      if (ACPI_FAILURE (Status))      { @@ -297,26 +299,26 @@ InitializeAcpi (          return (Status);      } -    /* Create the ACPI namespace from ACPI tables */ +    /* Install local handlers */ -    Status = AcpiLoadTables (); +    Status = InstallHandlers ();      if (ACPI_FAILURE (Status))      { +        ACPI_EXCEPTION ((AE_INFO, Status, "While installing handlers"));          return (Status);      } -    /* Install local handlers */ +    /* Initialize the ACPI hardware */ -    Status = InstallHandlers (); +    Status = AcpiEnableSubsystem (ACPI_FULL_INITIALIZATION);      if (ACPI_FAILURE (Status))      { -        ACPI_EXCEPTION ((AE_INFO, Status, "While installing handlers"));          return (Status);      } -    /* Initialize the ACPI hardware */ +    /* Create the ACPI namespace from ACPI tables */ -    Status = AcpiEnableSubsystem (ACPI_FULL_INITIALIZATION); +    Status = AcpiLoadTables ();      if (ACPI_FAILURE (Status))      {          return (Status); diff --git a/tests/misc/grammar.asl b/tests/misc/grammar.asl index ee0f2bcee1f5..b808065b6518 100644 --- a/tests/misc/grammar.asl +++ b/tests/misc/grammar.asl @@ -1280,6 +1280,10 @@ DefinitionBlock (              Store ("****** There were errors during the execution of the test ******", Debug)          } +        // Flush all notifies + +        Sleep (250) +          //          // Last Test          // @@ -1922,8 +1926,6 @@ DefinitionBlock (              }          }) -    /* Parser thinks this is a method invocation!! */ -          Store (RefOf (MAIN), Local5)          // For this to work, ABCD must NOT exist. | 
