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 /* 9*1c0e1b6dSJung-uk Kim * Copyright (C) 2000 - 2015, 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 #include <contrib/dev/acpica/include/acpi.h> 46a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 47a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h> 48a159c266SJung-uk Kim 49a159c266SJung-uk Kim #define _COMPONENT ACPI_NAMESPACE 50a159c266SJung-uk Kim ACPI_MODULE_NAME ("nsrepair2") 51a159c266SJung-uk Kim 52a159c266SJung-uk Kim 53a159c266SJung-uk Kim /* 54a159c266SJung-uk Kim * Information structure and handler for ACPI predefined names that can 55a159c266SJung-uk Kim * be repaired on a per-name basis. 56a159c266SJung-uk Kim */ 57a159c266SJung-uk Kim typedef 58a159c266SJung-uk Kim ACPI_STATUS (*ACPI_REPAIR_FUNCTION) ( 59895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 60a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 61a159c266SJung-uk Kim 62a159c266SJung-uk Kim typedef struct acpi_repair_info 63a159c266SJung-uk Kim { 64a159c266SJung-uk Kim char Name[ACPI_NAME_SIZE]; 65a159c266SJung-uk Kim ACPI_REPAIR_FUNCTION RepairFunction; 66a159c266SJung-uk Kim 67a159c266SJung-uk Kim } ACPI_REPAIR_INFO; 68a159c266SJung-uk Kim 69a159c266SJung-uk Kim 70a159c266SJung-uk Kim /* Local prototypes */ 71a159c266SJung-uk Kim 72a159c266SJung-uk Kim static const ACPI_REPAIR_INFO * 739c48c75eSJung-uk Kim AcpiNsMatchComplexRepair ( 74a159c266SJung-uk Kim ACPI_NAMESPACE_NODE *Node); 75a159c266SJung-uk Kim 76a159c266SJung-uk Kim static ACPI_STATUS 77a159c266SJung-uk Kim AcpiNsRepair_ALR ( 78895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 79a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 80a159c266SJung-uk Kim 81a159c266SJung-uk Kim static ACPI_STATUS 82a159c266SJung-uk Kim AcpiNsRepair_CID ( 83895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 84a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 85a159c266SJung-uk Kim 86a159c266SJung-uk Kim static ACPI_STATUS 87a9d8d09cSJung-uk Kim AcpiNsRepair_CST ( 88a9d8d09cSJung-uk Kim ACPI_EVALUATE_INFO *Info, 89a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 90a9d8d09cSJung-uk Kim 91a9d8d09cSJung-uk Kim static ACPI_STATUS 92a159c266SJung-uk Kim AcpiNsRepair_FDE ( 93895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 94a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 95a159c266SJung-uk Kim 96a159c266SJung-uk Kim static ACPI_STATUS 97a159c266SJung-uk Kim AcpiNsRepair_HID ( 98895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 99a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 100a159c266SJung-uk Kim 101a159c266SJung-uk Kim static ACPI_STATUS 102a9d8d09cSJung-uk Kim AcpiNsRepair_PRT ( 103a9d8d09cSJung-uk Kim ACPI_EVALUATE_INFO *Info, 104a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 105a9d8d09cSJung-uk Kim 106a9d8d09cSJung-uk Kim static ACPI_STATUS 107a159c266SJung-uk Kim AcpiNsRepair_PSS ( 108895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 109a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 110a159c266SJung-uk Kim 111a159c266SJung-uk Kim static ACPI_STATUS 112a159c266SJung-uk Kim AcpiNsRepair_TSS ( 113895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 114a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr); 115a159c266SJung-uk Kim 116a159c266SJung-uk Kim static ACPI_STATUS 117a159c266SJung-uk Kim AcpiNsCheckSortedList ( 118895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 119a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject, 120a9d8d09cSJung-uk Kim UINT32 StartIndex, 121a159c266SJung-uk Kim UINT32 ExpectedCount, 122a159c266SJung-uk Kim UINT32 SortIndex, 123a159c266SJung-uk Kim UINT8 SortDirection, 124a159c266SJung-uk Kim char *SortKeyName); 125a159c266SJung-uk Kim 126a9d8d09cSJung-uk Kim /* Values for SortDirection above */ 127a9d8d09cSJung-uk Kim 128a9d8d09cSJung-uk Kim #define ACPI_SORT_ASCENDING 0 129a9d8d09cSJung-uk Kim #define ACPI_SORT_DESCENDING 1 130a9d8d09cSJung-uk Kim 131a9d8d09cSJung-uk Kim static void 132a9d8d09cSJung-uk Kim AcpiNsRemoveElement ( 133a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc, 134a9d8d09cSJung-uk Kim UINT32 Index); 135a9d8d09cSJung-uk Kim 136a159c266SJung-uk Kim static void 137a159c266SJung-uk Kim AcpiNsSortList ( 138a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **Elements, 139a159c266SJung-uk Kim UINT32 Count, 140a159c266SJung-uk Kim UINT32 Index, 141a159c266SJung-uk Kim UINT8 SortDirection); 142a159c266SJung-uk Kim 143a159c266SJung-uk Kim 144a159c266SJung-uk Kim /* 145a159c266SJung-uk Kim * This table contains the names of the predefined methods for which we can 146a159c266SJung-uk Kim * perform more complex repairs. 147a159c266SJung-uk Kim * 148a159c266SJung-uk Kim * As necessary: 149a159c266SJung-uk Kim * 150a159c266SJung-uk Kim * _ALR: Sort the list ascending by AmbientIlluminance 151a159c266SJung-uk Kim * _CID: Strings: uppercase all, remove any leading asterisk 152a9d8d09cSJung-uk Kim * _CST: Sort the list ascending by C state type 153a159c266SJung-uk Kim * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs 154a159c266SJung-uk Kim * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs 155a159c266SJung-uk Kim * _HID: Strings: uppercase all, remove any leading asterisk 156a9d8d09cSJung-uk Kim * _PRT: Fix reversed SourceName and SourceIndex 157a159c266SJung-uk Kim * _PSS: Sort the list descending by Power 158a159c266SJung-uk Kim * _TSS: Sort the list descending by Power 159a159c266SJung-uk Kim * 160a159c266SJung-uk Kim * Names that must be packages, but cannot be sorted: 161a159c266SJung-uk Kim * 162a159c266SJung-uk Kim * _BCL: Values are tied to the Package index where they appear, and cannot 163a159c266SJung-uk Kim * be moved or sorted. These index values are used for _BQC and _BCM. 164a159c266SJung-uk Kim * However, we can fix the case where a buffer is returned, by converting 165a159c266SJung-uk Kim * it to a Package of integers. 166a159c266SJung-uk Kim */ 167a159c266SJung-uk Kim static const ACPI_REPAIR_INFO AcpiNsRepairableNames[] = 168a159c266SJung-uk Kim { 169a159c266SJung-uk Kim {"_ALR", AcpiNsRepair_ALR}, 170a159c266SJung-uk Kim {"_CID", AcpiNsRepair_CID}, 171a9d8d09cSJung-uk Kim {"_CST", AcpiNsRepair_CST}, 172a159c266SJung-uk Kim {"_FDE", AcpiNsRepair_FDE}, 173a159c266SJung-uk Kim {"_GTM", AcpiNsRepair_FDE}, /* _GTM has same repair as _FDE */ 174a159c266SJung-uk Kim {"_HID", AcpiNsRepair_HID}, 175a9d8d09cSJung-uk Kim {"_PRT", AcpiNsRepair_PRT}, 176a159c266SJung-uk Kim {"_PSS", AcpiNsRepair_PSS}, 177a159c266SJung-uk Kim {"_TSS", AcpiNsRepair_TSS}, 178a159c266SJung-uk Kim {{0,0,0,0}, NULL} /* Table terminator */ 179a159c266SJung-uk Kim }; 180a159c266SJung-uk Kim 181a159c266SJung-uk Kim 182a159c266SJung-uk Kim #define ACPI_FDE_FIELD_COUNT 5 183a159c266SJung-uk Kim #define ACPI_FDE_BYTE_BUFFER_SIZE 5 184a159c266SJung-uk Kim #define ACPI_FDE_DWORD_BUFFER_SIZE (ACPI_FDE_FIELD_COUNT * sizeof (UINT32)) 185a159c266SJung-uk Kim 186a159c266SJung-uk Kim 187a159c266SJung-uk Kim /****************************************************************************** 188a159c266SJung-uk Kim * 189a159c266SJung-uk Kim * FUNCTION: AcpiNsComplexRepairs 190a159c266SJung-uk Kim * 191895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 192a159c266SJung-uk Kim * Node - Namespace node for the method/object 193a159c266SJung-uk Kim * ValidateStatus - Original status of earlier validation 194a159c266SJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 195a159c266SJung-uk Kim * evaluation of a method or object 196a159c266SJung-uk Kim * 197a159c266SJung-uk Kim * RETURN: Status. AE_OK if repair was successful. If name is not 198a159c266SJung-uk Kim * matched, ValidateStatus is returned. 199a159c266SJung-uk Kim * 200a159c266SJung-uk Kim * DESCRIPTION: Attempt to repair/convert a return object of a type that was 201a159c266SJung-uk Kim * not expected. 202a159c266SJung-uk Kim * 203a159c266SJung-uk Kim *****************************************************************************/ 204a159c266SJung-uk Kim 205a159c266SJung-uk Kim ACPI_STATUS 206a159c266SJung-uk Kim AcpiNsComplexRepairs ( 207895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 208a159c266SJung-uk Kim ACPI_NAMESPACE_NODE *Node, 209a159c266SJung-uk Kim ACPI_STATUS ValidateStatus, 210a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 211a159c266SJung-uk Kim { 212a159c266SJung-uk Kim const ACPI_REPAIR_INFO *Predefined; 213a159c266SJung-uk Kim ACPI_STATUS Status; 214a159c266SJung-uk Kim 215a159c266SJung-uk Kim 216a159c266SJung-uk Kim /* Check if this name is in the list of repairable names */ 217a159c266SJung-uk Kim 2189c48c75eSJung-uk Kim Predefined = AcpiNsMatchComplexRepair (Node); 219a159c266SJung-uk Kim if (!Predefined) 220a159c266SJung-uk Kim { 221a159c266SJung-uk Kim return (ValidateStatus); 222a159c266SJung-uk Kim } 223a159c266SJung-uk Kim 224895f26a9SJung-uk Kim Status = Predefined->RepairFunction (Info, ReturnObjectPtr); 225a159c266SJung-uk Kim return (Status); 226a159c266SJung-uk Kim } 227a159c266SJung-uk Kim 228a159c266SJung-uk Kim 229a159c266SJung-uk Kim /****************************************************************************** 230a159c266SJung-uk Kim * 2319c48c75eSJung-uk Kim * FUNCTION: AcpiNsMatchComplexRepair 232a159c266SJung-uk Kim * 233a159c266SJung-uk Kim * PARAMETERS: Node - Namespace node for the method/object 234a159c266SJung-uk Kim * 235a159c266SJung-uk Kim * RETURN: Pointer to entry in repair table. NULL indicates not found. 236a159c266SJung-uk Kim * 237a159c266SJung-uk Kim * DESCRIPTION: Check an object name against the repairable object list. 238a159c266SJung-uk Kim * 239a159c266SJung-uk Kim *****************************************************************************/ 240a159c266SJung-uk Kim 241a159c266SJung-uk Kim static const ACPI_REPAIR_INFO * 2429c48c75eSJung-uk Kim AcpiNsMatchComplexRepair ( 243a159c266SJung-uk Kim ACPI_NAMESPACE_NODE *Node) 244a159c266SJung-uk Kim { 245a159c266SJung-uk Kim const ACPI_REPAIR_INFO *ThisName; 246a159c266SJung-uk Kim 247a159c266SJung-uk Kim 248a159c266SJung-uk Kim /* Search info table for a repairable predefined method/object name */ 249a159c266SJung-uk Kim 250a159c266SJung-uk Kim ThisName = AcpiNsRepairableNames; 251a159c266SJung-uk Kim while (ThisName->RepairFunction) 252a159c266SJung-uk Kim { 253a159c266SJung-uk Kim if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name)) 254a159c266SJung-uk Kim { 255a159c266SJung-uk Kim return (ThisName); 256a159c266SJung-uk Kim } 257a159c266SJung-uk Kim ThisName++; 258a159c266SJung-uk Kim } 259a159c266SJung-uk Kim 260a159c266SJung-uk Kim return (NULL); /* Not found */ 261a159c266SJung-uk Kim } 262a159c266SJung-uk Kim 263a159c266SJung-uk Kim 264a159c266SJung-uk Kim /****************************************************************************** 265a159c266SJung-uk Kim * 266a159c266SJung-uk Kim * FUNCTION: AcpiNsRepair_ALR 267a159c266SJung-uk Kim * 268895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 269a159c266SJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 270a159c266SJung-uk Kim * evaluation of a method or object 271a159c266SJung-uk Kim * 272a159c266SJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 273a159c266SJung-uk Kim * 274a159c266SJung-uk Kim * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list 275a159c266SJung-uk Kim * ascending by the ambient illuminance values. 276a159c266SJung-uk Kim * 277a159c266SJung-uk Kim *****************************************************************************/ 278a159c266SJung-uk Kim 279a159c266SJung-uk Kim static ACPI_STATUS 280a159c266SJung-uk Kim AcpiNsRepair_ALR ( 281895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 282a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 283a159c266SJung-uk Kim { 284a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 285a159c266SJung-uk Kim ACPI_STATUS Status; 286a159c266SJung-uk Kim 287a159c266SJung-uk Kim 288a9d8d09cSJung-uk Kim Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 2, 1, 289a159c266SJung-uk Kim ACPI_SORT_ASCENDING, "AmbientIlluminance"); 290a159c266SJung-uk Kim 291a159c266SJung-uk Kim return (Status); 292a159c266SJung-uk Kim } 293a159c266SJung-uk Kim 294a159c266SJung-uk Kim 295a159c266SJung-uk Kim /****************************************************************************** 296a159c266SJung-uk Kim * 297a159c266SJung-uk Kim * FUNCTION: AcpiNsRepair_FDE 298a159c266SJung-uk Kim * 299895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 300a159c266SJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 301a159c266SJung-uk Kim * evaluation of a method or object 302a159c266SJung-uk Kim * 303a159c266SJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 304a159c266SJung-uk Kim * 305a159c266SJung-uk Kim * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return 306a159c266SJung-uk Kim * value is a Buffer of 5 DWORDs. This function repairs a common 307a159c266SJung-uk Kim * problem where the return value is a Buffer of BYTEs, not 308a159c266SJung-uk Kim * DWORDs. 309a159c266SJung-uk Kim * 310a159c266SJung-uk Kim *****************************************************************************/ 311a159c266SJung-uk Kim 312a159c266SJung-uk Kim static ACPI_STATUS 313a159c266SJung-uk Kim AcpiNsRepair_FDE ( 314895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 315a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 316a159c266SJung-uk Kim { 317a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 318a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *BufferObject; 319a159c266SJung-uk Kim UINT8 *ByteBuffer; 320a159c266SJung-uk Kim UINT32 *DwordBuffer; 321a159c266SJung-uk Kim UINT32 i; 322a159c266SJung-uk Kim 323a159c266SJung-uk Kim 324a159c266SJung-uk Kim ACPI_FUNCTION_NAME (NsRepair_FDE); 325a159c266SJung-uk Kim 326a159c266SJung-uk Kim 327a159c266SJung-uk Kim switch (ReturnObject->Common.Type) 328a159c266SJung-uk Kim { 329a159c266SJung-uk Kim case ACPI_TYPE_BUFFER: 330a159c266SJung-uk Kim 331a159c266SJung-uk Kim /* This is the expected type. Length should be (at least) 5 DWORDs */ 332a159c266SJung-uk Kim 333a159c266SJung-uk Kim if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE) 334a159c266SJung-uk Kim { 335a159c266SJung-uk Kim return (AE_OK); 336a159c266SJung-uk Kim } 337a159c266SJung-uk Kim 338a159c266SJung-uk Kim /* We can only repair if we have exactly 5 BYTEs */ 339a159c266SJung-uk Kim 340a159c266SJung-uk Kim if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE) 341a159c266SJung-uk Kim { 342895f26a9SJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 343a159c266SJung-uk Kim "Incorrect return buffer length %u, expected %u", 344a159c266SJung-uk Kim ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE)); 345a159c266SJung-uk Kim 346a159c266SJung-uk Kim return (AE_AML_OPERAND_TYPE); 347a159c266SJung-uk Kim } 348a159c266SJung-uk Kim 349a159c266SJung-uk Kim /* Create the new (larger) buffer object */ 350a159c266SJung-uk Kim 351a159c266SJung-uk Kim BufferObject = AcpiUtCreateBufferObject (ACPI_FDE_DWORD_BUFFER_SIZE); 352a159c266SJung-uk Kim if (!BufferObject) 353a159c266SJung-uk Kim { 354a159c266SJung-uk Kim return (AE_NO_MEMORY); 355a159c266SJung-uk Kim } 356a159c266SJung-uk Kim 357a159c266SJung-uk Kim /* Expand each byte to a DWORD */ 358a159c266SJung-uk Kim 359a159c266SJung-uk Kim ByteBuffer = ReturnObject->Buffer.Pointer; 360a159c266SJung-uk Kim DwordBuffer = ACPI_CAST_PTR (UINT32, BufferObject->Buffer.Pointer); 361a159c266SJung-uk Kim 362a159c266SJung-uk Kim for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++) 363a159c266SJung-uk Kim { 364a159c266SJung-uk Kim *DwordBuffer = (UINT32) *ByteBuffer; 365a159c266SJung-uk Kim DwordBuffer++; 366a159c266SJung-uk Kim ByteBuffer++; 367a159c266SJung-uk Kim } 368a159c266SJung-uk Kim 369a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 370a159c266SJung-uk Kim "%s Expanded Byte Buffer to expected DWord Buffer\n", 371895f26a9SJung-uk Kim Info->FullPathname)); 372a159c266SJung-uk Kim break; 373a159c266SJung-uk Kim 374a159c266SJung-uk Kim default: 375a9d8d09cSJung-uk Kim 376a159c266SJung-uk Kim return (AE_AML_OPERAND_TYPE); 377a159c266SJung-uk Kim } 378a159c266SJung-uk Kim 379a159c266SJung-uk Kim /* Delete the original return object, return the new buffer object */ 380a159c266SJung-uk Kim 381a159c266SJung-uk Kim AcpiUtRemoveReference (ReturnObject); 382a159c266SJung-uk Kim *ReturnObjectPtr = BufferObject; 383a159c266SJung-uk Kim 384895f26a9SJung-uk Kim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 385a159c266SJung-uk Kim return (AE_OK); 386a159c266SJung-uk Kim } 387a159c266SJung-uk Kim 388a159c266SJung-uk Kim 389a159c266SJung-uk Kim /****************************************************************************** 390a159c266SJung-uk Kim * 391a159c266SJung-uk Kim * FUNCTION: AcpiNsRepair_CID 392a159c266SJung-uk Kim * 393895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 394a159c266SJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 395a159c266SJung-uk Kim * evaluation of a method or object 396a159c266SJung-uk Kim * 397a159c266SJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 398a159c266SJung-uk Kim * 399a159c266SJung-uk Kim * DESCRIPTION: Repair for the _CID object. If a string, ensure that all 400a159c266SJung-uk Kim * letters are uppercase and that there is no leading asterisk. 401a159c266SJung-uk Kim * If a Package, ensure same for all string elements. 402a159c266SJung-uk Kim * 403a159c266SJung-uk Kim *****************************************************************************/ 404a159c266SJung-uk Kim 405a159c266SJung-uk Kim static ACPI_STATUS 406a159c266SJung-uk Kim AcpiNsRepair_CID ( 407895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 408a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 409a159c266SJung-uk Kim { 410a159c266SJung-uk Kim ACPI_STATUS Status; 411a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 412a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ElementPtr; 413a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *OriginalElement; 414a159c266SJung-uk Kim UINT16 OriginalRefCount; 415a159c266SJung-uk Kim UINT32 i; 416a159c266SJung-uk Kim 417a159c266SJung-uk Kim 418a159c266SJung-uk Kim /* Check for _CID as a simple string */ 419a159c266SJung-uk Kim 420a159c266SJung-uk Kim if (ReturnObject->Common.Type == ACPI_TYPE_STRING) 421a159c266SJung-uk Kim { 422895f26a9SJung-uk Kim Status = AcpiNsRepair_HID (Info, ReturnObjectPtr); 423a159c266SJung-uk Kim return (Status); 424a159c266SJung-uk Kim } 425a159c266SJung-uk Kim 426a159c266SJung-uk Kim /* Exit if not a Package */ 427a159c266SJung-uk Kim 428a159c266SJung-uk Kim if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE) 429a159c266SJung-uk Kim { 430a159c266SJung-uk Kim return (AE_OK); 431a159c266SJung-uk Kim } 432a159c266SJung-uk Kim 433a159c266SJung-uk Kim /* Examine each element of the _CID package */ 434a159c266SJung-uk Kim 435a159c266SJung-uk Kim ElementPtr = ReturnObject->Package.Elements; 436a159c266SJung-uk Kim for (i = 0; i < ReturnObject->Package.Count; i++) 437a159c266SJung-uk Kim { 438a159c266SJung-uk Kim OriginalElement = *ElementPtr; 439a159c266SJung-uk Kim OriginalRefCount = OriginalElement->Common.ReferenceCount; 440a159c266SJung-uk Kim 441895f26a9SJung-uk Kim Status = AcpiNsRepair_HID (Info, ElementPtr); 442a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 443a159c266SJung-uk Kim { 444a159c266SJung-uk Kim return (Status); 445a159c266SJung-uk Kim } 446a159c266SJung-uk Kim 447a159c266SJung-uk Kim /* Take care with reference counts */ 448a159c266SJung-uk Kim 449a159c266SJung-uk Kim if (OriginalElement != *ElementPtr) 450a159c266SJung-uk Kim { 451a159c266SJung-uk Kim /* Element was replaced */ 452a159c266SJung-uk Kim 453a159c266SJung-uk Kim (*ElementPtr)->Common.ReferenceCount = 454a159c266SJung-uk Kim OriginalRefCount; 455a159c266SJung-uk Kim 456a159c266SJung-uk Kim AcpiUtRemoveReference (OriginalElement); 457a159c266SJung-uk Kim } 458a159c266SJung-uk Kim 459a159c266SJung-uk Kim ElementPtr++; 460a159c266SJung-uk Kim } 461a159c266SJung-uk Kim 462a159c266SJung-uk Kim return (AE_OK); 463a159c266SJung-uk Kim } 464a159c266SJung-uk Kim 465a159c266SJung-uk Kim 466a159c266SJung-uk Kim /****************************************************************************** 467a159c266SJung-uk Kim * 468a9d8d09cSJung-uk Kim * FUNCTION: AcpiNsRepair_CST 469a9d8d09cSJung-uk Kim * 470a9d8d09cSJung-uk Kim * PARAMETERS: Info - Method execution information block 471a9d8d09cSJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 472a9d8d09cSJung-uk Kim * evaluation of a method or object 473a9d8d09cSJung-uk Kim * 474a9d8d09cSJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 475a9d8d09cSJung-uk Kim * 476a9d8d09cSJung-uk Kim * DESCRIPTION: Repair for the _CST object: 477a9d8d09cSJung-uk Kim * 1. Sort the list ascending by C state type 478a9d8d09cSJung-uk Kim * 2. Ensure type cannot be zero 479313a0c13SJung-uk Kim * 3. A subpackage count of zero means _CST is meaningless 480313a0c13SJung-uk Kim * 4. Count must match the number of C state subpackages 481a9d8d09cSJung-uk Kim * 482a9d8d09cSJung-uk Kim *****************************************************************************/ 483a9d8d09cSJung-uk Kim 484a9d8d09cSJung-uk Kim static ACPI_STATUS 485a9d8d09cSJung-uk Kim AcpiNsRepair_CST ( 486a9d8d09cSJung-uk Kim ACPI_EVALUATE_INFO *Info, 487a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 488a9d8d09cSJung-uk Kim { 489a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 490a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **OuterElements; 491a9d8d09cSJung-uk Kim UINT32 OuterElementCount; 492a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc; 493a9d8d09cSJung-uk Kim ACPI_STATUS Status; 494a9d8d09cSJung-uk Kim BOOLEAN Removing; 495a9d8d09cSJung-uk Kim UINT32 i; 496a9d8d09cSJung-uk Kim 497a9d8d09cSJung-uk Kim 498a9d8d09cSJung-uk Kim ACPI_FUNCTION_NAME (NsRepair_CST); 499a9d8d09cSJung-uk Kim 500a9d8d09cSJung-uk Kim 501a9d8d09cSJung-uk Kim /* 5028d744e47SJung-uk Kim * Check if the C-state type values are proportional. 503a9d8d09cSJung-uk Kim */ 504a9d8d09cSJung-uk Kim OuterElementCount = ReturnObject->Package.Count - 1; 505a9d8d09cSJung-uk Kim i = 0; 506a9d8d09cSJung-uk Kim while (i < OuterElementCount) 507a9d8d09cSJung-uk Kim { 508a9d8d09cSJung-uk Kim OuterElements = &ReturnObject->Package.Elements[i + 1]; 509a9d8d09cSJung-uk Kim Removing = FALSE; 510a9d8d09cSJung-uk Kim 511a9d8d09cSJung-uk Kim if ((*OuterElements)->Package.Count == 0) 512a9d8d09cSJung-uk Kim { 513a9d8d09cSJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 514a9d8d09cSJung-uk Kim "SubPackage[%u] - removing entry due to zero count", i)); 515a9d8d09cSJung-uk Kim Removing = TRUE; 5168d744e47SJung-uk Kim goto RemoveElement; 517a9d8d09cSJung-uk Kim } 518a9d8d09cSJung-uk Kim 519a9d8d09cSJung-uk Kim ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */ 520a9d8d09cSJung-uk Kim if ((UINT32) ObjDesc->Integer.Value == 0) 521a9d8d09cSJung-uk Kim { 522a9d8d09cSJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 523a9d8d09cSJung-uk Kim "SubPackage[%u] - removing entry due to invalid Type(0)", i)); 524a9d8d09cSJung-uk Kim Removing = TRUE; 525a9d8d09cSJung-uk Kim } 526a9d8d09cSJung-uk Kim 5278d744e47SJung-uk Kim RemoveElement: 528a9d8d09cSJung-uk Kim if (Removing) 529a9d8d09cSJung-uk Kim { 530a9d8d09cSJung-uk Kim AcpiNsRemoveElement (ReturnObject, i + 1); 531a9d8d09cSJung-uk Kim OuterElementCount--; 532a9d8d09cSJung-uk Kim } 533a9d8d09cSJung-uk Kim else 534a9d8d09cSJung-uk Kim { 535a9d8d09cSJung-uk Kim i++; 536a9d8d09cSJung-uk Kim } 537a9d8d09cSJung-uk Kim } 538a9d8d09cSJung-uk Kim 539a9d8d09cSJung-uk Kim /* Update top-level package count, Type "Integer" checked elsewhere */ 540a9d8d09cSJung-uk Kim 541a9d8d09cSJung-uk Kim ObjDesc = ReturnObject->Package.Elements[0]; 542a9d8d09cSJung-uk Kim ObjDesc->Integer.Value = OuterElementCount; 5438d744e47SJung-uk Kim 5448d744e47SJung-uk Kim /* 5458d744e47SJung-uk Kim * Entries (subpackages) in the _CST Package must be sorted by the 5468d744e47SJung-uk Kim * C-state type, in ascending order. 5478d744e47SJung-uk Kim */ 5488d744e47SJung-uk Kim Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1, 5498d744e47SJung-uk Kim ACPI_SORT_ASCENDING, "C-State Type"); 5508d744e47SJung-uk Kim if (ACPI_FAILURE (Status)) 5518d744e47SJung-uk Kim { 5528d744e47SJung-uk Kim return (Status); 5538d744e47SJung-uk Kim } 5548d744e47SJung-uk Kim 555a9d8d09cSJung-uk Kim return (AE_OK); 556a9d8d09cSJung-uk Kim } 557a9d8d09cSJung-uk Kim 558a9d8d09cSJung-uk Kim 559a9d8d09cSJung-uk Kim /****************************************************************************** 560a9d8d09cSJung-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 * 651a9d8d09cSJung-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 * 659a9d8d09cSJung-uk Kim * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed 660a9d8d09cSJung-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 665a9d8d09cSJung-uk Kim AcpiNsRepair_PRT ( 666895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 667a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 668a159c266SJung-uk Kim { 669a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *PackageObject = *ReturnObjectPtr; 670a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **TopObjectList; 671a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **SubObjectList; 672a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc; 673313a0c13SJung-uk Kim ACPI_OPERAND_OBJECT *SubPackage; 674a9d8d09cSJung-uk Kim UINT32 ElementCount; 675a9d8d09cSJung-uk Kim UINT32 Index; 676a159c266SJung-uk Kim 677a159c266SJung-uk Kim 678a9d8d09cSJung-uk Kim /* Each element in the _PRT package is a subpackage */ 679a9d8d09cSJung-uk Kim 680a9d8d09cSJung-uk Kim TopObjectList = PackageObject->Package.Elements; 681a9d8d09cSJung-uk Kim ElementCount = PackageObject->Package.Count; 682a9d8d09cSJung-uk Kim 683313a0c13SJung-uk Kim /* Examine each subpackage */ 684313a0c13SJung-uk Kim 685313a0c13SJung-uk Kim for (Index = 0; Index < ElementCount; Index++, TopObjectList++) 686a9d8d09cSJung-uk Kim { 687313a0c13SJung-uk Kim SubPackage = *TopObjectList; 688313a0c13SJung-uk Kim SubObjectList = SubPackage->Package.Elements; 689313a0c13SJung-uk Kim 690313a0c13SJung-uk Kim /* Check for minimum required element count */ 691313a0c13SJung-uk Kim 692313a0c13SJung-uk Kim if (SubPackage->Package.Count < 4) 693313a0c13SJung-uk Kim { 694313a0c13SJung-uk Kim continue; 695313a0c13SJung-uk Kim } 696a9d8d09cSJung-uk Kim 697a159c266SJung-uk Kim /* 698a9d8d09cSJung-uk Kim * If the BIOS has erroneously reversed the _PRT SourceName (index 2) 699a9d8d09cSJung-uk Kim * and the SourceIndex (index 3), fix it. _PRT is important enough to 700a9d8d09cSJung-uk Kim * workaround this BIOS error. This also provides compatibility with 701a9d8d09cSJung-uk Kim * other ACPI implementations. 702a159c266SJung-uk Kim */ 703a9d8d09cSJung-uk Kim ObjDesc = SubObjectList[3]; 704a9d8d09cSJung-uk Kim if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)) 705a159c266SJung-uk Kim { 706a9d8d09cSJung-uk Kim SubObjectList[3] = SubObjectList[2]; 707a9d8d09cSJung-uk Kim SubObjectList[2] = ObjDesc; 708a9d8d09cSJung-uk Kim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 709a9d8d09cSJung-uk Kim 710313a0c13SJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, 711313a0c13SJung-uk Kim Info->FullPathname, Info->NodeFlags, 712a9d8d09cSJung-uk Kim "PRT[%X]: Fixed reversed SourceName and SourceIndex", 713a9d8d09cSJung-uk Kim Index)); 714a159c266SJung-uk Kim } 715a9d8d09cSJung-uk Kim } 716a9d8d09cSJung-uk Kim 717a9d8d09cSJung-uk Kim return (AE_OK); 718a159c266SJung-uk Kim } 719a159c266SJung-uk Kim 720a159c266SJung-uk Kim 721a159c266SJung-uk Kim /****************************************************************************** 722a159c266SJung-uk Kim * 723a159c266SJung-uk Kim * FUNCTION: AcpiNsRepair_PSS 724a159c266SJung-uk Kim * 725895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 726a159c266SJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 727a159c266SJung-uk Kim * evaluation of a method or object 728a159c266SJung-uk Kim * 729a159c266SJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 730a159c266SJung-uk Kim * 731a159c266SJung-uk Kim * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list 732a159c266SJung-uk Kim * by the CPU frequencies. Check that the power dissipation values 733a159c266SJung-uk Kim * are all proportional to CPU frequency (i.e., sorting by 734a159c266SJung-uk Kim * frequency should be the same as sorting by power.) 735a159c266SJung-uk Kim * 736a159c266SJung-uk Kim *****************************************************************************/ 737a159c266SJung-uk Kim 738a159c266SJung-uk Kim static ACPI_STATUS 739a159c266SJung-uk Kim AcpiNsRepair_PSS ( 740895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 741a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 742a159c266SJung-uk Kim { 743a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 744a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **OuterElements; 745a159c266SJung-uk Kim UINT32 OuterElementCount; 746a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **Elements; 747a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc; 748a159c266SJung-uk Kim UINT32 PreviousValue; 749a159c266SJung-uk Kim ACPI_STATUS Status; 750a159c266SJung-uk Kim UINT32 i; 751a159c266SJung-uk Kim 752a159c266SJung-uk Kim 753a159c266SJung-uk Kim /* 754313a0c13SJung-uk Kim * Entries (subpackages) in the _PSS Package must be sorted by power 755a159c266SJung-uk Kim * dissipation, in descending order. If it appears that the list is 756a159c266SJung-uk Kim * incorrectly sorted, sort it. We sort by CpuFrequency, since this 757a159c266SJung-uk Kim * should be proportional to the power. 758a159c266SJung-uk Kim */ 759a9d8d09cSJung-uk Kim Status =AcpiNsCheckSortedList (Info, ReturnObject, 0, 6, 0, 760a159c266SJung-uk Kim ACPI_SORT_DESCENDING, "CpuFrequency"); 761a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 762a159c266SJung-uk Kim { 763a159c266SJung-uk Kim return (Status); 764a159c266SJung-uk Kim } 765a159c266SJung-uk Kim 766a159c266SJung-uk Kim /* 767a159c266SJung-uk Kim * We now know the list is correctly sorted by CPU frequency. Check if 768a159c266SJung-uk Kim * the power dissipation values are proportional. 769a159c266SJung-uk Kim */ 770a159c266SJung-uk Kim PreviousValue = ACPI_UINT32_MAX; 771a159c266SJung-uk Kim OuterElements = ReturnObject->Package.Elements; 772a159c266SJung-uk Kim OuterElementCount = ReturnObject->Package.Count; 773a159c266SJung-uk Kim 774a159c266SJung-uk Kim for (i = 0; i < OuterElementCount; i++) 775a159c266SJung-uk Kim { 776a159c266SJung-uk Kim Elements = (*OuterElements)->Package.Elements; 777a159c266SJung-uk Kim ObjDesc = Elements[1]; /* Index1 = PowerDissipation */ 778a159c266SJung-uk Kim 779a159c266SJung-uk Kim if ((UINT32) ObjDesc->Integer.Value > PreviousValue) 780a159c266SJung-uk Kim { 781895f26a9SJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 782a159c266SJung-uk Kim "SubPackage[%u,%u] - suspicious power dissipation values", 783a159c266SJung-uk Kim i-1, i)); 784a159c266SJung-uk Kim } 785a159c266SJung-uk Kim 786a159c266SJung-uk Kim PreviousValue = (UINT32) ObjDesc->Integer.Value; 787a159c266SJung-uk Kim OuterElements++; 788a159c266SJung-uk Kim } 789a159c266SJung-uk Kim 790a159c266SJung-uk Kim return (AE_OK); 791a159c266SJung-uk Kim } 792a159c266SJung-uk Kim 793a159c266SJung-uk Kim 794a159c266SJung-uk Kim /****************************************************************************** 795a159c266SJung-uk Kim * 796a9d8d09cSJung-uk Kim * FUNCTION: AcpiNsRepair_TSS 797a9d8d09cSJung-uk Kim * 798a9d8d09cSJung-uk Kim * PARAMETERS: Info - Method execution information block 799a9d8d09cSJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 800a9d8d09cSJung-uk Kim * evaluation of a method or object 801a9d8d09cSJung-uk Kim * 802a9d8d09cSJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 803a9d8d09cSJung-uk Kim * 804a9d8d09cSJung-uk Kim * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list 805a9d8d09cSJung-uk Kim * descending by the power dissipation values. 806a9d8d09cSJung-uk Kim * 807a9d8d09cSJung-uk Kim *****************************************************************************/ 808a9d8d09cSJung-uk Kim 809a9d8d09cSJung-uk Kim static ACPI_STATUS 810a9d8d09cSJung-uk Kim AcpiNsRepair_TSS ( 811a9d8d09cSJung-uk Kim ACPI_EVALUATE_INFO *Info, 812a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 813a9d8d09cSJung-uk Kim { 814a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 815a9d8d09cSJung-uk Kim ACPI_STATUS Status; 816a9d8d09cSJung-uk Kim ACPI_NAMESPACE_NODE *Node; 817a9d8d09cSJung-uk Kim 818a9d8d09cSJung-uk Kim 819a9d8d09cSJung-uk Kim /* 820a9d8d09cSJung-uk Kim * We can only sort the _TSS return package if there is no _PSS in the 821a9d8d09cSJung-uk Kim * same scope. This is because if _PSS is present, the ACPI specification 822a9d8d09cSJung-uk Kim * dictates that the _TSS Power Dissipation field is to be ignored, and 823a9d8d09cSJung-uk Kim * therefore some BIOSs leave garbage values in the _TSS Power field(s). 824a9d8d09cSJung-uk Kim * In this case, it is best to just return the _TSS package as-is. 825a9d8d09cSJung-uk Kim * (May, 2011) 826a9d8d09cSJung-uk Kim */ 827a9d8d09cSJung-uk Kim Status = AcpiNsGetNode (Info->Node, "^_PSS", 828a9d8d09cSJung-uk Kim ACPI_NS_NO_UPSEARCH, &Node); 829a9d8d09cSJung-uk Kim if (ACPI_SUCCESS (Status)) 830a9d8d09cSJung-uk Kim { 831a9d8d09cSJung-uk Kim return (AE_OK); 832a9d8d09cSJung-uk Kim } 833a9d8d09cSJung-uk Kim 834a9d8d09cSJung-uk Kim Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1, 835a9d8d09cSJung-uk Kim ACPI_SORT_DESCENDING, "PowerDissipation"); 836a9d8d09cSJung-uk Kim 837a9d8d09cSJung-uk Kim return (Status); 838a9d8d09cSJung-uk Kim } 839a9d8d09cSJung-uk Kim 840a9d8d09cSJung-uk Kim 841a9d8d09cSJung-uk Kim /****************************************************************************** 842a9d8d09cSJung-uk Kim * 843a159c266SJung-uk Kim * FUNCTION: AcpiNsCheckSortedList 844a159c266SJung-uk Kim * 845895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 846a159c266SJung-uk Kim * ReturnObject - Pointer to the top-level returned object 847313a0c13SJung-uk Kim * StartIndex - Index of the first subpackage 848313a0c13SJung-uk Kim * ExpectedCount - Minimum length of each subpackage 849313a0c13SJung-uk Kim * SortIndex - Subpackage entry to sort on 850a159c266SJung-uk Kim * SortDirection - Ascending or descending 851a159c266SJung-uk Kim * SortKeyName - Name of the SortIndex field 852a159c266SJung-uk Kim * 853a159c266SJung-uk Kim * RETURN: Status. AE_OK if the list is valid and is sorted correctly or 854a159c266SJung-uk Kim * has been repaired by sorting the list. 855a159c266SJung-uk Kim * 856a159c266SJung-uk Kim * DESCRIPTION: Check if the package list is valid and sorted correctly by the 857a159c266SJung-uk Kim * SortIndex. If not, then sort the list. 858a159c266SJung-uk Kim * 859a159c266SJung-uk Kim *****************************************************************************/ 860a159c266SJung-uk Kim 861a159c266SJung-uk Kim static ACPI_STATUS 862a159c266SJung-uk Kim AcpiNsCheckSortedList ( 863895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 864a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject, 865a9d8d09cSJung-uk Kim UINT32 StartIndex, 866a159c266SJung-uk Kim UINT32 ExpectedCount, 867a159c266SJung-uk Kim UINT32 SortIndex, 868a159c266SJung-uk Kim UINT8 SortDirection, 869a159c266SJung-uk Kim char *SortKeyName) 870a159c266SJung-uk Kim { 871a159c266SJung-uk Kim UINT32 OuterElementCount; 872a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **OuterElements; 873a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **Elements; 874a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc; 875a159c266SJung-uk Kim UINT32 i; 876a159c266SJung-uk Kim UINT32 PreviousValue; 877a159c266SJung-uk Kim 878a159c266SJung-uk Kim 879a159c266SJung-uk Kim ACPI_FUNCTION_NAME (NsCheckSortedList); 880a159c266SJung-uk Kim 881a159c266SJung-uk Kim 882a159c266SJung-uk Kim /* The top-level object must be a package */ 883a159c266SJung-uk Kim 884a159c266SJung-uk Kim if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE) 885a159c266SJung-uk Kim { 886a159c266SJung-uk Kim return (AE_AML_OPERAND_TYPE); 887a159c266SJung-uk Kim } 888a159c266SJung-uk Kim 889a159c266SJung-uk Kim /* 890313a0c13SJung-uk Kim * NOTE: assumes list of subpackages contains no NULL elements. 891a159c266SJung-uk Kim * Any NULL elements should have been removed by earlier call 892a159c266SJung-uk Kim * to AcpiNsRemoveNullElements. 893a159c266SJung-uk Kim */ 894a159c266SJung-uk Kim OuterElementCount = ReturnObject->Package.Count; 895a9d8d09cSJung-uk Kim if (!OuterElementCount || StartIndex >= OuterElementCount) 896a159c266SJung-uk Kim { 897a159c266SJung-uk Kim return (AE_AML_PACKAGE_LIMIT); 898a159c266SJung-uk Kim } 899a159c266SJung-uk Kim 900a9d8d09cSJung-uk Kim OuterElements = &ReturnObject->Package.Elements[StartIndex]; 901a9d8d09cSJung-uk Kim OuterElementCount -= StartIndex; 902a9d8d09cSJung-uk Kim 903a159c266SJung-uk Kim PreviousValue = 0; 904a159c266SJung-uk Kim if (SortDirection == ACPI_SORT_DESCENDING) 905a159c266SJung-uk Kim { 906a159c266SJung-uk Kim PreviousValue = ACPI_UINT32_MAX; 907a159c266SJung-uk Kim } 908a159c266SJung-uk Kim 909a159c266SJung-uk Kim /* Examine each subpackage */ 910a159c266SJung-uk Kim 911a159c266SJung-uk Kim for (i = 0; i < OuterElementCount; i++) 912a159c266SJung-uk Kim { 913a159c266SJung-uk Kim /* Each element of the top-level package must also be a package */ 914a159c266SJung-uk Kim 915a159c266SJung-uk Kim if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE) 916a159c266SJung-uk Kim { 917a159c266SJung-uk Kim return (AE_AML_OPERAND_TYPE); 918a159c266SJung-uk Kim } 919a159c266SJung-uk Kim 920313a0c13SJung-uk Kim /* Each subpackage must have the minimum length */ 921a159c266SJung-uk Kim 922a159c266SJung-uk Kim if ((*OuterElements)->Package.Count < ExpectedCount) 923a159c266SJung-uk Kim { 924a159c266SJung-uk Kim return (AE_AML_PACKAGE_LIMIT); 925a159c266SJung-uk Kim } 926a159c266SJung-uk Kim 927a159c266SJung-uk Kim Elements = (*OuterElements)->Package.Elements; 928a159c266SJung-uk Kim ObjDesc = Elements[SortIndex]; 929a159c266SJung-uk Kim 930a159c266SJung-uk Kim if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER) 931a159c266SJung-uk Kim { 932a159c266SJung-uk Kim return (AE_AML_OPERAND_TYPE); 933a159c266SJung-uk Kim } 934a159c266SJung-uk Kim 935a159c266SJung-uk Kim /* 936a159c266SJung-uk Kim * The list must be sorted in the specified order. If we detect a 937a159c266SJung-uk Kim * discrepancy, sort the entire list. 938a159c266SJung-uk Kim */ 939a159c266SJung-uk Kim if (((SortDirection == ACPI_SORT_ASCENDING) && 940a159c266SJung-uk Kim (ObjDesc->Integer.Value < PreviousValue)) || 941a159c266SJung-uk Kim ((SortDirection == ACPI_SORT_DESCENDING) && 942a159c266SJung-uk Kim (ObjDesc->Integer.Value > PreviousValue))) 943a159c266SJung-uk Kim { 944a9d8d09cSJung-uk Kim AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex], 945a159c266SJung-uk Kim OuterElementCount, SortIndex, SortDirection); 946a159c266SJung-uk Kim 947895f26a9SJung-uk Kim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 948a159c266SJung-uk Kim 949a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 950a159c266SJung-uk Kim "%s: Repaired unsorted list - now sorted by %s\n", 951895f26a9SJung-uk Kim Info->FullPathname, SortKeyName)); 952a159c266SJung-uk Kim return (AE_OK); 953a159c266SJung-uk Kim } 954a159c266SJung-uk Kim 955a159c266SJung-uk Kim PreviousValue = (UINT32) ObjDesc->Integer.Value; 956a159c266SJung-uk Kim OuterElements++; 957a159c266SJung-uk Kim } 958a159c266SJung-uk Kim 959a159c266SJung-uk Kim return (AE_OK); 960a159c266SJung-uk Kim } 961a159c266SJung-uk Kim 962a159c266SJung-uk Kim 963a159c266SJung-uk Kim /****************************************************************************** 964a159c266SJung-uk Kim * 965a159c266SJung-uk Kim * FUNCTION: AcpiNsSortList 966a159c266SJung-uk Kim * 967a159c266SJung-uk Kim * PARAMETERS: Elements - Package object element list 968a159c266SJung-uk Kim * Count - Element count for above 969a159c266SJung-uk Kim * Index - Sort by which package element 970a159c266SJung-uk Kim * SortDirection - Ascending or Descending sort 971a159c266SJung-uk Kim * 972a159c266SJung-uk Kim * RETURN: None 973a159c266SJung-uk Kim * 974a159c266SJung-uk Kim * DESCRIPTION: Sort the objects that are in a package element list. 975a159c266SJung-uk Kim * 976a159c266SJung-uk Kim * NOTE: Assumes that all NULL elements have been removed from the package, 977a159c266SJung-uk Kim * and that all elements have been verified to be of type Integer. 978a159c266SJung-uk Kim * 979a159c266SJung-uk Kim *****************************************************************************/ 980a159c266SJung-uk Kim 981a159c266SJung-uk Kim static void 982a159c266SJung-uk Kim AcpiNsSortList ( 983a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **Elements, 984a159c266SJung-uk Kim UINT32 Count, 985a159c266SJung-uk Kim UINT32 Index, 986a159c266SJung-uk Kim UINT8 SortDirection) 987a159c266SJung-uk Kim { 988a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc1; 989a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc2; 990a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *TempObj; 991a159c266SJung-uk Kim UINT32 i; 992a159c266SJung-uk Kim UINT32 j; 993a159c266SJung-uk Kim 994a159c266SJung-uk Kim 995a159c266SJung-uk Kim /* Simple bubble sort */ 996a159c266SJung-uk Kim 997a159c266SJung-uk Kim for (i = 1; i < Count; i++) 998a159c266SJung-uk Kim { 999a159c266SJung-uk Kim for (j = (Count - 1); j >= i; j--) 1000a159c266SJung-uk Kim { 1001a159c266SJung-uk Kim ObjDesc1 = Elements[j-1]->Package.Elements[Index]; 1002a159c266SJung-uk Kim ObjDesc2 = Elements[j]->Package.Elements[Index]; 1003a159c266SJung-uk Kim 1004a159c266SJung-uk Kim if (((SortDirection == ACPI_SORT_ASCENDING) && 1005a159c266SJung-uk Kim (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) || 1006a159c266SJung-uk Kim 1007a159c266SJung-uk Kim ((SortDirection == ACPI_SORT_DESCENDING) && 1008a159c266SJung-uk Kim (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value))) 1009a159c266SJung-uk Kim { 1010a159c266SJung-uk Kim TempObj = Elements[j-1]; 1011a159c266SJung-uk Kim Elements[j-1] = Elements[j]; 1012a159c266SJung-uk Kim Elements[j] = TempObj; 1013a159c266SJung-uk Kim } 1014a159c266SJung-uk Kim } 1015a159c266SJung-uk Kim } 1016a159c266SJung-uk Kim } 1017a9d8d09cSJung-uk Kim 1018a9d8d09cSJung-uk Kim 1019a9d8d09cSJung-uk Kim /****************************************************************************** 1020a9d8d09cSJung-uk Kim * 1021a9d8d09cSJung-uk Kim * FUNCTION: AcpiNsRemoveElement 1022a9d8d09cSJung-uk Kim * 1023a9d8d09cSJung-uk Kim * PARAMETERS: ObjDesc - Package object element list 1024a9d8d09cSJung-uk Kim * Index - Index of element to remove 1025a9d8d09cSJung-uk Kim * 1026a9d8d09cSJung-uk Kim * RETURN: None 1027a9d8d09cSJung-uk Kim * 1028a9d8d09cSJung-uk Kim * DESCRIPTION: Remove the requested element of a package and delete it. 1029a9d8d09cSJung-uk Kim * 1030a9d8d09cSJung-uk Kim *****************************************************************************/ 1031a9d8d09cSJung-uk Kim 1032a9d8d09cSJung-uk Kim static void 1033a9d8d09cSJung-uk Kim AcpiNsRemoveElement ( 1034a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc, 1035a9d8d09cSJung-uk Kim UINT32 Index) 1036a9d8d09cSJung-uk Kim { 1037a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **Source; 1038a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **Dest; 1039a9d8d09cSJung-uk Kim UINT32 Count; 1040a9d8d09cSJung-uk Kim UINT32 NewCount; 1041a9d8d09cSJung-uk Kim UINT32 i; 1042a9d8d09cSJung-uk Kim 1043a9d8d09cSJung-uk Kim 1044a9d8d09cSJung-uk Kim ACPI_FUNCTION_NAME (NsRemoveElement); 1045a9d8d09cSJung-uk Kim 1046a9d8d09cSJung-uk Kim 1047a9d8d09cSJung-uk Kim Count = ObjDesc->Package.Count; 1048a9d8d09cSJung-uk Kim NewCount = Count - 1; 1049a9d8d09cSJung-uk Kim 1050a9d8d09cSJung-uk Kim Source = ObjDesc->Package.Elements; 1051a9d8d09cSJung-uk Kim Dest = Source; 1052a9d8d09cSJung-uk Kim 1053a9d8d09cSJung-uk Kim /* Examine all elements of the package object, remove matched index */ 1054a9d8d09cSJung-uk Kim 1055a9d8d09cSJung-uk Kim for (i = 0; i < Count; i++) 1056a9d8d09cSJung-uk Kim { 1057a9d8d09cSJung-uk Kim if (i == Index) 1058a9d8d09cSJung-uk Kim { 1059a9d8d09cSJung-uk Kim AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */ 1060a9d8d09cSJung-uk Kim AcpiUtRemoveReference (*Source); 1061a9d8d09cSJung-uk Kim } 1062a9d8d09cSJung-uk Kim else 1063a9d8d09cSJung-uk Kim { 1064a9d8d09cSJung-uk Kim *Dest = *Source; 1065a9d8d09cSJung-uk Kim Dest++; 1066a9d8d09cSJung-uk Kim } 1067a9d8d09cSJung-uk Kim Source++; 1068a9d8d09cSJung-uk Kim } 1069a9d8d09cSJung-uk Kim 1070a9d8d09cSJung-uk Kim /* NULL terminate list and update the package count */ 1071a9d8d09cSJung-uk Kim 1072a9d8d09cSJung-uk Kim *Dest = NULL; 1073a9d8d09cSJung-uk Kim ObjDesc->Package.Count = NewCount; 1074a9d8d09cSJung-uk Kim } 1075