ReactOS  0.4.15-dev-3203-gacde1e0
nsrepair2.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Module Name: nsrepair2 - Repair for objects returned by specific
4  * predefined methods
5  *
6  *****************************************************************************/
7 
8 /*
9  * Copyright (C) 2000 - 2021, Intel Corp.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  * notice, this list of conditions, and the following disclaimer,
17  * without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  * substantially similar to the "NO WARRANTY" disclaimer below
20  * ("Disclaimer") and any redistribution must be conditioned upon
21  * including a substantially similar Disclaimer requirement for further
22  * binary redistribution.
23  * 3. Neither the names of the above-listed copyright holders nor the names
24  * of any contributors may be used to endorse or promote products derived
25  * from this software without specific prior written permission.
26  *
27  * Alternatively, this software may be distributed under the terms of the
28  * GNU General Public License ("GPL") version 2 as published by the Free
29  * Software Foundation.
30  *
31  * NO WARRANTY
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGES.
43  */
44 
45 #include "acpi.h"
46 #include "accommon.h"
47 #include "acnamesp.h"
48 
49 #define _COMPONENT ACPI_NAMESPACE
50  ACPI_MODULE_NAME ("nsrepair2")
51 
52 
53 /*
54  * Information structure and handler for ACPI predefined names that can
55  * be repaired on a per-name basis.
56  */
57 typedef
60  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
61 
63 {
66 
68 
69 
70 /* Local prototypes */
71 
72 static const ACPI_REPAIR_INFO *
75 
76 static ACPI_STATUS
79  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
80 
81 static ACPI_STATUS
84  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
85 
86 static ACPI_STATUS
89  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
90 
91 static ACPI_STATUS
94  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
95 
96 static ACPI_STATUS
99  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
100 
101 static ACPI_STATUS
104  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
105 
106 static ACPI_STATUS
109  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
110 
111 static ACPI_STATUS
114  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
115 
116 static ACPI_STATUS
119  ACPI_OPERAND_OBJECT *ReturnObject,
120  UINT32 StartIndex,
121  UINT32 ExpectedCount,
122  UINT32 SortIndex,
123  UINT8 SortDirection,
124  char *SortKeyName);
125 
126 /* Values for SortDirection above */
127 
128 #define ACPI_SORT_ASCENDING 0
129 #define ACPI_SORT_DESCENDING 1
130 
131 static void
133  ACPI_OPERAND_OBJECT *ObjDesc,
134  UINT32 Index);
135 
136 static void
138  ACPI_OPERAND_OBJECT **Elements,
139  UINT32 Count,
140  UINT32 Index,
141  UINT8 SortDirection);
142 
143 
144 /*
145  * This table contains the names of the predefined methods for which we can
146  * perform more complex repairs.
147  *
148  * As necessary:
149  *
150  * _ALR: Sort the list ascending by AmbientIlluminance
151  * _CID: Strings: uppercase all, remove any leading asterisk
152  * _CST: Sort the list ascending by C state type
153  * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
154  * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
155  * _HID: Strings: uppercase all, remove any leading asterisk
156  * _PRT: Fix reversed SourceName and SourceIndex
157  * _PSS: Sort the list descending by Power
158  * _TSS: Sort the list descending by Power
159  *
160  * Names that must be packages, but cannot be sorted:
161  *
162  * _BCL: Values are tied to the Package index where they appear, and cannot
163  * be moved or sorted. These index values are used for _BQC and _BCM.
164  * However, we can fix the case where a buffer is returned, by converting
165  * it to a Package of integers.
166  */
168 {
169  {"_ALR", AcpiNsRepair_ALR},
170  {"_CID", AcpiNsRepair_CID},
171  {"_CST", AcpiNsRepair_CST},
172  {"_FDE", AcpiNsRepair_FDE},
173  {"_GTM", AcpiNsRepair_FDE}, /* _GTM has same repair as _FDE */
174  {"_HID", AcpiNsRepair_HID},
175  {"_PRT", AcpiNsRepair_PRT},
176  {"_PSS", AcpiNsRepair_PSS},
177  {"_TSS", AcpiNsRepair_TSS},
178  {{0,0,0,0}, NULL} /* Table terminator */
179 };
180 
181 
182 #define ACPI_FDE_FIELD_COUNT 5
183 #define ACPI_FDE_BYTE_BUFFER_SIZE 5
184 #define ACPI_FDE_DWORD_BUFFER_SIZE (ACPI_FDE_FIELD_COUNT * (UINT32) sizeof (UINT32))
185 
186 
187 /******************************************************************************
188  *
189  * FUNCTION: AcpiNsComplexRepairs
190  *
191  * PARAMETERS: Info - Method execution information block
192  * Node - Namespace node for the method/object
193  * ValidateStatus - Original status of earlier validation
194  * ReturnObjectPtr - Pointer to the object returned from the
195  * evaluation of a method or object
196  *
197  * RETURN: Status. AE_OK if repair was successful. If name is not
198  * matched, ValidateStatus is returned.
199  *
200  * DESCRIPTION: Attempt to repair/convert a return object of a type that was
201  * not expected.
202  *
203  *****************************************************************************/
204 
209  ACPI_STATUS ValidateStatus,
210  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
211 {
212  const ACPI_REPAIR_INFO *Predefined;
214 
215 
216  ACPI_FUNCTION_TRACE (NsComplexRepairs);
217 
218  /* Check if this name is in the list of repairable names */
219 
220  Predefined = AcpiNsMatchComplexRepair (Node);
221  if (!Predefined)
222  {
223  return_ACPI_STATUS (ValidateStatus);
224  }
225 
226  Status = Predefined->RepairFunction (Info, ReturnObjectPtr);
228 }
229 
230 
231 /******************************************************************************
232  *
233  * FUNCTION: AcpiNsMatchComplexRepair
234  *
235  * PARAMETERS: Node - Namespace node for the method/object
236  *
237  * RETURN: Pointer to entry in repair table. NULL indicates not found.
238  *
239  * DESCRIPTION: Check an object name against the repairable object list.
240  *
241  *****************************************************************************/
242 
243 static const ACPI_REPAIR_INFO *
246 {
247  const ACPI_REPAIR_INFO *ThisName;
248 
249 
250  /* Search info table for a repairable predefined method/object name */
251 
252  ThisName = AcpiNsRepairableNames;
253  while (ThisName->RepairFunction)
254  {
255  if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, ThisName->Name))
256  {
257  return (ThisName);
258  }
259 
260  ThisName++;
261  }
262 
263  return (NULL); /* Not found */
264 }
265 
266 
267 /******************************************************************************
268  *
269  * FUNCTION: AcpiNsRepair_ALR
270  *
271  * PARAMETERS: Info - Method execution information block
272  * ReturnObjectPtr - Pointer to the object returned from the
273  * evaluation of a method or object
274  *
275  * RETURN: Status. AE_OK if object is OK or was repaired successfully
276  *
277  * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list
278  * ascending by the ambient illuminance values.
279  *
280  *****************************************************************************/
281 
282 static ACPI_STATUS
285  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
286 {
287  ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
289 
290 
291  Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 2, 1,
292  ACPI_SORT_ASCENDING, "AmbientIlluminance");
293 
294  return (Status);
295 }
296 
297 
298 /******************************************************************************
299  *
300  * FUNCTION: AcpiNsRepair_FDE
301  *
302  * PARAMETERS: Info - Method execution information block
303  * ReturnObjectPtr - Pointer to the object returned from the
304  * evaluation of a method or object
305  *
306  * RETURN: Status. AE_OK if object is OK or was repaired successfully
307  *
308  * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return
309  * value is a Buffer of 5 DWORDs. This function repairs a common
310  * problem where the return value is a Buffer of BYTEs, not
311  * DWORDs.
312  *
313  *****************************************************************************/
314 
315 static ACPI_STATUS
318  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
319 {
320  ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
321  ACPI_OPERAND_OBJECT *BufferObject;
322  UINT8 *ByteBuffer;
323  UINT32 *DwordBuffer;
324  UINT32 i;
325 
326 
327  ACPI_FUNCTION_NAME (NsRepair_FDE);
328 
329 
330  switch (ReturnObject->Common.Type)
331  {
332  case ACPI_TYPE_BUFFER:
333 
334  /* This is the expected type. Length should be (at least) 5 DWORDs */
335 
336  if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE)
337  {
338  return (AE_OK);
339  }
340 
341  /* We can only repair if we have exactly 5 BYTEs */
342 
343  if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE)
344  {
346  Info->FullPathname, Info->NodeFlags,
347  "Incorrect return buffer length %u, expected %u",
348  ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE));
349 
350  return (AE_AML_OPERAND_TYPE);
351  }
352 
353  /* Create the new (larger) buffer object */
354 
355  BufferObject = AcpiUtCreateBufferObject (
357  if (!BufferObject)
358  {
359  return (AE_NO_MEMORY);
360  }
361 
362  /* Expand each byte to a DWORD */
363 
364  ByteBuffer = ReturnObject->Buffer.Pointer;
365  DwordBuffer = ACPI_CAST_PTR (UINT32,
366  BufferObject->Buffer.Pointer);
367 
368  for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++)
369  {
370  *DwordBuffer = (UINT32) *ByteBuffer;
371  DwordBuffer++;
372  ByteBuffer++;
373  }
374 
376  "%s Expanded Byte Buffer to expected DWord Buffer\n",
377  Info->FullPathname));
378  break;
379 
380  default:
381 
382  return (AE_AML_OPERAND_TYPE);
383  }
384 
385  /* Delete the original return object, return the new buffer object */
386 
387  AcpiUtRemoveReference (ReturnObject);
388  *ReturnObjectPtr = BufferObject;
389 
390  Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
391  return (AE_OK);
392 }
393 
394 
395 /******************************************************************************
396  *
397  * FUNCTION: AcpiNsRepair_CID
398  *
399  * PARAMETERS: Info - Method execution information block
400  * ReturnObjectPtr - Pointer to the object returned from the
401  * evaluation of a method or object
402  *
403  * RETURN: Status. AE_OK if object is OK or was repaired successfully
404  *
405  * DESCRIPTION: Repair for the _CID object. If a string, ensure that all
406  * letters are uppercase and that there is no leading asterisk.
407  * If a Package, ensure same for all string elements.
408  *
409  *****************************************************************************/
410 
411 static ACPI_STATUS
414  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
415 {
417  ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
418  ACPI_OPERAND_OBJECT **ElementPtr;
419  ACPI_OPERAND_OBJECT *OriginalElement;
420  UINT16 OriginalRefCount;
421  UINT32 i;
422 
423  ACPI_FUNCTION_TRACE (NsRepair_CID);
424 
425  /* Check for _CID as a simple string */
426 
427  if (ReturnObject->Common.Type == ACPI_TYPE_STRING)
428  {
429  Status = AcpiNsRepair_HID (Info, ReturnObjectPtr);
431  }
432 
433  /* Exit if not a Package */
434 
435  if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
436  {
438  }
439 
440  /* Examine each element of the _CID package */
441 
442  ElementPtr = ReturnObject->Package.Elements;
443  for (i = 0; i < ReturnObject->Package.Count; i++)
444  {
445  OriginalElement = *ElementPtr;
446  OriginalRefCount = OriginalElement->Common.ReferenceCount;
447 
448  Status = AcpiNsRepair_HID (Info, ElementPtr);
449  if (ACPI_FAILURE (Status))
450  {
452  }
453 
454  if (OriginalElement != *ElementPtr)
455  {
456  /* Update reference count of new object */
457 
458  (*ElementPtr)->Common.ReferenceCount =
459  OriginalRefCount;
460 
461  /*
462  * The OriginalElement holds a reference from the package object
463  * that represents _HID. Since a new element was created by _HID,
464  * remove the reference from the _CID package.
465  */
466  AcpiUtRemoveReference (OriginalElement);
467  }
468 
469  ElementPtr++;
470  }
471 
473 }
474 
475 
476 /******************************************************************************
477  *
478  * FUNCTION: AcpiNsRepair_CST
479  *
480  * PARAMETERS: Info - Method execution information block
481  * ReturnObjectPtr - Pointer to the object returned from the
482  * evaluation of a method or object
483  *
484  * RETURN: Status. AE_OK if object is OK or was repaired successfully
485  *
486  * DESCRIPTION: Repair for the _CST object:
487  * 1. Sort the list ascending by C state type
488  * 2. Ensure type cannot be zero
489  * 3. A subpackage count of zero means _CST is meaningless
490  * 4. Count must match the number of C state subpackages
491  *
492  *****************************************************************************/
493 
494 static ACPI_STATUS
497  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
498 {
499  ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
500  ACPI_OPERAND_OBJECT **OuterElements;
501  UINT32 OuterElementCount;
502  ACPI_OPERAND_OBJECT *ObjDesc;
504  BOOLEAN Removing;
505  UINT32 i;
506 
507 
508  ACPI_FUNCTION_NAME (NsRepair_CST);
509 
510 
511  /*
512  * Check if the C-state type values are proportional.
513  */
514  OuterElementCount = ReturnObject->Package.Count - 1;
515  i = 0;
516  while (i < OuterElementCount)
517  {
518  OuterElements = &ReturnObject->Package.Elements[i + 1];
519  Removing = FALSE;
520 
521  if ((*OuterElements)->Package.Count == 0)
522  {
524  Info->FullPathname, Info->NodeFlags,
525  "SubPackage[%u] - removing entry due to zero count", i));
526  Removing = TRUE;
527  goto RemoveElement;
528  }
529 
530  ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */
531  if ((UINT32) ObjDesc->Integer.Value == 0)
532  {
534  Info->FullPathname, Info->NodeFlags,
535  "SubPackage[%u] - removing entry due to invalid Type(0)", i));
536  Removing = TRUE;
537  }
538 
539 RemoveElement:
540  if (Removing)
541  {
542  AcpiNsRemoveElement (ReturnObject, i + 1);
543  OuterElementCount--;
544  }
545  else
546  {
547  i++;
548  }
549  }
550 
551  /* Update top-level package count, Type "Integer" checked elsewhere */
552 
553  ObjDesc = ReturnObject->Package.Elements[0];
554  ObjDesc->Integer.Value = OuterElementCount;
555 
556  /*
557  * Entries (subpackages) in the _CST Package must be sorted by the
558  * C-state type, in ascending order.
559  */
560  Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1,
561  ACPI_SORT_ASCENDING, "C-State Type");
562  if (ACPI_FAILURE (Status))
563  {
564  return (Status);
565  }
566 
567  return (AE_OK);
568 }
569 
570 
571 /******************************************************************************
572  *
573  * FUNCTION: AcpiNsRepair_HID
574  *
575  * PARAMETERS: Info - Method execution information block
576  * ReturnObjectPtr - Pointer to the object returned from the
577  * evaluation of a method or object
578  *
579  * RETURN: Status. AE_OK if object is OK or was repaired successfully
580  *
581  * DESCRIPTION: Repair for the _HID object. If a string, ensure that all
582  * letters are uppercase and that there is no leading asterisk.
583  *
584  *****************************************************************************/
585 
586 static ACPI_STATUS
589  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
590 {
591  ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
592  ACPI_OPERAND_OBJECT *NewString;
593  char *Source;
594  char *Dest;
595 
596 
597  ACPI_FUNCTION_NAME (NsRepair_HID);
598 
599 
600  /* We only care about string _HID objects (not integers) */
601 
602  if (ReturnObject->Common.Type != ACPI_TYPE_STRING)
603  {
605  }
606 
607  if (ReturnObject->String.Length == 0)
608  {
610  Info->FullPathname, Info->NodeFlags,
611  "Invalid zero-length _HID or _CID string"));
612 
613  /* Return AE_OK anyway, let driver handle it */
614 
615  Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
617  }
618 
619  /* It is simplest to always create a new string object */
620 
621  NewString = AcpiUtCreateStringObject (ReturnObject->String.Length);
622  if (!NewString)
623  {
625  }
626 
627  /*
628  * Remove a leading asterisk if present. For some unknown reason, there
629  * are many machines in the field that contains IDs like this.
630  *
631  * Examples: "*PNP0C03", "*ACPI0003"
632  */
633  Source = ReturnObject->String.Pointer;
634  if (*Source == '*')
635  {
636  Source++;
637  NewString->String.Length--;
638 
640  "%s: Removed invalid leading asterisk\n", Info->FullPathname));
641  }
642 
643  /*
644  * Copy and uppercase the string. From the ACPI 5.0 specification:
645  *
646  * A valid PNP ID must be of the form "AAA####" where A is an uppercase
647  * letter and # is a hex digit. A valid ACPI ID must be of the form
648  * "NNNN####" where N is an uppercase letter or decimal digit, and
649  * # is a hex digit.
650  */
651  for (Dest = NewString->String.Pointer; *Source; Dest++, Source++)
652  {
653  *Dest = (char) toupper ((int) *Source);
654  }
655 
656  AcpiUtRemoveReference (ReturnObject);
657  *ReturnObjectPtr = NewString;
659 }
660 
661 
662 /******************************************************************************
663  *
664  * FUNCTION: AcpiNsRepair_PRT
665  *
666  * PARAMETERS: Info - Method execution information block
667  * ReturnObjectPtr - Pointer to the object returned from the
668  * evaluation of a method or object
669  *
670  * RETURN: Status. AE_OK if object is OK or was repaired successfully
671  *
672  * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed
673  * SourceName and SourceIndex field, a common BIOS bug.
674  *
675  *****************************************************************************/
676 
677 static ACPI_STATUS
680  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
681 {
682  ACPI_OPERAND_OBJECT *PackageObject = *ReturnObjectPtr;
683  ACPI_OPERAND_OBJECT **TopObjectList;
684  ACPI_OPERAND_OBJECT **SubObjectList;
685  ACPI_OPERAND_OBJECT *ObjDesc;
686  ACPI_OPERAND_OBJECT *SubPackage;
687  UINT32 ElementCount;
688  UINT32 Index;
689 
690 
691  /* Each element in the _PRT package is a subpackage */
692 
693  TopObjectList = PackageObject->Package.Elements;
694  ElementCount = PackageObject->Package.Count;
695 
696  /* Examine each subpackage */
697 
698  for (Index = 0; Index < ElementCount; Index++, TopObjectList++)
699  {
700  SubPackage = *TopObjectList;
701  SubObjectList = SubPackage->Package.Elements;
702 
703  /* Check for minimum required element count */
704 
705  if (SubPackage->Package.Count < 4)
706  {
707  continue;
708  }
709 
710  /*
711  * If the BIOS has erroneously reversed the _PRT SourceName (index 2)
712  * and the SourceIndex (index 3), fix it. _PRT is important enough to
713  * workaround this BIOS error. This also provides compatibility with
714  * other ACPI implementations.
715  */
716  ObjDesc = SubObjectList[3];
717  if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER))
718  {
719  SubObjectList[3] = SubObjectList[2];
720  SubObjectList[2] = ObjDesc;
721  Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
722 
724  Info->FullPathname, Info->NodeFlags,
725  "PRT[%X]: Fixed reversed SourceName and SourceIndex",
726  Index));
727  }
728  }
729 
730  return (AE_OK);
731 }
732 
733 
734 /******************************************************************************
735  *
736  * FUNCTION: AcpiNsRepair_PSS
737  *
738  * PARAMETERS: Info - Method execution information block
739  * ReturnObjectPtr - Pointer to the object returned from the
740  * evaluation of a method or object
741  *
742  * RETURN: Status. AE_OK if object is OK or was repaired successfully
743  *
744  * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list
745  * by the CPU frequencies. Check that the power dissipation values
746  * are all proportional to CPU frequency (i.e., sorting by
747  * frequency should be the same as sorting by power.)
748  *
749  *****************************************************************************/
750 
751 static ACPI_STATUS
754  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
755 {
756  ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
757  ACPI_OPERAND_OBJECT **OuterElements;
758  UINT32 OuterElementCount;
759  ACPI_OPERAND_OBJECT **Elements;
760  ACPI_OPERAND_OBJECT *ObjDesc;
761  UINT32 PreviousValue;
763  UINT32 i;
764 
765 
766  /*
767  * Entries (subpackages) in the _PSS Package must be sorted by power
768  * dissipation, in descending order. If it appears that the list is
769  * incorrectly sorted, sort it. We sort by CpuFrequency, since this
770  * should be proportional to the power.
771  */
772  Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 6, 0,
773  ACPI_SORT_DESCENDING, "CpuFrequency");
774  if (ACPI_FAILURE (Status))
775  {
776  return (Status);
777  }
778 
779  /*
780  * We now know the list is correctly sorted by CPU frequency. Check if
781  * the power dissipation values are proportional.
782  */
783  PreviousValue = ACPI_UINT32_MAX;
784  OuterElements = ReturnObject->Package.Elements;
785  OuterElementCount = ReturnObject->Package.Count;
786 
787  for (i = 0; i < OuterElementCount; i++)
788  {
789  Elements = (*OuterElements)->Package.Elements;
790  ObjDesc = Elements[1]; /* Index1 = PowerDissipation */
791 
792  if ((UINT32) ObjDesc->Integer.Value > PreviousValue)
793  {
795  Info->FullPathname, Info->NodeFlags,
796  "SubPackage[%u,%u] - suspicious power dissipation values",
797  i-1, i));
798  }
799 
800  PreviousValue = (UINT32) ObjDesc->Integer.Value;
801  OuterElements++;
802  }
803 
804  return (AE_OK);
805 }
806 
807 
808 /******************************************************************************
809  *
810  * FUNCTION: AcpiNsRepair_TSS
811  *
812  * PARAMETERS: Info - Method execution information block
813  * ReturnObjectPtr - Pointer to the object returned from the
814  * evaluation of a method or object
815  *
816  * RETURN: Status. AE_OK if object is OK or was repaired successfully
817  *
818  * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
819  * descending by the power dissipation values.
820  *
821  *****************************************************************************/
822 
823 static ACPI_STATUS
826  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
827 {
828  ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
831 
832 
833  /*
834  * We can only sort the _TSS return package if there is no _PSS in the
835  * same scope. This is because if _PSS is present, the ACPI specification
836  * dictates that the _TSS Power Dissipation field is to be ignored, and
837  * therefore some BIOSs leave garbage values in the _TSS Power field(s).
838  * In this case, it is best to just return the _TSS package as-is.
839  * (May, 2011)
840  */
841  Status = AcpiNsGetNode (Info->Node, "^_PSS",
843  if (ACPI_SUCCESS (Status))
844  {
845  return (AE_OK);
846  }
847 
848  Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1,
849  ACPI_SORT_DESCENDING, "PowerDissipation");
850 
851  return (Status);
852 }
853 
854 
855 /******************************************************************************
856  *
857  * FUNCTION: AcpiNsCheckSortedList
858  *
859  * PARAMETERS: Info - Method execution information block
860  * ReturnObject - Pointer to the top-level returned object
861  * StartIndex - Index of the first subpackage
862  * ExpectedCount - Minimum length of each subpackage
863  * SortIndex - Subpackage entry to sort on
864  * SortDirection - Ascending or descending
865  * SortKeyName - Name of the SortIndex field
866  *
867  * RETURN: Status. AE_OK if the list is valid and is sorted correctly or
868  * has been repaired by sorting the list.
869  *
870  * DESCRIPTION: Check if the package list is valid and sorted correctly by the
871  * SortIndex. If not, then sort the list.
872  *
873  *****************************************************************************/
874 
875 static ACPI_STATUS
878  ACPI_OPERAND_OBJECT *ReturnObject,
879  UINT32 StartIndex,
880  UINT32 ExpectedCount,
881  UINT32 SortIndex,
882  UINT8 SortDirection,
883  char *SortKeyName)
884 {
885  UINT32 OuterElementCount;
886  ACPI_OPERAND_OBJECT **OuterElements;
887  ACPI_OPERAND_OBJECT **Elements;
888  ACPI_OPERAND_OBJECT *ObjDesc;
889  UINT32 i;
890  UINT32 PreviousValue;
891 
892 
893  ACPI_FUNCTION_NAME (NsCheckSortedList);
894 
895 
896  /* The top-level object must be a package */
897 
898  if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
899  {
900  return (AE_AML_OPERAND_TYPE);
901  }
902 
903  /*
904  * NOTE: assumes list of subpackages contains no NULL elements.
905  * Any NULL elements should have been removed by earlier call
906  * to AcpiNsRemoveNullElements.
907  */
908  OuterElementCount = ReturnObject->Package.Count;
909  if (!OuterElementCount || StartIndex >= OuterElementCount)
910  {
911  return (AE_AML_PACKAGE_LIMIT);
912  }
913 
914  OuterElements = &ReturnObject->Package.Elements[StartIndex];
915  OuterElementCount -= StartIndex;
916 
917  PreviousValue = 0;
918  if (SortDirection == ACPI_SORT_DESCENDING)
919  {
920  PreviousValue = ACPI_UINT32_MAX;
921  }
922 
923  /* Examine each subpackage */
924 
925  for (i = 0; i < OuterElementCount; i++)
926  {
927  /* Each element of the top-level package must also be a package */
928 
929  if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE)
930  {
931  return (AE_AML_OPERAND_TYPE);
932  }
933 
934  /* Each subpackage must have the minimum length */
935 
936  if ((*OuterElements)->Package.Count < ExpectedCount)
937  {
938  return (AE_AML_PACKAGE_LIMIT);
939  }
940 
941  Elements = (*OuterElements)->Package.Elements;
942  ObjDesc = Elements[SortIndex];
943 
944  if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
945  {
946  return (AE_AML_OPERAND_TYPE);
947  }
948 
949  /*
950  * The list must be sorted in the specified order. If we detect a
951  * discrepancy, sort the entire list.
952  */
953  if (((SortDirection == ACPI_SORT_ASCENDING) &&
954  (ObjDesc->Integer.Value < PreviousValue)) ||
955  ((SortDirection == ACPI_SORT_DESCENDING) &&
956  (ObjDesc->Integer.Value > PreviousValue)))
957  {
958  AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex],
959  OuterElementCount, SortIndex, SortDirection);
960 
961  Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
962 
964  "%s: Repaired unsorted list - now sorted by %s\n",
965  Info->FullPathname, SortKeyName));
966  return (AE_OK);
967  }
968 
969  PreviousValue = (UINT32) ObjDesc->Integer.Value;
970  OuterElements++;
971  }
972 
973  return (AE_OK);
974 }
975 
976 
977 /******************************************************************************
978  *
979  * FUNCTION: AcpiNsSortList
980  *
981  * PARAMETERS: Elements - Package object element list
982  * Count - Element count for above
983  * Index - Sort by which package element
984  * SortDirection - Ascending or Descending sort
985  *
986  * RETURN: None
987  *
988  * DESCRIPTION: Sort the objects that are in a package element list.
989  *
990  * NOTE: Assumes that all NULL elements have been removed from the package,
991  * and that all elements have been verified to be of type Integer.
992  *
993  *****************************************************************************/
994 
995 static void
997  ACPI_OPERAND_OBJECT **Elements,
998  UINT32 Count,
999  UINT32 Index,
1000  UINT8 SortDirection)
1001 {
1002  ACPI_OPERAND_OBJECT *ObjDesc1;
1003  ACPI_OPERAND_OBJECT *ObjDesc2;
1004  ACPI_OPERAND_OBJECT *TempObj;
1005  UINT32 i;
1006  UINT32 j;
1007 
1008 
1009  /* Simple bubble sort */
1010 
1011  for (i = 1; i < Count; i++)
1012  {
1013  for (j = (Count - 1); j >= i; j--)
1014  {
1015  ObjDesc1 = Elements[j-1]->Package.Elements[Index];
1016  ObjDesc2 = Elements[j]->Package.Elements[Index];
1017 
1018  if (((SortDirection == ACPI_SORT_ASCENDING) &&
1019  (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) ||
1020 
1021  ((SortDirection == ACPI_SORT_DESCENDING) &&
1022  (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value)))
1023  {
1024  TempObj = Elements[j-1];
1025  Elements[j-1] = Elements[j];
1026  Elements[j] = TempObj;
1027  }
1028  }
1029  }
1030 }
1031 
1032 
1033 /******************************************************************************
1034  *
1035  * FUNCTION: AcpiNsRemoveElement
1036  *
1037  * PARAMETERS: ObjDesc - Package object element list
1038  * Index - Index of element to remove
1039  *
1040  * RETURN: None
1041  *
1042  * DESCRIPTION: Remove the requested element of a package and delete it.
1043  *
1044  *****************************************************************************/
1045 
1046 static void
1048  ACPI_OPERAND_OBJECT *ObjDesc,
1049  UINT32 Index)
1050 {
1052  ACPI_OPERAND_OBJECT **Dest;
1053  UINT32 Count;
1054  UINT32 NewCount;
1055  UINT32 i;
1056 
1057 
1058  ACPI_FUNCTION_NAME (NsRemoveElement);
1059 
1060 
1061  Count = ObjDesc->Package.Count;
1062  NewCount = Count - 1;
1063 
1064  Source = ObjDesc->Package.Elements;
1065  Dest = Source;
1066 
1067  /* Examine all elements of the package object, remove matched index */
1068 
1069  for (i = 0; i < Count; i++)
1070  {
1071  if (i == Index)
1072  {
1073  AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */
1075  }
1076  else
1077  {
1078  *Dest = *Source;
1079  Dest++;
1080  }
1081 
1082  Source++;
1083  }
1084 
1085  /* NULL terminate list and update the package count */
1086 
1087  *Dest = NULL;
1088  ObjDesc->Package.Count = NewCount;
1089 }
static const ACPI_REPAIR_INFO AcpiNsRepairableNames[]
Definition: nsrepair2.c:167
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
char Name[ACPI_NAMESEG_SIZE]
Definition: nsrepair2.c:64
static ACPI_STATUS AcpiNsRepair_FDE(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:316
#define AE_NO_MEMORY
Definition: acexcep.h:112
ACPI_OBJECT_PACKAGE Package
Definition: acobject.h:522
#define TRUE
Definition: types.h:120
#define ACPI_TYPE_BUFFER
Definition: actypes.h:682
#define ACPI_TYPE_INTEGER
Definition: actypes.h:680
ACPI_OPERAND_OBJECT * AcpiUtCreateBufferObject(ACPI_SIZE BufferSize)
Definition: utobject.c:258
#define ACPI_SORT_ASCENDING
Definition: nsrepair2.c:128
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_DB_REPAIR
Definition: acoutput.h:154
static ACPI_STATUS AcpiNsRepair_CID(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:412
#define AE_AML_OPERAND_TYPE
Definition: acexcep.h:182
struct acpi_repair_info ACPI_REPAIR_INFO
#define ACPI_FDE_DWORD_BUFFER_SIZE
Definition: nsrepair2.c:184
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
#define ACPI_TYPE_PACKAGE
Definition: actypes.h:683
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
ACPI_STATUS AcpiNsGetNode(ACPI_NAMESPACE_NODE *PrefixNode, const char *ExternalPathname, UINT32 Flags, ACPI_NAMESPACE_NODE **OutNode)
Definition: nsutils.c:863
#define FALSE
Definition: types.h:117
unsigned int UINT32
union node Node
Definition: types.h:1255
#define ACPI_OBJECT_REPAIRED
Definition: acstruct.h:235
static ACPI_STATUS AcpiNsRepair_TSS(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:824
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
ACPI_STATUS(* ACPI_REPAIR_FUNCTION)(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:58
static const ACPI_REPAIR_INFO * AcpiNsMatchComplexRepair(ACPI_NAMESPACE_NODE *Node)
Definition: nsrepair2.c:244
unsigned char BOOLEAN
#define ACPI_WARN_PREDEFINED(plist)
Definition: acmacros.h:464
#define AE_INFO
Definition: acoutput.h:230
unsigned char
Definition: typeof.h:29
static ACPI_STATUS AcpiNsRepair_ALR(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:283
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
ACPI_OPERAND_OBJECT * AcpiUtCreateStringObject(ACPI_SIZE StringSize)
Definition: utobject.c:320
Status
Definition: gdiplustypes.h:24
int Count
Definition: noreturn.cpp:7
int toupper(int c)
Definition: utclib.c:881
ACPI_OBJECT_BUFFER Buffer
Definition: acobject.h:521
ACPI_STATUS AcpiNsComplexRepairs(ACPI_EVALUATE_INFO *Info, ACPI_NAMESPACE_NODE *Node, ACPI_STATUS ValidateStatus, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:206
static ACPI_STATUS AcpiNsCheckSortedList(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT *ReturnObject, UINT32 StartIndex, UINT32 ExpectedCount, UINT32 SortIndex, UINT8 SortDirection, char *SortKeyName)
Definition: nsrepair2.c:876
_In_ WDFCOLLECTION _In_ ULONG Index
#define ACPI_UINT32_MAX
Definition: actypes.h:66
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
static ACPI_STATUS AcpiNsRepair_PRT(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:678
#define ACPI_COMPARE_NAMESEG(a, b)
Definition: actypes.h:561
#define ACPI_FDE_FIELD_COUNT
Definition: nsrepair2.c:182
static ACPI_STATUS AcpiNsRepair_CST(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:495
ACPI_OBJECT_INTEGER Integer
Definition: acobject.h:519
ACPI_OBJECT_STRING String
Definition: acobject.h:520
#define ACPI_SORT_DESCENDING
Definition: nsrepair2.c:129
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_NS_NO_UPSEARCH
Definition: acnamesp.h:62
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
ACPI_OBJECT_COMMON Common
Definition: acobject.h:518
void AcpiUtRemoveReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:789
static ACPI_STATUS AcpiNsRepair_PSS(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:752
static void AcpiNsSortList(ACPI_OPERAND_OBJECT **Elements, UINT32 Count, UINT32 Index, UINT8 SortDirection)
Definition: nsrepair2.c:996
unsigned short UINT16
#define NULL
Definition: types.h:112
static void AcpiNsRemoveElement(ACPI_OPERAND_OBJECT *ObjDesc, UINT32 Index)
Definition: nsrepair2.c:1047
ACPI_REPAIR_FUNCTION RepairFunction
Definition: nsrepair2.c:65
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
#define ACPI_FUNCTION_NAME(a)
Definition: acoutput.h:479
#define ACPI_TYPE_STRING
Definition: actypes.h:681
#define AE_AML_PACKAGE_LIMIT
Definition: acexcep.h:190
#define ACPI_NAMESEG_SIZE
Definition: actypes.h:415
#define ACPI_CAST_PTR(t, p)
Definition: actypes.h:544
unsigned char UINT8
#define ACPI_FDE_BYTE_BUFFER_SIZE
Definition: nsrepair2.c:183
#define AE_OK
Definition: acexcep.h:97
static ACPI_STATUS AcpiNsRepair_HID(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:587
union acpi_operand_object ** Elements
Definition: acobject.h:161
Definition: dlist.c:348