summaryrefslogtreecommitdiffstats
path: root/sys/contrib/dev/acpica/components/namespace/nsrepair2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/components/namespace/nsrepair2.c')
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nsrepair2.c304
1 files changed, 271 insertions, 33 deletions
diff --git a/sys/contrib/dev/acpica/components/namespace/nsrepair2.c b/sys/contrib/dev/acpica/components/namespace/nsrepair2.c
index 7486dd7..85379e6 100644
--- a/sys/contrib/dev/acpica/components/namespace/nsrepair2.c
+++ b/sys/contrib/dev/acpica/components/namespace/nsrepair2.c
@@ -86,6 +86,11 @@ AcpiNsRepair_CID (
ACPI_OPERAND_OBJECT **ReturnObjectPtr);
static ACPI_STATUS
+AcpiNsRepair_CST (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+static ACPI_STATUS
AcpiNsRepair_FDE (
ACPI_EVALUATE_INFO *Info,
ACPI_OPERAND_OBJECT **ReturnObjectPtr);
@@ -96,6 +101,11 @@ AcpiNsRepair_HID (
ACPI_OPERAND_OBJECT **ReturnObjectPtr);
static ACPI_STATUS
+AcpiNsRepair_PRT (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+static ACPI_STATUS
AcpiNsRepair_PSS (
ACPI_EVALUATE_INFO *Info,
ACPI_OPERAND_OBJECT **ReturnObjectPtr);
@@ -109,11 +119,22 @@ static ACPI_STATUS
AcpiNsCheckSortedList (
ACPI_EVALUATE_INFO *Info,
ACPI_OPERAND_OBJECT *ReturnObject,
+ UINT32 StartIndex,
UINT32 ExpectedCount,
UINT32 SortIndex,
UINT8 SortDirection,
char *SortKeyName);
+/* Values for SortDirection above */
+
+#define ACPI_SORT_ASCENDING 0
+#define ACPI_SORT_DESCENDING 1
+
+static void
+AcpiNsRemoveElement (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 Index);
+
static void
AcpiNsSortList (
ACPI_OPERAND_OBJECT **Elements,
@@ -121,11 +142,6 @@ AcpiNsSortList (
UINT32 Index,
UINT8 SortDirection);
-/* Values for SortDirection above */
-
-#define ACPI_SORT_ASCENDING 0
-#define ACPI_SORT_DESCENDING 1
-
/*
* This table contains the names of the predefined methods for which we can
@@ -135,9 +151,11 @@ AcpiNsSortList (
*
* _ALR: Sort the list ascending by AmbientIlluminance
* _CID: Strings: uppercase all, remove any leading asterisk
+ * _CST: Sort the list ascending by C state type
* _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
* _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
* _HID: Strings: uppercase all, remove any leading asterisk
+ * _PRT: Fix reversed SourceName and SourceIndex
* _PSS: Sort the list descending by Power
* _TSS: Sort the list descending by Power
*
@@ -152,9 +170,11 @@ static const ACPI_REPAIR_INFO AcpiNsRepairableNames[] =
{
{"_ALR", AcpiNsRepair_ALR},
{"_CID", AcpiNsRepair_CID},
+ {"_CST", AcpiNsRepair_CST},
{"_FDE", AcpiNsRepair_FDE},
{"_GTM", AcpiNsRepair_FDE}, /* _GTM has same repair as _FDE */
{"_HID", AcpiNsRepair_HID},
+ {"_PRT", AcpiNsRepair_PRT},
{"_PSS", AcpiNsRepair_PSS},
{"_TSS", AcpiNsRepair_TSS},
{{0,0,0,0}, NULL} /* Table terminator */
@@ -267,7 +287,7 @@ AcpiNsRepair_ALR (
ACPI_STATUS Status;
- Status = AcpiNsCheckSortedList (Info, ReturnObject, 2, 1,
+ Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 2, 1,
ACPI_SORT_ASCENDING, "AmbientIlluminance");
return (Status);
@@ -354,6 +374,7 @@ AcpiNsRepair_FDE (
break;
default:
+
return (AE_AML_OPERAND_TYPE);
}
@@ -446,6 +467,97 @@ AcpiNsRepair_CID (
/******************************************************************************
*
+ * FUNCTION: AcpiNsRepair_CST
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _CST object:
+ * 1. Sort the list ascending by C state type
+ * 2. Ensure type cannot be zero
+ * 3. A sub-package count of zero means _CST is meaningless
+ * 4. Count must match the number of C state sub-packages
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+AcpiNsRepair_CST (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
+ ACPI_OPERAND_OBJECT **OuterElements;
+ UINT32 OuterElementCount;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+ BOOLEAN Removing;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_NAME (NsRepair_CST);
+
+
+ /*
+ * Entries (subpackages) in the _CST Package must be sorted by the
+ * C-state type, in ascending order.
+ */
+ Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1,
+ ACPI_SORT_ASCENDING, "C-State Type");
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /*
+ * We now know the list is correctly sorted by C-state type. Check if
+ * the C-state type values are proportional.
+ */
+ OuterElementCount = ReturnObject->Package.Count - 1;
+ i = 0;
+ while (i < OuterElementCount)
+ {
+ OuterElements = &ReturnObject->Package.Elements[i + 1];
+ Removing = FALSE;
+
+ if ((*OuterElements)->Package.Count == 0)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "SubPackage[%u] - removing entry due to zero count", i));
+ Removing = TRUE;
+ }
+
+ ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */
+ if ((UINT32) ObjDesc->Integer.Value == 0)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "SubPackage[%u] - removing entry due to invalid Type(0)", i));
+ Removing = TRUE;
+ }
+
+ if (Removing)
+ {
+ AcpiNsRemoveElement (ReturnObject, i + 1);
+ OuterElementCount--;
+ }
+ else
+ {
+ i++;
+ }
+ }
+
+ /* Update top-level package count, Type "Integer" checked elsewhere */
+
+ ObjDesc = ReturnObject->Package.Elements[0];
+ ObjDesc->Integer.Value = OuterElementCount;
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
* FUNCTION: AcpiNsRepair_HID
*
* PARAMETERS: Info - Method execution information block
@@ -536,7 +648,7 @@ AcpiNsRepair_HID (
/******************************************************************************
*
- * FUNCTION: AcpiNsRepair_TSS
+ * FUNCTION: AcpiNsRepair_PRT
*
* PARAMETERS: Info - Method execution information block
* ReturnObjectPtr - Pointer to the object returned from the
@@ -544,40 +656,57 @@ AcpiNsRepair_HID (
*
* RETURN: Status. AE_OK if object is OK or was repaired successfully
*
- * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
- * descending by the power dissipation values.
+ * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed
+ * SourceName and SourceIndex field, a common BIOS bug.
*
*****************************************************************************/
static ACPI_STATUS
-AcpiNsRepair_TSS (
+AcpiNsRepair_PRT (
ACPI_EVALUATE_INFO *Info,
ACPI_OPERAND_OBJECT **ReturnObjectPtr)
{
- ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
- ACPI_STATUS Status;
- ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *PackageObject = *ReturnObjectPtr;
+ ACPI_OPERAND_OBJECT **TopObjectList;
+ ACPI_OPERAND_OBJECT **SubObjectList;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ UINT32 ElementCount;
+ UINT32 Index;
- /*
- * We can only sort the _TSS return package if there is no _PSS in the
- * same scope. This is because if _PSS is present, the ACPI specification
- * dictates that the _TSS Power Dissipation field is to be ignored, and
- * therefore some BIOSs leave garbage values in the _TSS Power field(s).
- * In this case, it is best to just return the _TSS package as-is.
- * (May, 2011)
- */
- Status = AcpiNsGetNode (Info->Node, "^_PSS",
- ACPI_NS_NO_UPSEARCH, &Node);
- if (ACPI_SUCCESS (Status))
+ /* Each element in the _PRT package is a subpackage */
+
+ TopObjectList = PackageObject->Package.Elements;
+ ElementCount = PackageObject->Package.Count;
+
+ for (Index = 0; Index < ElementCount; Index++)
{
- return (AE_OK);
- }
+ SubObjectList = (*TopObjectList)->Package.Elements;
- Status = AcpiNsCheckSortedList (Info, ReturnObject, 5, 1,
- ACPI_SORT_DESCENDING, "PowerDissipation");
+ /*
+ * If the BIOS has erroneously reversed the _PRT SourceName (index 2)
+ * and the SourceIndex (index 3), fix it. _PRT is important enough to
+ * workaround this BIOS error. This also provides compatibility with
+ * other ACPI implementations.
+ */
+ ObjDesc = SubObjectList[3];
+ if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER))
+ {
+ SubObjectList[3] = SubObjectList[2];
+ SubObjectList[2] = ObjDesc;
+ Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
- return (Status);
+ ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags,
+ "PRT[%X]: Fixed reversed SourceName and SourceIndex",
+ Index));
+ }
+
+ /* Point to the next ACPI_OPERAND_OBJECT in the top level package */
+
+ TopObjectList++;
+ }
+
+ return (AE_OK);
}
@@ -619,7 +748,7 @@ AcpiNsRepair_PSS (
* incorrectly sorted, sort it. We sort by CpuFrequency, since this
* should be proportional to the power.
*/
- Status =AcpiNsCheckSortedList (Info, ReturnObject, 6, 0,
+ Status =AcpiNsCheckSortedList (Info, ReturnObject, 0, 6, 0,
ACPI_SORT_DESCENDING, "CpuFrequency");
if (ACPI_FAILURE (Status))
{
@@ -656,10 +785,58 @@ AcpiNsRepair_PSS (
/******************************************************************************
*
+ * FUNCTION: AcpiNsRepair_TSS
+ *
+ * PARAMETERS: Info - Method execution information block
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
+ * descending by the power dissipation values.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+AcpiNsRepair_TSS (
+ ACPI_EVALUATE_INFO *Info,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ /*
+ * We can only sort the _TSS return package if there is no _PSS in the
+ * same scope. This is because if _PSS is present, the ACPI specification
+ * dictates that the _TSS Power Dissipation field is to be ignored, and
+ * therefore some BIOSs leave garbage values in the _TSS Power field(s).
+ * In this case, it is best to just return the _TSS package as-is.
+ * (May, 2011)
+ */
+ Status = AcpiNsGetNode (Info->Node, "^_PSS",
+ ACPI_NS_NO_UPSEARCH, &Node);
+ if (ACPI_SUCCESS (Status))
+ {
+ return (AE_OK);
+ }
+
+ Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1,
+ ACPI_SORT_DESCENDING, "PowerDissipation");
+
+ return (Status);
+}
+
+
+/******************************************************************************
+ *
* FUNCTION: AcpiNsCheckSortedList
*
* PARAMETERS: Info - Method execution information block
* ReturnObject - Pointer to the top-level returned object
+ * StartIndex - Index of the first sub-package
* ExpectedCount - Minimum length of each sub-package
* SortIndex - Sub-package entry to sort on
* SortDirection - Ascending or descending
@@ -677,6 +854,7 @@ static ACPI_STATUS
AcpiNsCheckSortedList (
ACPI_EVALUATE_INFO *Info,
ACPI_OPERAND_OBJECT *ReturnObject,
+ UINT32 StartIndex,
UINT32 ExpectedCount,
UINT32 SortIndex,
UINT8 SortDirection,
@@ -705,13 +883,15 @@ AcpiNsCheckSortedList (
* Any NULL elements should have been removed by earlier call
* to AcpiNsRemoveNullElements.
*/
- OuterElements = ReturnObject->Package.Elements;
OuterElementCount = ReturnObject->Package.Count;
- if (!OuterElementCount)
+ if (!OuterElementCount || StartIndex >= OuterElementCount)
{
return (AE_AML_PACKAGE_LIMIT);
}
+ OuterElements = &ReturnObject->Package.Elements[StartIndex];
+ OuterElementCount -= StartIndex;
+
PreviousValue = 0;
if (SortDirection == ACPI_SORT_DESCENDING)
{
@@ -753,7 +933,7 @@ AcpiNsCheckSortedList (
((SortDirection == ACPI_SORT_DESCENDING) &&
(ObjDesc->Integer.Value > PreviousValue)))
{
- AcpiNsSortList (ReturnObject->Package.Elements,
+ AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex],
OuterElementCount, SortIndex, SortDirection);
Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
@@ -826,3 +1006,61 @@ AcpiNsSortList (
}
}
}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiNsRemoveElement
+ *
+ * PARAMETERS: ObjDesc - Package object element list
+ * Index - Index of element to remove
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Remove the requested element of a package and delete it.
+ *
+ *****************************************************************************/
+
+static void
+AcpiNsRemoveElement (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 Index)
+{
+ ACPI_OPERAND_OBJECT **Source;
+ ACPI_OPERAND_OBJECT **Dest;
+ UINT32 Count;
+ UINT32 NewCount;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_NAME (NsRemoveElement);
+
+
+ Count = ObjDesc->Package.Count;
+ NewCount = Count - 1;
+
+ Source = ObjDesc->Package.Elements;
+ Dest = Source;
+
+ /* Examine all elements of the package object, remove matched index */
+
+ for (i = 0; i < Count; i++)
+ {
+ if (i == Index)
+ {
+ AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */
+ AcpiUtRemoveReference (*Source);
+ }
+ else
+ {
+ *Dest = *Source;
+ Dest++;
+ }
+ Source++;
+ }
+
+ /* NULL terminate list and update the package count */
+
+ *Dest = NULL;
+ ObjDesc->Package.Count = NewCount;
+}
OpenPOWER on IntegriCloud