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