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 89a9d8d09cSJung-uk Kim AcpiNsRepair_CST ( 90a9d8d09cSJung-uk Kim ACPI_EVALUATE_INFO *Info, 91a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 92a9d8d09cSJung-uk Kim 93a9d8d09cSJung-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 104a9d8d09cSJung-uk Kim AcpiNsRepair_PRT ( 105a9d8d09cSJung-uk Kim ACPI_EVALUATE_INFO *Info, 106a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 107a9d8d09cSJung-uk Kim 108a9d8d09cSJung-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, 122a9d8d09cSJung-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 128a9d8d09cSJung-uk Kim /* Values for SortDirection above */ 129a9d8d09cSJung-uk Kim 130a9d8d09cSJung-uk Kim #define ACPI_SORT_ASCENDING 0 131a9d8d09cSJung-uk Kim #define ACPI_SORT_DESCENDING 1 132a9d8d09cSJung-uk Kim 133a9d8d09cSJung-uk Kim static void 134a9d8d09cSJung-uk Kim AcpiNsRemoveElement ( 135a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc, 136a9d8d09cSJung-uk Kim UINT32 Index); 137a9d8d09cSJung-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 154a9d8d09cSJung-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 158a9d8d09cSJung-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}, 173a9d8d09cSJung-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}, 177a9d8d09cSJung-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 290a9d8d09cSJung-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: 377a9d8d09cSJung-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 * 470a9d8d09cSJung-uk Kim * FUNCTION: AcpiNsRepair_CST 471a9d8d09cSJung-uk Kim * 472a9d8d09cSJung-uk Kim * PARAMETERS: Info - Method execution information block 473a9d8d09cSJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 474a9d8d09cSJung-uk Kim * evaluation of a method or object 475a9d8d09cSJung-uk Kim * 476a9d8d09cSJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 477a9d8d09cSJung-uk Kim * 478a9d8d09cSJung-uk Kim * DESCRIPTION: Repair for the _CST object: 479a9d8d09cSJung-uk Kim * 1. Sort the list ascending by C state type 480a9d8d09cSJung-uk Kim * 2. Ensure type cannot be zero 481a9d8d09cSJung-uk Kim * 3. A sub-package count of zero means _CST is meaningless 482a9d8d09cSJung-uk Kim * 4. Count must match the number of C state sub-packages 483a9d8d09cSJung-uk Kim * 484a9d8d09cSJung-uk Kim *****************************************************************************/ 485a9d8d09cSJung-uk Kim 486a9d8d09cSJung-uk Kim static ACPI_STATUS 487a9d8d09cSJung-uk Kim AcpiNsRepair_CST ( 488a9d8d09cSJung-uk Kim ACPI_EVALUATE_INFO *Info, 489a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 490a9d8d09cSJung-uk Kim { 491a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 492a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **OuterElements; 493a9d8d09cSJung-uk Kim UINT32 OuterElementCount; 494a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc; 495a9d8d09cSJung-uk Kim ACPI_STATUS Status; 496a9d8d09cSJung-uk Kim BOOLEAN Removing; 497a9d8d09cSJung-uk Kim UINT32 i; 498a9d8d09cSJung-uk Kim 499a9d8d09cSJung-uk Kim 500a9d8d09cSJung-uk Kim ACPI_FUNCTION_NAME (NsRepair_CST); 501a9d8d09cSJung-uk Kim 502a9d8d09cSJung-uk Kim 503a9d8d09cSJung-uk Kim /* 504*8d744e47SJung-uk Kim * Check if the C-state type values are proportional. 505a9d8d09cSJung-uk Kim */ 506a9d8d09cSJung-uk Kim OuterElementCount = ReturnObject->Package.Count - 1; 507a9d8d09cSJung-uk Kim i = 0; 508a9d8d09cSJung-uk Kim while (i < OuterElementCount) 509a9d8d09cSJung-uk Kim { 510a9d8d09cSJung-uk Kim OuterElements = &ReturnObject->Package.Elements[i + 1]; 511a9d8d09cSJung-uk Kim Removing = FALSE; 512a9d8d09cSJung-uk Kim 513a9d8d09cSJung-uk Kim if ((*OuterElements)->Package.Count == 0) 514a9d8d09cSJung-uk Kim { 515a9d8d09cSJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 516a9d8d09cSJung-uk Kim "SubPackage[%u] - removing entry due to zero count", i)); 517a9d8d09cSJung-uk Kim Removing = TRUE; 518*8d744e47SJung-uk Kim goto RemoveElement; 519a9d8d09cSJung-uk Kim } 520a9d8d09cSJung-uk Kim 521a9d8d09cSJung-uk Kim ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */ 522a9d8d09cSJung-uk Kim if ((UINT32) ObjDesc->Integer.Value == 0) 523a9d8d09cSJung-uk Kim { 524a9d8d09cSJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 525a9d8d09cSJung-uk Kim "SubPackage[%u] - removing entry due to invalid Type(0)", i)); 526a9d8d09cSJung-uk Kim Removing = TRUE; 527a9d8d09cSJung-uk Kim } 528a9d8d09cSJung-uk Kim 529*8d744e47SJung-uk Kim RemoveElement: 530a9d8d09cSJung-uk Kim if (Removing) 531a9d8d09cSJung-uk Kim { 532a9d8d09cSJung-uk Kim AcpiNsRemoveElement (ReturnObject, i + 1); 533a9d8d09cSJung-uk Kim OuterElementCount--; 534a9d8d09cSJung-uk Kim } 535a9d8d09cSJung-uk Kim else 536a9d8d09cSJung-uk Kim { 537a9d8d09cSJung-uk Kim i++; 538a9d8d09cSJung-uk Kim } 539a9d8d09cSJung-uk Kim } 540a9d8d09cSJung-uk Kim 541a9d8d09cSJung-uk Kim /* Update top-level package count, Type "Integer" checked elsewhere */ 542a9d8d09cSJung-uk Kim 543a9d8d09cSJung-uk Kim ObjDesc = ReturnObject->Package.Elements[0]; 544a9d8d09cSJung-uk Kim ObjDesc->Integer.Value = OuterElementCount; 545*8d744e47SJung-uk Kim 546*8d744e47SJung-uk Kim /* 547*8d744e47SJung-uk Kim * Entries (subpackages) in the _CST Package must be sorted by the 548*8d744e47SJung-uk Kim * C-state type, in ascending order. 549*8d744e47SJung-uk Kim */ 550*8d744e47SJung-uk Kim Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1, 551*8d744e47SJung-uk Kim ACPI_SORT_ASCENDING, "C-State Type"); 552*8d744e47SJung-uk Kim if (ACPI_FAILURE (Status)) 553*8d744e47SJung-uk Kim { 554*8d744e47SJung-uk Kim return (Status); 555*8d744e47SJung-uk Kim } 556*8d744e47SJung-uk Kim 557a9d8d09cSJung-uk Kim return (AE_OK); 558a9d8d09cSJung-uk Kim } 559a9d8d09cSJung-uk Kim 560a9d8d09cSJung-uk Kim 561a9d8d09cSJung-uk Kim /****************************************************************************** 562a9d8d09cSJung-uk Kim * 563a159c266SJung-uk Kim * FUNCTION: AcpiNsRepair_HID 564a159c266SJung-uk Kim * 565895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 566a159c266SJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 567a159c266SJung-uk Kim * evaluation of a method or object 568a159c266SJung-uk Kim * 569a159c266SJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 570a159c266SJung-uk Kim * 571a159c266SJung-uk Kim * DESCRIPTION: Repair for the _HID object. If a string, ensure that all 572a159c266SJung-uk Kim * letters are uppercase and that there is no leading asterisk. 573a159c266SJung-uk Kim * 574a159c266SJung-uk Kim *****************************************************************************/ 575a159c266SJung-uk Kim 576a159c266SJung-uk Kim static ACPI_STATUS 577a159c266SJung-uk Kim AcpiNsRepair_HID ( 578895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 579a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 580a159c266SJung-uk Kim { 581a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 582a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *NewString; 583a159c266SJung-uk Kim char *Source; 584a159c266SJung-uk Kim char *Dest; 585a159c266SJung-uk Kim 586a159c266SJung-uk Kim 587a159c266SJung-uk Kim ACPI_FUNCTION_NAME (NsRepair_HID); 588a159c266SJung-uk Kim 589a159c266SJung-uk Kim 590a159c266SJung-uk Kim /* We only care about string _HID objects (not integers) */ 591a159c266SJung-uk Kim 592a159c266SJung-uk Kim if (ReturnObject->Common.Type != ACPI_TYPE_STRING) 593a159c266SJung-uk Kim { 594a159c266SJung-uk Kim return (AE_OK); 595a159c266SJung-uk Kim } 596a159c266SJung-uk Kim 597a159c266SJung-uk Kim if (ReturnObject->String.Length == 0) 598a159c266SJung-uk Kim { 599895f26a9SJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 600a159c266SJung-uk Kim "Invalid zero-length _HID or _CID string")); 601a159c266SJung-uk Kim 602a159c266SJung-uk Kim /* Return AE_OK anyway, let driver handle it */ 603a159c266SJung-uk Kim 604895f26a9SJung-uk Kim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 605a159c266SJung-uk Kim return (AE_OK); 606a159c266SJung-uk Kim } 607a159c266SJung-uk Kim 608a159c266SJung-uk Kim /* It is simplest to always create a new string object */ 609a159c266SJung-uk Kim 610a159c266SJung-uk Kim NewString = AcpiUtCreateStringObject (ReturnObject->String.Length); 611a159c266SJung-uk Kim if (!NewString) 612a159c266SJung-uk Kim { 613a159c266SJung-uk Kim return (AE_NO_MEMORY); 614a159c266SJung-uk Kim } 615a159c266SJung-uk Kim 616a159c266SJung-uk Kim /* 617a159c266SJung-uk Kim * Remove a leading asterisk if present. For some unknown reason, there 618a159c266SJung-uk Kim * are many machines in the field that contains IDs like this. 619a159c266SJung-uk Kim * 620a159c266SJung-uk Kim * Examples: "*PNP0C03", "*ACPI0003" 621a159c266SJung-uk Kim */ 622a159c266SJung-uk Kim Source = ReturnObject->String.Pointer; 623a159c266SJung-uk Kim if (*Source == '*') 624a159c266SJung-uk Kim { 625a159c266SJung-uk Kim Source++; 626a159c266SJung-uk Kim NewString->String.Length--; 627a159c266SJung-uk Kim 628a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 629895f26a9SJung-uk Kim "%s: Removed invalid leading asterisk\n", Info->FullPathname)); 630a159c266SJung-uk Kim } 631a159c266SJung-uk Kim 632a159c266SJung-uk Kim /* 633a159c266SJung-uk Kim * Copy and uppercase the string. From the ACPI 5.0 specification: 634a159c266SJung-uk Kim * 635a159c266SJung-uk Kim * A valid PNP ID must be of the form "AAA####" where A is an uppercase 636a159c266SJung-uk Kim * letter and # is a hex digit. A valid ACPI ID must be of the form 637a159c266SJung-uk Kim * "NNNN####" where N is an uppercase letter or decimal digit, and 638a159c266SJung-uk Kim * # is a hex digit. 639a159c266SJung-uk Kim */ 640a159c266SJung-uk Kim for (Dest = NewString->String.Pointer; *Source; Dest++, Source++) 641a159c266SJung-uk Kim { 642a159c266SJung-uk Kim *Dest = (char) ACPI_TOUPPER (*Source); 643a159c266SJung-uk Kim } 644a159c266SJung-uk Kim 645a159c266SJung-uk Kim AcpiUtRemoveReference (ReturnObject); 646a159c266SJung-uk Kim *ReturnObjectPtr = NewString; 647a159c266SJung-uk Kim return (AE_OK); 648a159c266SJung-uk Kim } 649a159c266SJung-uk Kim 650a159c266SJung-uk Kim 651a159c266SJung-uk Kim /****************************************************************************** 652a159c266SJung-uk Kim * 653a9d8d09cSJung-uk Kim * FUNCTION: AcpiNsRepair_PRT 654a159c266SJung-uk Kim * 655895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 656a159c266SJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 657a159c266SJung-uk Kim * evaluation of a method or object 658a159c266SJung-uk Kim * 659a159c266SJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 660a159c266SJung-uk Kim * 661a9d8d09cSJung-uk Kim * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed 662a9d8d09cSJung-uk Kim * SourceName and SourceIndex field, a common BIOS bug. 663a159c266SJung-uk Kim * 664a159c266SJung-uk Kim *****************************************************************************/ 665a159c266SJung-uk Kim 666a159c266SJung-uk Kim static ACPI_STATUS 667a9d8d09cSJung-uk Kim AcpiNsRepair_PRT ( 668895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 669a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 670a159c266SJung-uk Kim { 671a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *PackageObject = *ReturnObjectPtr; 672a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **TopObjectList; 673a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **SubObjectList; 674a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc; 675a9d8d09cSJung-uk Kim UINT32 ElementCount; 676a9d8d09cSJung-uk Kim UINT32 Index; 677a159c266SJung-uk Kim 678a159c266SJung-uk Kim 679a9d8d09cSJung-uk Kim /* Each element in the _PRT package is a subpackage */ 680a9d8d09cSJung-uk Kim 681a9d8d09cSJung-uk Kim TopObjectList = PackageObject->Package.Elements; 682a9d8d09cSJung-uk Kim ElementCount = PackageObject->Package.Count; 683a9d8d09cSJung-uk Kim 684a9d8d09cSJung-uk Kim for (Index = 0; Index < ElementCount; Index++) 685a9d8d09cSJung-uk Kim { 686a9d8d09cSJung-uk Kim SubObjectList = (*TopObjectList)->Package.Elements; 687a9d8d09cSJung-uk Kim 688a159c266SJung-uk Kim /* 689a9d8d09cSJung-uk Kim * If the BIOS has erroneously reversed the _PRT SourceName (index 2) 690a9d8d09cSJung-uk Kim * and the SourceIndex (index 3), fix it. _PRT is important enough to 691a9d8d09cSJung-uk Kim * workaround this BIOS error. This also provides compatibility with 692a9d8d09cSJung-uk Kim * other ACPI implementations. 693a159c266SJung-uk Kim */ 694a9d8d09cSJung-uk Kim ObjDesc = SubObjectList[3]; 695a9d8d09cSJung-uk Kim if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)) 696a159c266SJung-uk Kim { 697a9d8d09cSJung-uk Kim SubObjectList[3] = SubObjectList[2]; 698a9d8d09cSJung-uk Kim SubObjectList[2] = ObjDesc; 699a9d8d09cSJung-uk Kim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 700a9d8d09cSJung-uk Kim 701a9d8d09cSJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 702a9d8d09cSJung-uk Kim "PRT[%X]: Fixed reversed SourceName and SourceIndex", 703a9d8d09cSJung-uk Kim Index)); 704a159c266SJung-uk Kim } 705a159c266SJung-uk Kim 706a9d8d09cSJung-uk Kim /* Point to the next ACPI_OPERAND_OBJECT in the top level package */ 707a159c266SJung-uk Kim 708a9d8d09cSJung-uk Kim TopObjectList++; 709a9d8d09cSJung-uk Kim } 710a9d8d09cSJung-uk Kim 711a9d8d09cSJung-uk Kim return (AE_OK); 712a159c266SJung-uk Kim } 713a159c266SJung-uk Kim 714a159c266SJung-uk Kim 715a159c266SJung-uk Kim /****************************************************************************** 716a159c266SJung-uk Kim * 717a159c266SJung-uk Kim * FUNCTION: AcpiNsRepair_PSS 718a159c266SJung-uk Kim * 719895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 720a159c266SJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 721a159c266SJung-uk Kim * evaluation of a method or object 722a159c266SJung-uk Kim * 723a159c266SJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 724a159c266SJung-uk Kim * 725a159c266SJung-uk Kim * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list 726a159c266SJung-uk Kim * by the CPU frequencies. Check that the power dissipation values 727a159c266SJung-uk Kim * are all proportional to CPU frequency (i.e., sorting by 728a159c266SJung-uk Kim * frequency should be the same as sorting by power.) 729a159c266SJung-uk Kim * 730a159c266SJung-uk Kim *****************************************************************************/ 731a159c266SJung-uk Kim 732a159c266SJung-uk Kim static ACPI_STATUS 733a159c266SJung-uk Kim AcpiNsRepair_PSS ( 734895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 735a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 736a159c266SJung-uk Kim { 737a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 738a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **OuterElements; 739a159c266SJung-uk Kim UINT32 OuterElementCount; 740a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **Elements; 741a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc; 742a159c266SJung-uk Kim UINT32 PreviousValue; 743a159c266SJung-uk Kim ACPI_STATUS Status; 744a159c266SJung-uk Kim UINT32 i; 745a159c266SJung-uk Kim 746a159c266SJung-uk Kim 747a159c266SJung-uk Kim /* 748a159c266SJung-uk Kim * Entries (sub-packages) in the _PSS Package must be sorted by power 749a159c266SJung-uk Kim * dissipation, in descending order. If it appears that the list is 750a159c266SJung-uk Kim * incorrectly sorted, sort it. We sort by CpuFrequency, since this 751a159c266SJung-uk Kim * should be proportional to the power. 752a159c266SJung-uk Kim */ 753a9d8d09cSJung-uk Kim Status =AcpiNsCheckSortedList (Info, ReturnObject, 0, 6, 0, 754a159c266SJung-uk Kim ACPI_SORT_DESCENDING, "CpuFrequency"); 755a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 756a159c266SJung-uk Kim { 757a159c266SJung-uk Kim return (Status); 758a159c266SJung-uk Kim } 759a159c266SJung-uk Kim 760a159c266SJung-uk Kim /* 761a159c266SJung-uk Kim * We now know the list is correctly sorted by CPU frequency. Check if 762a159c266SJung-uk Kim * the power dissipation values are proportional. 763a159c266SJung-uk Kim */ 764a159c266SJung-uk Kim PreviousValue = ACPI_UINT32_MAX; 765a159c266SJung-uk Kim OuterElements = ReturnObject->Package.Elements; 766a159c266SJung-uk Kim OuterElementCount = ReturnObject->Package.Count; 767a159c266SJung-uk Kim 768a159c266SJung-uk Kim for (i = 0; i < OuterElementCount; i++) 769a159c266SJung-uk Kim { 770a159c266SJung-uk Kim Elements = (*OuterElements)->Package.Elements; 771a159c266SJung-uk Kim ObjDesc = Elements[1]; /* Index1 = PowerDissipation */ 772a159c266SJung-uk Kim 773a159c266SJung-uk Kim if ((UINT32) ObjDesc->Integer.Value > PreviousValue) 774a159c266SJung-uk Kim { 775895f26a9SJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 776a159c266SJung-uk Kim "SubPackage[%u,%u] - suspicious power dissipation values", 777a159c266SJung-uk Kim i-1, i)); 778a159c266SJung-uk Kim } 779a159c266SJung-uk Kim 780a159c266SJung-uk Kim PreviousValue = (UINT32) ObjDesc->Integer.Value; 781a159c266SJung-uk Kim OuterElements++; 782a159c266SJung-uk Kim } 783a159c266SJung-uk Kim 784a159c266SJung-uk Kim return (AE_OK); 785a159c266SJung-uk Kim } 786a159c266SJung-uk Kim 787a159c266SJung-uk Kim 788a159c266SJung-uk Kim /****************************************************************************** 789a159c266SJung-uk Kim * 790a9d8d09cSJung-uk Kim * FUNCTION: AcpiNsRepair_TSS 791a9d8d09cSJung-uk Kim * 792a9d8d09cSJung-uk Kim * PARAMETERS: Info - Method execution information block 793a9d8d09cSJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 794a9d8d09cSJung-uk Kim * evaluation of a method or object 795a9d8d09cSJung-uk Kim * 796a9d8d09cSJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 797a9d8d09cSJung-uk Kim * 798a9d8d09cSJung-uk Kim * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list 799a9d8d09cSJung-uk Kim * descending by the power dissipation values. 800a9d8d09cSJung-uk Kim * 801a9d8d09cSJung-uk Kim *****************************************************************************/ 802a9d8d09cSJung-uk Kim 803a9d8d09cSJung-uk Kim static ACPI_STATUS 804a9d8d09cSJung-uk Kim AcpiNsRepair_TSS ( 805a9d8d09cSJung-uk Kim ACPI_EVALUATE_INFO *Info, 806a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 807a9d8d09cSJung-uk Kim { 808a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 809a9d8d09cSJung-uk Kim ACPI_STATUS Status; 810a9d8d09cSJung-uk Kim ACPI_NAMESPACE_NODE *Node; 811a9d8d09cSJung-uk Kim 812a9d8d09cSJung-uk Kim 813a9d8d09cSJung-uk Kim /* 814a9d8d09cSJung-uk Kim * We can only sort the _TSS return package if there is no _PSS in the 815a9d8d09cSJung-uk Kim * same scope. This is because if _PSS is present, the ACPI specification 816a9d8d09cSJung-uk Kim * dictates that the _TSS Power Dissipation field is to be ignored, and 817a9d8d09cSJung-uk Kim * therefore some BIOSs leave garbage values in the _TSS Power field(s). 818a9d8d09cSJung-uk Kim * In this case, it is best to just return the _TSS package as-is. 819a9d8d09cSJung-uk Kim * (May, 2011) 820a9d8d09cSJung-uk Kim */ 821a9d8d09cSJung-uk Kim Status = AcpiNsGetNode (Info->Node, "^_PSS", 822a9d8d09cSJung-uk Kim ACPI_NS_NO_UPSEARCH, &Node); 823a9d8d09cSJung-uk Kim if (ACPI_SUCCESS (Status)) 824a9d8d09cSJung-uk Kim { 825a9d8d09cSJung-uk Kim return (AE_OK); 826a9d8d09cSJung-uk Kim } 827a9d8d09cSJung-uk Kim 828a9d8d09cSJung-uk Kim Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1, 829a9d8d09cSJung-uk Kim ACPI_SORT_DESCENDING, "PowerDissipation"); 830a9d8d09cSJung-uk Kim 831a9d8d09cSJung-uk Kim return (Status); 832a9d8d09cSJung-uk Kim } 833a9d8d09cSJung-uk Kim 834a9d8d09cSJung-uk Kim 835a9d8d09cSJung-uk Kim /****************************************************************************** 836a9d8d09cSJung-uk Kim * 837a159c266SJung-uk Kim * FUNCTION: AcpiNsCheckSortedList 838a159c266SJung-uk Kim * 839895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 840a159c266SJung-uk Kim * ReturnObject - Pointer to the top-level returned object 841a9d8d09cSJung-uk Kim * StartIndex - Index of the first sub-package 842a159c266SJung-uk Kim * ExpectedCount - Minimum length of each sub-package 843a159c266SJung-uk Kim * SortIndex - Sub-package entry to sort on 844a159c266SJung-uk Kim * SortDirection - Ascending or descending 845a159c266SJung-uk Kim * SortKeyName - Name of the SortIndex field 846a159c266SJung-uk Kim * 847a159c266SJung-uk Kim * RETURN: Status. AE_OK if the list is valid and is sorted correctly or 848a159c266SJung-uk Kim * has been repaired by sorting the list. 849a159c266SJung-uk Kim * 850a159c266SJung-uk Kim * DESCRIPTION: Check if the package list is valid and sorted correctly by the 851a159c266SJung-uk Kim * SortIndex. If not, then sort the list. 852a159c266SJung-uk Kim * 853a159c266SJung-uk Kim *****************************************************************************/ 854a159c266SJung-uk Kim 855a159c266SJung-uk Kim static ACPI_STATUS 856a159c266SJung-uk Kim AcpiNsCheckSortedList ( 857895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 858a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject, 859a9d8d09cSJung-uk Kim UINT32 StartIndex, 860a159c266SJung-uk Kim UINT32 ExpectedCount, 861a159c266SJung-uk Kim UINT32 SortIndex, 862a159c266SJung-uk Kim UINT8 SortDirection, 863a159c266SJung-uk Kim char *SortKeyName) 864a159c266SJung-uk Kim { 865a159c266SJung-uk Kim UINT32 OuterElementCount; 866a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **OuterElements; 867a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **Elements; 868a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc; 869a159c266SJung-uk Kim UINT32 i; 870a159c266SJung-uk Kim UINT32 PreviousValue; 871a159c266SJung-uk Kim 872a159c266SJung-uk Kim 873a159c266SJung-uk Kim ACPI_FUNCTION_NAME (NsCheckSortedList); 874a159c266SJung-uk Kim 875a159c266SJung-uk Kim 876a159c266SJung-uk Kim /* The top-level object must be a package */ 877a159c266SJung-uk Kim 878a159c266SJung-uk Kim if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE) 879a159c266SJung-uk Kim { 880a159c266SJung-uk Kim return (AE_AML_OPERAND_TYPE); 881a159c266SJung-uk Kim } 882a159c266SJung-uk Kim 883a159c266SJung-uk Kim /* 884a159c266SJung-uk Kim * NOTE: assumes list of sub-packages contains no NULL elements. 885a159c266SJung-uk Kim * Any NULL elements should have been removed by earlier call 886a159c266SJung-uk Kim * to AcpiNsRemoveNullElements. 887a159c266SJung-uk Kim */ 888a159c266SJung-uk Kim OuterElementCount = ReturnObject->Package.Count; 889a9d8d09cSJung-uk Kim if (!OuterElementCount || StartIndex >= OuterElementCount) 890a159c266SJung-uk Kim { 891a159c266SJung-uk Kim return (AE_AML_PACKAGE_LIMIT); 892a159c266SJung-uk Kim } 893a159c266SJung-uk Kim 894a9d8d09cSJung-uk Kim OuterElements = &ReturnObject->Package.Elements[StartIndex]; 895a9d8d09cSJung-uk Kim OuterElementCount -= StartIndex; 896a9d8d09cSJung-uk Kim 897a159c266SJung-uk Kim PreviousValue = 0; 898a159c266SJung-uk Kim if (SortDirection == ACPI_SORT_DESCENDING) 899a159c266SJung-uk Kim { 900a159c266SJung-uk Kim PreviousValue = ACPI_UINT32_MAX; 901a159c266SJung-uk Kim } 902a159c266SJung-uk Kim 903a159c266SJung-uk Kim /* Examine each subpackage */ 904a159c266SJung-uk Kim 905a159c266SJung-uk Kim for (i = 0; i < OuterElementCount; i++) 906a159c266SJung-uk Kim { 907a159c266SJung-uk Kim /* Each element of the top-level package must also be a package */ 908a159c266SJung-uk Kim 909a159c266SJung-uk Kim if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE) 910a159c266SJung-uk Kim { 911a159c266SJung-uk Kim return (AE_AML_OPERAND_TYPE); 912a159c266SJung-uk Kim } 913a159c266SJung-uk Kim 914a159c266SJung-uk Kim /* Each sub-package must have the minimum length */ 915a159c266SJung-uk Kim 916a159c266SJung-uk Kim if ((*OuterElements)->Package.Count < ExpectedCount) 917a159c266SJung-uk Kim { 918a159c266SJung-uk Kim return (AE_AML_PACKAGE_LIMIT); 919a159c266SJung-uk Kim } 920a159c266SJung-uk Kim 921a159c266SJung-uk Kim Elements = (*OuterElements)->Package.Elements; 922a159c266SJung-uk Kim ObjDesc = Elements[SortIndex]; 923a159c266SJung-uk Kim 924a159c266SJung-uk Kim if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER) 925a159c266SJung-uk Kim { 926a159c266SJung-uk Kim return (AE_AML_OPERAND_TYPE); 927a159c266SJung-uk Kim } 928a159c266SJung-uk Kim 929a159c266SJung-uk Kim /* 930a159c266SJung-uk Kim * The list must be sorted in the specified order. If we detect a 931a159c266SJung-uk Kim * discrepancy, sort the entire list. 932a159c266SJung-uk Kim */ 933a159c266SJung-uk Kim if (((SortDirection == ACPI_SORT_ASCENDING) && 934a159c266SJung-uk Kim (ObjDesc->Integer.Value < PreviousValue)) || 935a159c266SJung-uk Kim ((SortDirection == ACPI_SORT_DESCENDING) && 936a159c266SJung-uk Kim (ObjDesc->Integer.Value > PreviousValue))) 937a159c266SJung-uk Kim { 938a9d8d09cSJung-uk Kim AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex], 939a159c266SJung-uk Kim OuterElementCount, SortIndex, SortDirection); 940a159c266SJung-uk Kim 941895f26a9SJung-uk Kim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 942a159c266SJung-uk Kim 943a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 944a159c266SJung-uk Kim "%s: Repaired unsorted list - now sorted by %s\n", 945895f26a9SJung-uk Kim Info->FullPathname, SortKeyName)); 946a159c266SJung-uk Kim return (AE_OK); 947a159c266SJung-uk Kim } 948a159c266SJung-uk Kim 949a159c266SJung-uk Kim PreviousValue = (UINT32) ObjDesc->Integer.Value; 950a159c266SJung-uk Kim OuterElements++; 951a159c266SJung-uk Kim } 952a159c266SJung-uk Kim 953a159c266SJung-uk Kim return (AE_OK); 954a159c266SJung-uk Kim } 955a159c266SJung-uk Kim 956a159c266SJung-uk Kim 957a159c266SJung-uk Kim /****************************************************************************** 958a159c266SJung-uk Kim * 959a159c266SJung-uk Kim * FUNCTION: AcpiNsSortList 960a159c266SJung-uk Kim * 961a159c266SJung-uk Kim * PARAMETERS: Elements - Package object element list 962a159c266SJung-uk Kim * Count - Element count for above 963a159c266SJung-uk Kim * Index - Sort by which package element 964a159c266SJung-uk Kim * SortDirection - Ascending or Descending sort 965a159c266SJung-uk Kim * 966a159c266SJung-uk Kim * RETURN: None 967a159c266SJung-uk Kim * 968a159c266SJung-uk Kim * DESCRIPTION: Sort the objects that are in a package element list. 969a159c266SJung-uk Kim * 970a159c266SJung-uk Kim * NOTE: Assumes that all NULL elements have been removed from the package, 971a159c266SJung-uk Kim * and that all elements have been verified to be of type Integer. 972a159c266SJung-uk Kim * 973a159c266SJung-uk Kim *****************************************************************************/ 974a159c266SJung-uk Kim 975a159c266SJung-uk Kim static void 976a159c266SJung-uk Kim AcpiNsSortList ( 977a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **Elements, 978a159c266SJung-uk Kim UINT32 Count, 979a159c266SJung-uk Kim UINT32 Index, 980a159c266SJung-uk Kim UINT8 SortDirection) 981a159c266SJung-uk Kim { 982a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc1; 983a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc2; 984a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *TempObj; 985a159c266SJung-uk Kim UINT32 i; 986a159c266SJung-uk Kim UINT32 j; 987a159c266SJung-uk Kim 988a159c266SJung-uk Kim 989a159c266SJung-uk Kim /* Simple bubble sort */ 990a159c266SJung-uk Kim 991a159c266SJung-uk Kim for (i = 1; i < Count; i++) 992a159c266SJung-uk Kim { 993a159c266SJung-uk Kim for (j = (Count - 1); j >= i; j--) 994a159c266SJung-uk Kim { 995a159c266SJung-uk Kim ObjDesc1 = Elements[j-1]->Package.Elements[Index]; 996a159c266SJung-uk Kim ObjDesc2 = Elements[j]->Package.Elements[Index]; 997a159c266SJung-uk Kim 998a159c266SJung-uk Kim if (((SortDirection == ACPI_SORT_ASCENDING) && 999a159c266SJung-uk Kim (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) || 1000a159c266SJung-uk Kim 1001a159c266SJung-uk Kim ((SortDirection == ACPI_SORT_DESCENDING) && 1002a159c266SJung-uk Kim (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value))) 1003a159c266SJung-uk Kim { 1004a159c266SJung-uk Kim TempObj = Elements[j-1]; 1005a159c266SJung-uk Kim Elements[j-1] = Elements[j]; 1006a159c266SJung-uk Kim Elements[j] = TempObj; 1007a159c266SJung-uk Kim } 1008a159c266SJung-uk Kim } 1009a159c266SJung-uk Kim } 1010a159c266SJung-uk Kim } 1011a9d8d09cSJung-uk Kim 1012a9d8d09cSJung-uk Kim 1013a9d8d09cSJung-uk Kim /****************************************************************************** 1014a9d8d09cSJung-uk Kim * 1015a9d8d09cSJung-uk Kim * FUNCTION: AcpiNsRemoveElement 1016a9d8d09cSJung-uk Kim * 1017a9d8d09cSJung-uk Kim * PARAMETERS: ObjDesc - Package object element list 1018a9d8d09cSJung-uk Kim * Index - Index of element to remove 1019a9d8d09cSJung-uk Kim * 1020a9d8d09cSJung-uk Kim * RETURN: None 1021a9d8d09cSJung-uk Kim * 1022a9d8d09cSJung-uk Kim * DESCRIPTION: Remove the requested element of a package and delete it. 1023a9d8d09cSJung-uk Kim * 1024a9d8d09cSJung-uk Kim *****************************************************************************/ 1025a9d8d09cSJung-uk Kim 1026a9d8d09cSJung-uk Kim static void 1027a9d8d09cSJung-uk Kim AcpiNsRemoveElement ( 1028a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc, 1029a9d8d09cSJung-uk Kim UINT32 Index) 1030a9d8d09cSJung-uk Kim { 1031a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **Source; 1032a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **Dest; 1033a9d8d09cSJung-uk Kim UINT32 Count; 1034a9d8d09cSJung-uk Kim UINT32 NewCount; 1035a9d8d09cSJung-uk Kim UINT32 i; 1036a9d8d09cSJung-uk Kim 1037a9d8d09cSJung-uk Kim 1038a9d8d09cSJung-uk Kim ACPI_FUNCTION_NAME (NsRemoveElement); 1039a9d8d09cSJung-uk Kim 1040a9d8d09cSJung-uk Kim 1041a9d8d09cSJung-uk Kim Count = ObjDesc->Package.Count; 1042a9d8d09cSJung-uk Kim NewCount = Count - 1; 1043a9d8d09cSJung-uk Kim 1044a9d8d09cSJung-uk Kim Source = ObjDesc->Package.Elements; 1045a9d8d09cSJung-uk Kim Dest = Source; 1046a9d8d09cSJung-uk Kim 1047a9d8d09cSJung-uk Kim /* Examine all elements of the package object, remove matched index */ 1048a9d8d09cSJung-uk Kim 1049a9d8d09cSJung-uk Kim for (i = 0; i < Count; i++) 1050a9d8d09cSJung-uk Kim { 1051a9d8d09cSJung-uk Kim if (i == Index) 1052a9d8d09cSJung-uk Kim { 1053a9d8d09cSJung-uk Kim AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */ 1054a9d8d09cSJung-uk Kim AcpiUtRemoveReference (*Source); 1055a9d8d09cSJung-uk Kim } 1056a9d8d09cSJung-uk Kim else 1057a9d8d09cSJung-uk Kim { 1058a9d8d09cSJung-uk Kim *Dest = *Source; 1059a9d8d09cSJung-uk Kim Dest++; 1060a9d8d09cSJung-uk Kim } 1061a9d8d09cSJung-uk Kim Source++; 1062a9d8d09cSJung-uk Kim } 1063a9d8d09cSJung-uk Kim 1064a9d8d09cSJung-uk Kim /* NULL terminate list and update the package count */ 1065a9d8d09cSJung-uk Kim 1066a9d8d09cSJung-uk Kim *Dest = NULL; 1067a9d8d09cSJung-uk Kim ObjDesc->Package.Count = NewCount; 1068a9d8d09cSJung-uk Kim } 1069