diff options
Diffstat (limited to 'source/components/tables')
| -rw-r--r-- | source/components/tables/tbdata.c | 86 | ||||
| -rw-r--r-- | source/components/tables/tbfadt.c | 23 | ||||
| -rw-r--r-- | source/components/tables/tbutils.c | 96 | ||||
| -rw-r--r-- | source/components/tables/tbxface.c | 133 | ||||
| -rw-r--r-- | source/components/tables/tbxfload.c | 35 | 
5 files changed, 266 insertions, 107 deletions
| diff --git a/source/components/tables/tbdata.c b/source/components/tables/tbdata.c index 81b3abcfdd7bf..95b5b2672cd27 100644 --- a/source/components/tables/tbdata.c +++ b/source/components/tables/tbdata.c @@ -937,9 +937,9 @@ AcpiTbLoadTable (   *   * FUNCTION:    AcpiTbInstallAndLoadTable   * - * PARAMETERS:  Table                   - Pointer to the table - *              Address                 - Physical address of the table + * PARAMETERS:  Address                 - Physical address of the table   *              Flags                   - Allocation flags of the table + *              Override                - Whether override should be performed   *              TableIndex              - Where table index is returned   *   * RETURN:      Status @@ -950,7 +950,6 @@ AcpiTbLoadTable (  ACPI_STATUS  AcpiTbInstallAndLoadTable ( -    ACPI_TABLE_HEADER       *Table,      ACPI_PHYSICAL_ADDRESS   Address,      UINT8                   Flags,      BOOLEAN                 Override, @@ -958,10 +957,9 @@ AcpiTbInstallAndLoadTable (  {      ACPI_STATUS             Status;      UINT32                  i; -    ACPI_OWNER_ID           OwnerId; -    ACPI_FUNCTION_TRACE (AcpiLoadTable); +    ACPI_FUNCTION_TRACE (TbInstallAndLoadTable);      (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); @@ -975,48 +973,68 @@ AcpiTbInstallAndLoadTable (          goto UnlockAndExit;      } -    /* -     * Note: Now table is "INSTALLED", it must be validated before -     * using. -     */ -    Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]); -    if (ACPI_FAILURE (Status)) -    { -        goto UnlockAndExit; -    } +    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); +    Status = AcpiTbLoadTable (i, AcpiGbl_RootNode); +    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); +UnlockAndExit: +    *TableIndex = i;      (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); -    Status = AcpiNsLoadTable (i, AcpiGbl_RootNode); +    return_ACPI_STATUS (Status); +} -    /* Execute any module-level code that was found in the table */ -    if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode) -    { -        AcpiNsExecModuleCodeList (); -    } +/******************************************************************************* + * + * FUNCTION:    AcpiTbUnloadTable + * + * PARAMETERS:  TableIndex              - Table index + * + * RETURN:      Status + * + * DESCRIPTION: Unload an ACPI table + * + ******************************************************************************/ -    /* -     * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is -     * responsible for discovering any new wake GPEs by running _PRW methods -     * that may have been loaded by this table. -     */ -    Status = AcpiTbGetOwnerId (i, &OwnerId); -    if (ACPI_SUCCESS (Status)) +ACPI_STATUS +AcpiTbUnloadTable ( +    UINT32                  TableIndex) +{ +    ACPI_STATUS             Status = AE_OK; +    ACPI_TABLE_HEADER       *Table; + + +    ACPI_FUNCTION_TRACE (TbUnloadTable); + + +    /* Ensure the table is still loaded */ + +    if (!AcpiTbIsTableLoaded (TableIndex))      { -        AcpiEvUpdateGpes (OwnerId); +        return_ACPI_STATUS (AE_NOT_EXIST);      }      /* Invoke table handler if present */      if (AcpiGbl_TableHandler)      { -        (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table, -            AcpiGbl_TableHandlerContext); +        Status = AcpiGetTableByIndex (TableIndex, &Table); +        if (ACPI_SUCCESS (Status)) +        { +            (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, Table, +                AcpiGbl_TableHandlerContext); +        }      } -    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); -UnlockAndExit: -    *TableIndex = i; -    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); +    /* Delete the portion of the namespace owned by this table */ + +    Status = AcpiTbDeleteNamespaceByOwner (TableIndex); +    if (ACPI_FAILURE (Status)) +    { +        return_ACPI_STATUS (Status); +    } + +    (void) AcpiTbReleaseOwnerId (TableIndex); +    AcpiTbSetTableLoadedFlag (TableIndex, FALSE);      return_ACPI_STATUS (Status);  } diff --git a/source/components/tables/tbfadt.c b/source/components/tables/tbfadt.c index b75b52d9d0b97..1d327dc3113bb 100644 --- a/source/components/tables/tbfadt.c +++ b/source/components/tables/tbfadt.c @@ -341,6 +341,8 @@ AcpiTbParseFadt (  {      UINT32                  Length;      ACPI_TABLE_HEADER       *Table; +    ACPI_TABLE_DESC         *FadtDesc; +    ACPI_STATUS             Status;      /* @@ -350,14 +352,13 @@ AcpiTbParseFadt (       * Get a local copy of the FADT and convert it to a common format       * Map entire FADT, assumed to be smaller than one page.       */ -    Length = AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex].Length; - -    Table = AcpiOsMapMemory ( -        AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex].Address, Length); -    if (!Table) +    FadtDesc = &AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex]; +    Status = AcpiTbGetTable (FadtDesc, &Table); +    if (ACPI_FAILURE (Status))      {          return;      } +    Length = FadtDesc->Length;      /*       * Validate the FADT checksum before we copy the table. Ignore @@ -371,7 +372,7 @@ AcpiTbParseFadt (      /* All done with the real FADT, unmap it */ -    AcpiOsUnmapMemory (Table, Length); +    AcpiTbPutTable (FadtDesc);      /* Obtain the DSDT and FACS tables via their addresses within the FADT */ @@ -522,19 +523,17 @@ AcpiTbConvertFadt (      /* -     * For ACPI 1.0 FADTs (revision 1), ensure that reserved fields which +     * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which       * should be zero are indeed zero. This will workaround BIOSs that       * inadvertently place values in these fields.       *       * The ACPI 1.0 reserved fields that will be zeroed are the bytes located       * at offset 45, 55, 95, and the word located at offset 109, 110.       * -     * Note: The FADT revision value is unreliable because of BIOS errors. -     * The table length is instead used as the final word on the version. -     * -     * Note: FADT revision 3 is the ACPI 2.0 version of the FADT. +     * Note: The FADT revision value is unreliable. Only the length can be +     * trusted.       */ -    if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V3_SIZE) +    if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE)      {          AcpiGbl_FADT.PreferredProfile = 0;          AcpiGbl_FADT.PstateControl = 0; diff --git a/source/components/tables/tbutils.c b/source/components/tables/tbutils.c index 85b9c3e4c561a..6fc30a69fa388 100644 --- a/source/components/tables/tbutils.c +++ b/source/components/tables/tbutils.c @@ -411,3 +411,99 @@ NextTable:      AcpiOsUnmapMemory (Table, Length);      return_ACPI_STATUS (AE_OK);  } + + +/******************************************************************************* + * + * FUNCTION:    AcpiTbGetTable + * + * PARAMETERS:  TableDesc           - Table descriptor + *              OutTable            - Where the pointer to the table is returned + * + * RETURN:      Status and pointer to the requested table + * + * DESCRIPTION: Increase a reference to a table descriptor and return the + *              validated table pointer. + *              If the table descriptor is an entry of the root table list, + *              this API must be invoked with ACPI_MTX_TABLES acquired. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbGetTable ( +    ACPI_TABLE_DESC        *TableDesc, +    ACPI_TABLE_HEADER      **OutTable) +{ +    ACPI_STATUS            Status; + + +    ACPI_FUNCTION_TRACE (AcpiTbGetTable); + + +    if (TableDesc->ValidationCount == 0) +    { +        /* Table need to be "VALIDATED" */ + +        Status = AcpiTbValidateTable (TableDesc); +        if (ACPI_FAILURE (Status)) +        { +            return_ACPI_STATUS (Status); +        } +    } + +    TableDesc->ValidationCount++; +    if (TableDesc->ValidationCount == 0) +    { +        ACPI_ERROR ((AE_INFO, +            "Table %p, Validation count is zero after increment\n", +            TableDesc)); +        TableDesc->ValidationCount--; +        return_ACPI_STATUS (AE_LIMIT); +    } + +    *OutTable = TableDesc->Pointer; +    return_ACPI_STATUS (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION:    AcpiTbPutTable + * + * PARAMETERS:  TableDesc           - Table descriptor + * + * RETURN:      None + * + * DESCRIPTION: Decrease a reference to a table descriptor and release the + *              validated table pointer if no references. + *              If the table descriptor is an entry of the root table list, + *              this API must be invoked with ACPI_MTX_TABLES acquired. + * + ******************************************************************************/ + +void +AcpiTbPutTable ( +    ACPI_TABLE_DESC        *TableDesc) +{ + +    ACPI_FUNCTION_TRACE (AcpiTbPutTable); + + +    if (TableDesc->ValidationCount == 0) +    { +        ACPI_WARNING ((AE_INFO, +            "Table %p, Validation count is zero before decrement\n", +            TableDesc)); +        return_VOID; +    } +    TableDesc->ValidationCount--; + +    if (TableDesc->ValidationCount == 0) +    { +        /* Table need to be "INVALIDATED" */ + +        AcpiTbInvalidateTable (TableDesc); +    } + +    return_VOID; +} diff --git a/source/components/tables/tbxface.c b/source/components/tables/tbxface.c index 4c8c065cf3730..9346933cf5274 100644 --- a/source/components/tables/tbxface.c +++ b/source/components/tables/tbxface.c @@ -184,6 +184,7 @@ AcpiReallocateRootTable (      void)  {      ACPI_STATUS             Status; +    UINT32                  i;      ACPI_FUNCTION_TRACE (AcpiReallocateRootTable); @@ -198,6 +199,22 @@ AcpiReallocateRootTable (          return_ACPI_STATUS (AE_SUPPORT);      } +    /* +     * Ensure OS early boot logic, which is required by some hosts. If the +     * table state is reported to be wrong, developers should fix the +     * issue by invoking AcpiPutTable() for the reported table during the +     * early stage. +     */ +    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) +    { +        if (AcpiGbl_RootTableList.Tables[i].Pointer) +        { +            ACPI_ERROR ((AE_INFO, +                "Table [%4.4s] is not invalidated during early boot stage", +                AcpiGbl_RootTableList.Tables[i].Signature.Ascii)); +        } +    } +      AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;      Status = AcpiTbResizeRootTableList (); @@ -307,6 +324,11 @@ ACPI_EXPORT_SYMBOL (AcpiGetTableHeader)   *   * DESCRIPTION: Finds and verifies an ACPI table. Table must be in the   *              RSDT/XSDT. + *              Note that an early stage AcpiGetTable() call must be paired + *              with an early stage AcpiPutTable() call. otherwise the table + *              pointer mapped by the early stage mapping implementation may be + *              erroneously unmapped by the late stage unmapping implementation + *              in an AcpiPutTable() invoked during the late stage.   *   ******************************************************************************/ @@ -318,7 +340,8 @@ AcpiGetTable (  {      UINT32                  i;      UINT32                  j; -    ACPI_STATUS             Status; +    ACPI_STATUS             Status = AE_NOT_FOUND; +    ACPI_TABLE_DESC         *TableDesc;      /* Parameter validation */ @@ -328,12 +351,22 @@ AcpiGetTable (          return (AE_BAD_PARAMETER);      } +    /* +     * Note that the following line is required by some OSPMs, they only +     * check if the returned table is NULL instead of the returned status +     * to determined if this function is succeeded. +     */ +    *OutTable = NULL; + +    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); +      /* Walk the root table list */      for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)      { -        if (!ACPI_COMPARE_NAME ( -                &(AcpiGbl_RootTableList.Tables[i].Signature), Signature)) +        TableDesc = &AcpiGbl_RootTableList.Tables[i]; + +        if (!ACPI_COMPARE_NAME (&TableDesc->Signature, Signature))          {              continue;          } @@ -343,19 +376,66 @@ AcpiGetTable (              continue;          } -        Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]); -        if (ACPI_SUCCESS (Status)) +        Status = AcpiTbGetTable (TableDesc, OutTable); +        break; +    } + +    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); +    return (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiGetTable) + + +/******************************************************************************* + * + * FUNCTION:    AcpiPutTable + * + * PARAMETERS:  Table               - The pointer to the table + * + * RETURN:      None + * + * DESCRIPTION: Release a table returned by AcpiGetTable() and its clones. + *              Note that it is not safe if this function was invoked after an + *              uninstallation happened to the original table descriptor. + *              Currently there is no OSPMs' requirement to handle such + *              situations. + * + ******************************************************************************/ + +void +AcpiPutTable ( +    ACPI_TABLE_HEADER       *Table) +{ +    UINT32                  i; +    ACPI_TABLE_DESC         *TableDesc; + + +    ACPI_FUNCTION_TRACE (AcpiPutTable); + + +    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + +    /* Walk the root table list */ + +    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) +    { +        TableDesc = &AcpiGbl_RootTableList.Tables[i]; + +        if (TableDesc->Pointer != Table)          { -            *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer; +            continue;          } -        return (Status); +        AcpiTbPutTable (TableDesc); +        break;      } -    return (AE_NOT_FOUND); +    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); +    return_VOID;  } -ACPI_EXPORT_SYMBOL (AcpiGetTable) +ACPI_EXPORT_SYMBOL (AcpiPutTable)  /******************************************************************************* @@ -363,7 +443,7 @@ ACPI_EXPORT_SYMBOL (AcpiGetTable)   * FUNCTION:    AcpiGetTableByIndex   *   * PARAMETERS:  TableIndex          - Table index - *              Table               - Where the pointer to the table is returned + *              OutTable            - Where the pointer to the table is returned   *   * RETURN:      Status and pointer to the requested table   * @@ -375,7 +455,7 @@ ACPI_EXPORT_SYMBOL (AcpiGetTable)  ACPI_STATUS  AcpiGetTableByIndex (      UINT32                  TableIndex, -    ACPI_TABLE_HEADER       **Table) +    ACPI_TABLE_HEADER       **OutTable)  {      ACPI_STATUS             Status; @@ -385,37 +465,34 @@ AcpiGetTableByIndex (      /* Parameter validation */ -    if (!Table) +    if (!OutTable)      {          return_ACPI_STATUS (AE_BAD_PARAMETER);      } +    /* +     * Note that the following line is required by some OSPMs, they only +     * check if the returned table is NULL instead of the returned status +     * to determined if this function is succeeded. +     */ +    *OutTable = NULL; +      (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);      /* Validate index */      if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)      { -        (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); -        return_ACPI_STATUS (AE_BAD_PARAMETER); +        Status = AE_BAD_PARAMETER; +        goto UnlockAndExit;      } -    if (!AcpiGbl_RootTableList.Tables[TableIndex].Pointer) -    { -        /* Table is not mapped, map it */ - -        Status = AcpiTbValidateTable ( -            &AcpiGbl_RootTableList.Tables[TableIndex]); -        if (ACPI_FAILURE (Status)) -        { -            (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); -            return_ACPI_STATUS (Status); -        } -    } +    Status = AcpiTbGetTable ( +        &AcpiGbl_RootTableList.Tables[TableIndex], OutTable); -    *Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer; +UnlockAndExit:      (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); -    return_ACPI_STATUS (AE_OK); +    return_ACPI_STATUS (Status);  }  ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex) diff --git a/source/components/tables/tbxfload.c b/source/components/tables/tbxfload.c index 43fe397fde568..30c6534a56995 100644 --- a/source/components/tables/tbxfload.c +++ b/source/components/tables/tbxfload.c @@ -372,7 +372,7 @@ AcpiLoadTable (      /* Install the table and load it into the namespace */      ACPI_INFO (("Host-directed Dynamic ACPI Table Load:")); -    Status = AcpiTbInstallAndLoadTable (Table, ACPI_PTR_TO_PHYSADDR (Table), +    Status = AcpiTbInstallAndLoadTable (ACPI_PTR_TO_PHYSADDR (Table),          ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, FALSE, &TableIndex);      return_ACPI_STATUS (Status);  } @@ -459,39 +459,8 @@ AcpiUnloadParentTable (              break;          } -        /* Ensure the table is actually loaded */ -          (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); -        if (!AcpiTbIsTableLoaded (i)) -        { -            Status = AE_NOT_EXIST; -            (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); -            break; -        } - -        /* Invoke table handler if present */ - -        if (AcpiGbl_TableHandler) -        { -            (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, -                AcpiGbl_RootTableList.Tables[i].Pointer, -                AcpiGbl_TableHandlerContext); -        } - -        /* -         * Delete all namespace objects owned by this table. Note that -         * these objects can appear anywhere in the namespace by virtue -         * of the AML "Scope" operator. Thus, we need to track ownership -         * by an ID, not simply a position within the hierarchy. -         */ -        Status = AcpiTbDeleteNamespaceByOwner (i); -        if (ACPI_FAILURE (Status)) -        { -            break; -        } - -        Status = AcpiTbReleaseOwnerId (i); -        AcpiTbSetTableLoadedFlag (i, FALSE); +        Status = AcpiTbUnloadTable (i);          (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);          break;      } | 
