nsrepair2.c revision 202771
1199323Sjkim/****************************************************************************** 2199323Sjkim * 3199323Sjkim * Module Name: nsrepair2 - Repair for objects returned by specific 4199323Sjkim * predefined methods 5199323Sjkim * 6199323Sjkim *****************************************************************************/ 7199323Sjkim 8199323Sjkim/****************************************************************************** 9199323Sjkim * 10199323Sjkim * 1. Copyright Notice 11199323Sjkim * 12202771Sjkim * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. 13199323Sjkim * All rights reserved. 14199323Sjkim * 15199323Sjkim * 2. License 16199323Sjkim * 17199323Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property 18199323Sjkim * rights. You may have additional license terms from the party that provided 19199323Sjkim * you this software, covering your right to use that party's intellectual 20199323Sjkim * property rights. 21199323Sjkim * 22199323Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23199323Sjkim * copy of the source code appearing in this file ("Covered Code") an 24199323Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25199323Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy, 26199323Sjkim * make derivatives, distribute, use and display any portion of the Covered 27199323Sjkim * Code in any form, with the right to sublicense such rights; and 28199323Sjkim * 29199323Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30199323Sjkim * license (with the right to sublicense), under only those claims of Intel 31199323Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell, 32199323Sjkim * offer to sell, and import the Covered Code and derivative works thereof 33199323Sjkim * solely to the minimum extent necessary to exercise the above copyright 34199323Sjkim * license, and in no event shall the patent license extend to any additions 35199323Sjkim * to or modifications of the Original Intel Code. No other license or right 36199323Sjkim * is granted directly or by implication, estoppel or otherwise; 37199323Sjkim * 38199323Sjkim * The above copyright and patent license is granted only if the following 39199323Sjkim * conditions are met: 40199323Sjkim * 41199323Sjkim * 3. Conditions 42199323Sjkim * 43199323Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44199323Sjkim * Redistribution of source code of any substantial portion of the Covered 45199323Sjkim * Code or modification with rights to further distribute source must include 46199323Sjkim * the above Copyright Notice, the above License, this list of Conditions, 47199323Sjkim * and the following Disclaimer and Export Compliance provision. In addition, 48199323Sjkim * Licensee must cause all Covered Code to which Licensee contributes to 49199323Sjkim * contain a file documenting the changes Licensee made to create that Covered 50199323Sjkim * Code and the date of any change. Licensee must include in that file the 51199323Sjkim * documentation of any changes made by any predecessor Licensee. Licensee 52199323Sjkim * must include a prominent statement that the modification is derived, 53199323Sjkim * directly or indirectly, from Original Intel Code. 54199323Sjkim * 55199323Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56199323Sjkim * Redistribution of source code of any substantial portion of the Covered 57199323Sjkim * Code or modification without rights to further distribute source must 58199323Sjkim * include the following Disclaimer and Export Compliance provision in the 59199323Sjkim * documentation and/or other materials provided with distribution. In 60199323Sjkim * addition, Licensee may not authorize further sublicense of source of any 61199323Sjkim * portion of the Covered Code, and must include terms to the effect that the 62199323Sjkim * license from Licensee to its licensee is limited to the intellectual 63199323Sjkim * property embodied in the software Licensee provides to its licensee, and 64199323Sjkim * not to intellectual property embodied in modifications its licensee may 65199323Sjkim * make. 66199323Sjkim * 67199323Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any 68199323Sjkim * substantial portion of the Covered Code or modification must reproduce the 69199323Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance 70199323Sjkim * provision in the documentation and/or other materials provided with the 71199323Sjkim * distribution. 72199323Sjkim * 73199323Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original 74199323Sjkim * Intel Code. 75199323Sjkim * 76199323Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77199323Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or 78199323Sjkim * other dealings in products derived from or relating to the Covered Code 79199323Sjkim * without prior written authorization from Intel. 80199323Sjkim * 81199323Sjkim * 4. Disclaimer and Export Compliance 82199323Sjkim * 83199323Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84199323Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85199323Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86199323Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87199323Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88199323Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89199323Sjkim * PARTICULAR PURPOSE. 90199323Sjkim * 91199323Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92199323Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93199323Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94199323Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95199323Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96199323Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97199323Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98199323Sjkim * LIMITED REMEDY. 99199323Sjkim * 100199323Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this 101199323Sjkim * software or system incorporating such software without first obtaining any 102199323Sjkim * required license or other approval from the U. S. Department of Commerce or 103199323Sjkim * any other agency or department of the United States Government. In the 104199323Sjkim * event Licensee exports any such software from the United States or 105199323Sjkim * re-exports any such software from a foreign destination, Licensee shall 106199323Sjkim * ensure that the distribution and export/re-export of the software is in 107199323Sjkim * compliance with all laws, regulations, orders, or other restrictions of the 108199323Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109199323Sjkim * any of its subsidiaries will export/re-export any technical data, process, 110199323Sjkim * software, or service, directly or indirectly, to any country for which the 111199323Sjkim * United States government or any agency thereof requires an export license, 112199323Sjkim * other governmental approval, or letter of assurance, without first obtaining 113199323Sjkim * such license, approval or letter. 114199323Sjkim * 115199323Sjkim *****************************************************************************/ 116199323Sjkim 117199323Sjkim#define __NSREPAIR2_C__ 118199323Sjkim 119199337Sjkim#include <contrib/dev/acpica/include/acpi.h> 120199337Sjkim#include <contrib/dev/acpica/include/accommon.h> 121199337Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 122199323Sjkim 123199323Sjkim#define _COMPONENT ACPI_NAMESPACE 124199323Sjkim ACPI_MODULE_NAME ("nsrepair2") 125199323Sjkim 126199323Sjkim 127199323Sjkim/* 128199323Sjkim * Information structure and handler for ACPI predefined names that can 129199323Sjkim * be repaired on a per-name basis. 130199323Sjkim */ 131199323Sjkimtypedef 132199323SjkimACPI_STATUS (*ACPI_REPAIR_FUNCTION) ( 133199323Sjkim ACPI_PREDEFINED_DATA *Data, 134199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 135199323Sjkim 136199323Sjkimtypedef struct acpi_repair_info 137199323Sjkim{ 138199323Sjkim char Name[ACPI_NAME_SIZE]; 139199323Sjkim ACPI_REPAIR_FUNCTION RepairFunction; 140199323Sjkim 141199323Sjkim} ACPI_REPAIR_INFO; 142199323Sjkim 143199323Sjkim 144199323Sjkim/* Local prototypes */ 145199323Sjkim 146199323Sjkimstatic const ACPI_REPAIR_INFO * 147199323SjkimAcpiNsMatchRepairableName ( 148199323Sjkim ACPI_NAMESPACE_NODE *Node); 149199323Sjkim 150199323Sjkimstatic ACPI_STATUS 151199323SjkimAcpiNsRepair_ALR ( 152199323Sjkim ACPI_PREDEFINED_DATA *Data, 153199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 154199323Sjkim 155199323Sjkimstatic ACPI_STATUS 156200553SjkimAcpiNsRepair_FDE ( 157200553Sjkim ACPI_PREDEFINED_DATA *Data, 158200553Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 159200553Sjkim 160200553Sjkimstatic ACPI_STATUS 161199323SjkimAcpiNsRepair_PSS ( 162199323Sjkim ACPI_PREDEFINED_DATA *Data, 163199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 164199323Sjkim 165199323Sjkimstatic ACPI_STATUS 166199323SjkimAcpiNsRepair_TSS ( 167199323Sjkim ACPI_PREDEFINED_DATA *Data, 168199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 169199323Sjkim 170199323Sjkimstatic ACPI_STATUS 171199323SjkimAcpiNsCheckSortedList ( 172199323Sjkim ACPI_PREDEFINED_DATA *Data, 173199323Sjkim ACPI_OPERAND_OBJECT *ReturnObject, 174199323Sjkim UINT32 ExpectedCount, 175199323Sjkim UINT32 SortIndex, 176199323Sjkim UINT8 SortDirection, 177199323Sjkim char *SortKeyName); 178199323Sjkim 179202771Sjkimstatic void 180199323SjkimAcpiNsSortList ( 181199323Sjkim ACPI_OPERAND_OBJECT **Elements, 182199323Sjkim UINT32 Count, 183199323Sjkim UINT32 Index, 184199323Sjkim UINT8 SortDirection); 185199323Sjkim 186199323Sjkim/* Values for SortDirection above */ 187199323Sjkim 188199323Sjkim#define ACPI_SORT_ASCENDING 0 189199323Sjkim#define ACPI_SORT_DESCENDING 1 190199323Sjkim 191199323Sjkim 192199323Sjkim/* 193199323Sjkim * This table contains the names of the predefined methods for which we can 194199323Sjkim * perform more complex repairs. 195199323Sjkim * 196200553Sjkim * As necessary: 197200553Sjkim * 198200553Sjkim * _ALR: Sort the list ascending by AmbientIlluminance 199200553Sjkim * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs 200200553Sjkim * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs 201200553Sjkim * _PSS: Sort the list descending by Power 202200553Sjkim * _TSS: Sort the list descending by Power 203199323Sjkim */ 204199323Sjkimstatic const ACPI_REPAIR_INFO AcpiNsRepairableNames[] = 205199323Sjkim{ 206199323Sjkim {"_ALR", AcpiNsRepair_ALR}, 207200553Sjkim {"_FDE", AcpiNsRepair_FDE}, 208200553Sjkim {"_GTM", AcpiNsRepair_FDE}, /* _GTM has same repair as _FDE */ 209199323Sjkim {"_PSS", AcpiNsRepair_PSS}, 210199323Sjkim {"_TSS", AcpiNsRepair_TSS}, 211200553Sjkim {{0,0,0,0}, NULL} /* Table terminator */ 212199323Sjkim}; 213199323Sjkim 214199323Sjkim 215200553Sjkim#define ACPI_FDE_FIELD_COUNT 5 216200553Sjkim#define ACPI_FDE_BYTE_BUFFER_SIZE 5 217200553Sjkim#define ACPI_FDE_DWORD_BUFFER_SIZE (ACPI_FDE_FIELD_COUNT * sizeof (UINT32)) 218200553Sjkim 219200553Sjkim 220199323Sjkim/****************************************************************************** 221199323Sjkim * 222199323Sjkim * FUNCTION: AcpiNsComplexRepairs 223199323Sjkim * 224199323Sjkim * PARAMETERS: Data - Pointer to validation data structure 225199323Sjkim * Node - Namespace node for the method/object 226199323Sjkim * ValidateStatus - Original status of earlier validation 227199323Sjkim * ReturnObjectPtr - Pointer to the object returned from the 228199323Sjkim * evaluation of a method or object 229199323Sjkim * 230200553Sjkim * RETURN: Status. AE_OK if repair was successful. If name is not 231199323Sjkim * matched, ValidateStatus is returned. 232199323Sjkim * 233199323Sjkim * DESCRIPTION: Attempt to repair/convert a return object of a type that was 234199323Sjkim * not expected. 235199323Sjkim * 236199323Sjkim *****************************************************************************/ 237199323Sjkim 238199323SjkimACPI_STATUS 239199323SjkimAcpiNsComplexRepairs ( 240199323Sjkim ACPI_PREDEFINED_DATA *Data, 241199323Sjkim ACPI_NAMESPACE_NODE *Node, 242199323Sjkim ACPI_STATUS ValidateStatus, 243199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 244199323Sjkim{ 245199323Sjkim const ACPI_REPAIR_INFO *Predefined; 246199323Sjkim ACPI_STATUS Status; 247199323Sjkim 248199323Sjkim 249199323Sjkim /* Check if this name is in the list of repairable names */ 250199323Sjkim 251199323Sjkim Predefined = AcpiNsMatchRepairableName (Node); 252199323Sjkim if (!Predefined) 253199323Sjkim { 254199323Sjkim return (ValidateStatus); 255199323Sjkim } 256199323Sjkim 257199323Sjkim Status = Predefined->RepairFunction (Data, ReturnObjectPtr); 258199323Sjkim return (Status); 259199323Sjkim} 260199323Sjkim 261199323Sjkim 262199323Sjkim/****************************************************************************** 263199323Sjkim * 264199323Sjkim * FUNCTION: AcpiNsMatchRepairableName 265199323Sjkim * 266199323Sjkim * PARAMETERS: Node - Namespace node for the method/object 267199323Sjkim * 268199323Sjkim * RETURN: Pointer to entry in repair table. NULL indicates not found. 269199323Sjkim * 270199323Sjkim * DESCRIPTION: Check an object name against the repairable object list. 271199323Sjkim * 272199323Sjkim *****************************************************************************/ 273199323Sjkim 274199323Sjkimstatic const ACPI_REPAIR_INFO * 275199323SjkimAcpiNsMatchRepairableName ( 276199323Sjkim ACPI_NAMESPACE_NODE *Node) 277199323Sjkim{ 278199323Sjkim const ACPI_REPAIR_INFO *ThisName; 279199323Sjkim 280199323Sjkim 281199323Sjkim /* Search info table for a repairable predefined method/object name */ 282199323Sjkim 283199323Sjkim ThisName = AcpiNsRepairableNames; 284199323Sjkim while (ThisName->RepairFunction) 285199323Sjkim { 286199323Sjkim if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name)) 287199323Sjkim { 288199323Sjkim return (ThisName); 289199323Sjkim } 290199323Sjkim ThisName++; 291199323Sjkim } 292199323Sjkim 293199323Sjkim return (NULL); /* Not found */ 294199323Sjkim} 295199323Sjkim 296199323Sjkim 297199323Sjkim/****************************************************************************** 298199323Sjkim * 299199323Sjkim * FUNCTION: AcpiNsRepair_ALR 300199323Sjkim * 301199323Sjkim * PARAMETERS: Data - Pointer to validation data structure 302199323Sjkim * ReturnObjectPtr - Pointer to the object returned from the 303199323Sjkim * evaluation of a method or object 304199323Sjkim * 305199323Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 306199323Sjkim * 307199323Sjkim * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list 308199323Sjkim * ascending by the ambient illuminance values. 309199323Sjkim * 310199323Sjkim *****************************************************************************/ 311199323Sjkim 312199323Sjkimstatic ACPI_STATUS 313199323SjkimAcpiNsRepair_ALR ( 314199323Sjkim ACPI_PREDEFINED_DATA *Data, 315199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 316199323Sjkim{ 317199323Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 318199323Sjkim ACPI_STATUS Status; 319199323Sjkim 320199323Sjkim 321199323Sjkim Status = AcpiNsCheckSortedList (Data, ReturnObject, 2, 1, 322199323Sjkim ACPI_SORT_ASCENDING, "AmbientIlluminance"); 323199323Sjkim 324199323Sjkim return (Status); 325199323Sjkim} 326199323Sjkim 327199323Sjkim 328199323Sjkim/****************************************************************************** 329199323Sjkim * 330200553Sjkim * FUNCTION: AcpiNsRepair_FDE 331200553Sjkim * 332200553Sjkim * PARAMETERS: Data - Pointer to validation data structure 333200553Sjkim * ReturnObjectPtr - Pointer to the object returned from the 334200553Sjkim * evaluation of a method or object 335200553Sjkim * 336200553Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 337200553Sjkim * 338200553Sjkim * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return 339200553Sjkim * value is a Buffer of 5 DWORDs. This function repairs a common 340200553Sjkim * problem where the return value is a Buffer of BYTEs, not 341200553Sjkim * DWORDs. 342200553Sjkim * 343200553Sjkim *****************************************************************************/ 344200553Sjkim 345200553Sjkimstatic ACPI_STATUS 346200553SjkimAcpiNsRepair_FDE ( 347200553Sjkim ACPI_PREDEFINED_DATA *Data, 348200553Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 349200553Sjkim{ 350200553Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 351200553Sjkim ACPI_OPERAND_OBJECT *BufferObject; 352200553Sjkim UINT8 *ByteBuffer; 353200553Sjkim UINT32 *DwordBuffer; 354200553Sjkim UINT32 i; 355200553Sjkim 356200553Sjkim 357200553Sjkim ACPI_FUNCTION_NAME (NsRepair_FDE); 358200553Sjkim 359200553Sjkim 360200553Sjkim switch (ReturnObject->Common.Type) 361200553Sjkim { 362200553Sjkim case ACPI_TYPE_BUFFER: 363200553Sjkim 364200553Sjkim /* This is the expected type. Length should be (at least) 5 DWORDs */ 365200553Sjkim 366200553Sjkim if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE) 367200553Sjkim { 368200553Sjkim return (AE_OK); 369200553Sjkim } 370200553Sjkim 371200553Sjkim /* We can only repair if we have exactly 5 BYTEs */ 372200553Sjkim 373200553Sjkim if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE) 374200553Sjkim { 375200553Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 376200553Sjkim "Incorrect return buffer length %u, expected %u", 377200553Sjkim ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE)); 378200553Sjkim 379200553Sjkim return (AE_AML_OPERAND_TYPE); 380200553Sjkim } 381200553Sjkim 382200553Sjkim /* Create the new (larger) buffer object */ 383200553Sjkim 384200553Sjkim BufferObject = AcpiUtCreateBufferObject (ACPI_FDE_DWORD_BUFFER_SIZE); 385200553Sjkim if (!BufferObject) 386200553Sjkim { 387200553Sjkim return (AE_NO_MEMORY); 388200553Sjkim } 389200553Sjkim 390200553Sjkim /* Expand each byte to a DWORD */ 391200553Sjkim 392200553Sjkim ByteBuffer = ReturnObject->Buffer.Pointer; 393200553Sjkim DwordBuffer = ACPI_CAST_PTR (UINT32, BufferObject->Buffer.Pointer); 394200553Sjkim 395200553Sjkim for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++) 396200553Sjkim { 397200553Sjkim *DwordBuffer = (UINT32) *ByteBuffer; 398200553Sjkim DwordBuffer++; 399200553Sjkim ByteBuffer++; 400200553Sjkim } 401200553Sjkim 402200553Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 403200553Sjkim "%s Expanded Byte Buffer to expected DWord Buffer\n", 404200553Sjkim Data->Pathname)); 405200553Sjkim break; 406200553Sjkim 407200553Sjkim default: 408200553Sjkim return (AE_AML_OPERAND_TYPE); 409200553Sjkim } 410200553Sjkim 411200553Sjkim /* Delete the original return object, return the new buffer object */ 412200553Sjkim 413200553Sjkim AcpiUtRemoveReference (ReturnObject); 414200553Sjkim *ReturnObjectPtr = BufferObject; 415200553Sjkim 416200553Sjkim Data->Flags |= ACPI_OBJECT_REPAIRED; 417200553Sjkim return (AE_OK); 418200553Sjkim} 419200553Sjkim 420200553Sjkim 421200553Sjkim/****************************************************************************** 422200553Sjkim * 423199323Sjkim * FUNCTION: AcpiNsRepair_TSS 424199323Sjkim * 425199323Sjkim * PARAMETERS: Data - Pointer to validation data structure 426199323Sjkim * ReturnObjectPtr - Pointer to the object returned from the 427199323Sjkim * evaluation of a method or object 428199323Sjkim * 429199323Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 430199323Sjkim * 431199323Sjkim * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list 432199323Sjkim * descending by the power dissipation values. 433199323Sjkim * 434199323Sjkim *****************************************************************************/ 435199323Sjkim 436199323Sjkimstatic ACPI_STATUS 437199323SjkimAcpiNsRepair_TSS ( 438199323Sjkim ACPI_PREDEFINED_DATA *Data, 439199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 440199323Sjkim{ 441199323Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 442199323Sjkim ACPI_STATUS Status; 443199323Sjkim 444199323Sjkim 445199323Sjkim Status = AcpiNsCheckSortedList (Data, ReturnObject, 5, 1, 446199323Sjkim ACPI_SORT_DESCENDING, "PowerDissipation"); 447199323Sjkim 448199323Sjkim return (Status); 449199323Sjkim} 450199323Sjkim 451199323Sjkim 452199323Sjkim/****************************************************************************** 453199323Sjkim * 454199323Sjkim * FUNCTION: AcpiNsRepair_PSS 455199323Sjkim * 456199323Sjkim * PARAMETERS: Data - Pointer to validation data structure 457199323Sjkim * ReturnObjectPtr - Pointer to the object returned from the 458199323Sjkim * evaluation of a method or object 459199323Sjkim * 460199323Sjkim * RETURN: Status. AE_OK if object is OK or was repaired successfully 461199323Sjkim * 462199323Sjkim * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list 463199323Sjkim * by the CPU frequencies. Check that the power dissipation values 464199323Sjkim * are all proportional to CPU frequency (i.e., sorting by 465199323Sjkim * frequency should be the same as sorting by power.) 466199323Sjkim * 467199323Sjkim *****************************************************************************/ 468199323Sjkim 469199323Sjkimstatic ACPI_STATUS 470199323SjkimAcpiNsRepair_PSS ( 471199323Sjkim ACPI_PREDEFINED_DATA *Data, 472199323Sjkim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 473199323Sjkim{ 474199323Sjkim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 475199323Sjkim ACPI_OPERAND_OBJECT **OuterElements; 476199323Sjkim UINT32 OuterElementCount; 477199323Sjkim ACPI_OPERAND_OBJECT **Elements; 478199323Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 479199323Sjkim UINT32 PreviousValue; 480199323Sjkim ACPI_STATUS Status; 481199323Sjkim UINT32 i; 482199323Sjkim 483199323Sjkim 484199323Sjkim /* 485199323Sjkim * Entries (sub-packages) in the _PSS Package must be sorted by power 486199323Sjkim * dissipation, in descending order. If it appears that the list is 487199323Sjkim * incorrectly sorted, sort it. We sort by CpuFrequency, since this 488199323Sjkim * should be proportional to the power. 489199323Sjkim */ 490199323Sjkim Status =AcpiNsCheckSortedList (Data, ReturnObject, 6, 0, 491199323Sjkim ACPI_SORT_DESCENDING, "CpuFrequency"); 492199323Sjkim if (ACPI_FAILURE (Status)) 493199323Sjkim { 494199323Sjkim return (Status); 495199323Sjkim } 496199323Sjkim 497199323Sjkim /* 498199323Sjkim * We now know the list is correctly sorted by CPU frequency. Check if 499199323Sjkim * the power dissipation values are proportional. 500199323Sjkim */ 501199323Sjkim PreviousValue = ACPI_UINT32_MAX; 502199323Sjkim OuterElements = ReturnObject->Package.Elements; 503199323Sjkim OuterElementCount = ReturnObject->Package.Count; 504199323Sjkim 505199323Sjkim for (i = 0; i < OuterElementCount; i++) 506199323Sjkim { 507199323Sjkim Elements = (*OuterElements)->Package.Elements; 508199323Sjkim ObjDesc = Elements[1]; /* Index1 = PowerDissipation */ 509199323Sjkim 510199323Sjkim if ((UINT32) ObjDesc->Integer.Value > PreviousValue) 511199323Sjkim { 512199323Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, 513199323Sjkim "SubPackage[%u,%u] - suspicious power dissipation values", 514199323Sjkim i-1, i)); 515199323Sjkim } 516199323Sjkim 517199323Sjkim PreviousValue = (UINT32) ObjDesc->Integer.Value; 518199323Sjkim OuterElements++; 519199323Sjkim } 520199323Sjkim 521199323Sjkim return (AE_OK); 522199323Sjkim} 523199323Sjkim 524199323Sjkim 525199323Sjkim/****************************************************************************** 526199323Sjkim * 527199323Sjkim * FUNCTION: AcpiNsCheckSortedList 528199323Sjkim * 529199323Sjkim * PARAMETERS: Data - Pointer to validation data structure 530199323Sjkim * ReturnObject - Pointer to the top-level returned object 531199323Sjkim * ExpectedCount - Minimum length of each sub-package 532199323Sjkim * SortIndex - Sub-package entry to sort on 533199323Sjkim * SortDirection - Ascending or descending 534199323Sjkim * SortKeyName - Name of the SortIndex field 535199323Sjkim * 536199323Sjkim * RETURN: Status. AE_OK if the list is valid and is sorted correctly or 537199323Sjkim * has been repaired by sorting the list. 538199323Sjkim * 539199323Sjkim * DESCRIPTION: Check if the package list is valid and sorted correctly by the 540199323Sjkim * SortIndex. If not, then sort the list. 541199323Sjkim * 542199323Sjkim *****************************************************************************/ 543199323Sjkim 544199323Sjkimstatic ACPI_STATUS 545199323SjkimAcpiNsCheckSortedList ( 546199323Sjkim ACPI_PREDEFINED_DATA *Data, 547199323Sjkim ACPI_OPERAND_OBJECT *ReturnObject, 548199323Sjkim UINT32 ExpectedCount, 549199323Sjkim UINT32 SortIndex, 550199323Sjkim UINT8 SortDirection, 551199323Sjkim char *SortKeyName) 552199323Sjkim{ 553199323Sjkim UINT32 OuterElementCount; 554199323Sjkim ACPI_OPERAND_OBJECT **OuterElements; 555199323Sjkim ACPI_OPERAND_OBJECT **Elements; 556199323Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 557199323Sjkim UINT32 i; 558199323Sjkim UINT32 PreviousValue; 559199323Sjkim 560199323Sjkim 561200553Sjkim ACPI_FUNCTION_NAME (NsCheckSortedList); 562200553Sjkim 563200553Sjkim 564199323Sjkim /* The top-level object must be a package */ 565199323Sjkim 566199323Sjkim if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE) 567199323Sjkim { 568199323Sjkim return (AE_AML_OPERAND_TYPE); 569199323Sjkim } 570199323Sjkim 571199323Sjkim /* 572200553Sjkim * NOTE: assumes list of sub-packages contains no NULL elements. 573200553Sjkim * Any NULL elements should have been removed by earlier call 574200553Sjkim * to AcpiNsRemoveNullElements. 575199323Sjkim */ 576199323Sjkim OuterElements = ReturnObject->Package.Elements; 577199323Sjkim OuterElementCount = ReturnObject->Package.Count; 578199323Sjkim if (!OuterElementCount) 579199323Sjkim { 580199323Sjkim return (AE_AML_PACKAGE_LIMIT); 581199323Sjkim } 582199323Sjkim 583199323Sjkim PreviousValue = 0; 584199323Sjkim if (SortDirection == ACPI_SORT_DESCENDING) 585199323Sjkim { 586199323Sjkim PreviousValue = ACPI_UINT32_MAX; 587199323Sjkim } 588199323Sjkim 589199323Sjkim /* Examine each subpackage */ 590199323Sjkim 591199323Sjkim for (i = 0; i < OuterElementCount; i++) 592199323Sjkim { 593199323Sjkim /* Each element of the top-level package must also be a package */ 594199323Sjkim 595199323Sjkim if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE) 596199323Sjkim { 597199323Sjkim return (AE_AML_OPERAND_TYPE); 598199323Sjkim } 599199323Sjkim 600199323Sjkim /* Each sub-package must have the minimum length */ 601199323Sjkim 602199323Sjkim if ((*OuterElements)->Package.Count < ExpectedCount) 603199323Sjkim { 604199323Sjkim return (AE_AML_PACKAGE_LIMIT); 605199323Sjkim } 606199323Sjkim 607199323Sjkim Elements = (*OuterElements)->Package.Elements; 608199323Sjkim ObjDesc = Elements[SortIndex]; 609199323Sjkim 610199323Sjkim if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER) 611199323Sjkim { 612199323Sjkim return (AE_AML_OPERAND_TYPE); 613199323Sjkim } 614199323Sjkim 615199323Sjkim /* 616199323Sjkim * The list must be sorted in the specified order. If we detect a 617202771Sjkim * discrepancy, sort the entire list. 618199323Sjkim */ 619199323Sjkim if (((SortDirection == ACPI_SORT_ASCENDING) && 620199323Sjkim (ObjDesc->Integer.Value < PreviousValue)) || 621199323Sjkim ((SortDirection == ACPI_SORT_DESCENDING) && 622199323Sjkim (ObjDesc->Integer.Value > PreviousValue))) 623199323Sjkim { 624202771Sjkim AcpiNsSortList (ReturnObject->Package.Elements, 625202771Sjkim OuterElementCount, SortIndex, SortDirection); 626199323Sjkim 627199323Sjkim Data->Flags |= ACPI_OBJECT_REPAIRED; 628199323Sjkim 629200553Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 630200553Sjkim "%s: Repaired unsorted list - now sorted by %s\n", 631200553Sjkim Data->Pathname, SortKeyName)); 632199323Sjkim return (AE_OK); 633199323Sjkim } 634199323Sjkim 635199323Sjkim PreviousValue = (UINT32) ObjDesc->Integer.Value; 636199323Sjkim OuterElements++; 637199323Sjkim } 638199323Sjkim 639199323Sjkim return (AE_OK); 640199323Sjkim} 641199323Sjkim 642199323Sjkim 643199323Sjkim/****************************************************************************** 644199323Sjkim * 645199323Sjkim * FUNCTION: AcpiNsSortList 646199323Sjkim * 647199323Sjkim * PARAMETERS: Elements - Package object element list 648199323Sjkim * Count - Element count for above 649199323Sjkim * Index - Sort by which package element 650199323Sjkim * SortDirection - Ascending or Descending sort 651199323Sjkim * 652202771Sjkim * RETURN: None 653199323Sjkim * 654199323Sjkim * DESCRIPTION: Sort the objects that are in a package element list. 655199323Sjkim * 656202771Sjkim * NOTE: Assumes that all NULL elements have been removed from the package, 657202771Sjkim * and that all elements have been verified to be of type Integer. 658199323Sjkim * 659199323Sjkim *****************************************************************************/ 660199323Sjkim 661202771Sjkimstatic void 662199323SjkimAcpiNsSortList ( 663199323Sjkim ACPI_OPERAND_OBJECT **Elements, 664199323Sjkim UINT32 Count, 665199323Sjkim UINT32 Index, 666199323Sjkim UINT8 SortDirection) 667199323Sjkim{ 668199323Sjkim ACPI_OPERAND_OBJECT *ObjDesc1; 669199323Sjkim ACPI_OPERAND_OBJECT *ObjDesc2; 670199323Sjkim ACPI_OPERAND_OBJECT *TempObj; 671199323Sjkim UINT32 i; 672199323Sjkim UINT32 j; 673199323Sjkim 674199323Sjkim 675199323Sjkim /* Simple bubble sort */ 676199323Sjkim 677199323Sjkim for (i = 1; i < Count; i++) 678199323Sjkim { 679199323Sjkim for (j = (Count - 1); j >= i; j--) 680199323Sjkim { 681199323Sjkim ObjDesc1 = Elements[j-1]->Package.Elements[Index]; 682199323Sjkim ObjDesc2 = Elements[j]->Package.Elements[Index]; 683199323Sjkim 684199323Sjkim if (((SortDirection == ACPI_SORT_ASCENDING) && 685199323Sjkim (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) || 686199323Sjkim 687199323Sjkim ((SortDirection == ACPI_SORT_DESCENDING) && 688199323Sjkim (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value))) 689199323Sjkim { 690199323Sjkim TempObj = Elements[j-1]; 691199323Sjkim Elements[j-1] = Elements[j]; 692199323Sjkim Elements[j] = TempObj; 693199323Sjkim } 694199323Sjkim } 695199323Sjkim } 696199323Sjkim} 697