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*f8146b88SJung-uk Kim * Copyright (C) 2000 - 2016, 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 } 257*f8146b88SJung-uk Kim 258a159c266SJung-uk Kim ThisName++; 259a159c266SJung-uk Kim } 260a159c266SJung-uk Kim 261a159c266SJung-uk Kim return (NULL); /* Not found */ 262a159c266SJung-uk Kim } 263a159c266SJung-uk Kim 264a159c266SJung-uk Kim 265a159c266SJung-uk Kim /****************************************************************************** 266a159c266SJung-uk Kim * 267a159c266SJung-uk Kim * FUNCTION: AcpiNsRepair_ALR 268a159c266SJung-uk Kim * 269895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 270a159c266SJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 271a159c266SJung-uk Kim * evaluation of a method or object 272a159c266SJung-uk Kim * 273a159c266SJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 274a159c266SJung-uk Kim * 275a159c266SJung-uk Kim * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list 276a159c266SJung-uk Kim * ascending by the ambient illuminance values. 277a159c266SJung-uk Kim * 278a159c266SJung-uk Kim *****************************************************************************/ 279a159c266SJung-uk Kim 280a159c266SJung-uk Kim static ACPI_STATUS 281a159c266SJung-uk Kim AcpiNsRepair_ALR ( 282895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 283a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 284a159c266SJung-uk Kim { 285a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 286a159c266SJung-uk Kim ACPI_STATUS Status; 287a159c266SJung-uk Kim 288a159c266SJung-uk Kim 289a9d8d09cSJung-uk Kim Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 2, 1, 290a159c266SJung-uk Kim ACPI_SORT_ASCENDING, "AmbientIlluminance"); 291a159c266SJung-uk Kim 292a159c266SJung-uk Kim return (Status); 293a159c266SJung-uk Kim } 294a159c266SJung-uk Kim 295a159c266SJung-uk Kim 296a159c266SJung-uk Kim /****************************************************************************** 297a159c266SJung-uk Kim * 298a159c266SJung-uk Kim * FUNCTION: AcpiNsRepair_FDE 299a159c266SJung-uk Kim * 300895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 301a159c266SJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 302a159c266SJung-uk Kim * evaluation of a method or object 303a159c266SJung-uk Kim * 304a159c266SJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 305a159c266SJung-uk Kim * 306a159c266SJung-uk Kim * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return 307a159c266SJung-uk Kim * value is a Buffer of 5 DWORDs. This function repairs a common 308a159c266SJung-uk Kim * problem where the return value is a Buffer of BYTEs, not 309a159c266SJung-uk Kim * DWORDs. 310a159c266SJung-uk Kim * 311a159c266SJung-uk Kim *****************************************************************************/ 312a159c266SJung-uk Kim 313a159c266SJung-uk Kim static ACPI_STATUS 314a159c266SJung-uk Kim AcpiNsRepair_FDE ( 315895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 316a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 317a159c266SJung-uk Kim { 318a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 319a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *BufferObject; 320a159c266SJung-uk Kim UINT8 *ByteBuffer; 321a159c266SJung-uk Kim UINT32 *DwordBuffer; 322a159c266SJung-uk Kim UINT32 i; 323a159c266SJung-uk Kim 324a159c266SJung-uk Kim 325a159c266SJung-uk Kim ACPI_FUNCTION_NAME (NsRepair_FDE); 326a159c266SJung-uk Kim 327a159c266SJung-uk Kim 328a159c266SJung-uk Kim switch (ReturnObject->Common.Type) 329a159c266SJung-uk Kim { 330a159c266SJung-uk Kim case ACPI_TYPE_BUFFER: 331a159c266SJung-uk Kim 332a159c266SJung-uk Kim /* This is the expected type. Length should be (at least) 5 DWORDs */ 333a159c266SJung-uk Kim 334a159c266SJung-uk Kim if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE) 335a159c266SJung-uk Kim { 336a159c266SJung-uk Kim return (AE_OK); 337a159c266SJung-uk Kim } 338a159c266SJung-uk Kim 339a159c266SJung-uk Kim /* We can only repair if we have exactly 5 BYTEs */ 340a159c266SJung-uk Kim 341a159c266SJung-uk Kim if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE) 342a159c266SJung-uk Kim { 343*f8146b88SJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, 344*f8146b88SJung-uk Kim 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 353*f8146b88SJung-uk Kim BufferObject = AcpiUtCreateBufferObject ( 354*f8146b88SJung-uk Kim ACPI_FDE_DWORD_BUFFER_SIZE); 355a159c266SJung-uk Kim if (!BufferObject) 356a159c266SJung-uk Kim { 357a159c266SJung-uk Kim return (AE_NO_MEMORY); 358a159c266SJung-uk Kim } 359a159c266SJung-uk Kim 360a159c266SJung-uk Kim /* Expand each byte to a DWORD */ 361a159c266SJung-uk Kim 362a159c266SJung-uk Kim ByteBuffer = ReturnObject->Buffer.Pointer; 363*f8146b88SJung-uk Kim DwordBuffer = ACPI_CAST_PTR (UINT32, 364*f8146b88SJung-uk Kim BufferObject->Buffer.Pointer); 365a159c266SJung-uk Kim 366a159c266SJung-uk Kim for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++) 367a159c266SJung-uk Kim { 368a159c266SJung-uk Kim *DwordBuffer = (UINT32) *ByteBuffer; 369a159c266SJung-uk Kim DwordBuffer++; 370a159c266SJung-uk Kim ByteBuffer++; 371a159c266SJung-uk Kim } 372a159c266SJung-uk Kim 373a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 374a159c266SJung-uk Kim "%s Expanded Byte Buffer to expected DWord Buffer\n", 375895f26a9SJung-uk Kim Info->FullPathname)); 376a159c266SJung-uk Kim break; 377a159c266SJung-uk Kim 378a159c266SJung-uk Kim default: 379a9d8d09cSJung-uk Kim 380a159c266SJung-uk Kim return (AE_AML_OPERAND_TYPE); 381a159c266SJung-uk Kim } 382a159c266SJung-uk Kim 383a159c266SJung-uk Kim /* Delete the original return object, return the new buffer object */ 384a159c266SJung-uk Kim 385a159c266SJung-uk Kim AcpiUtRemoveReference (ReturnObject); 386a159c266SJung-uk Kim *ReturnObjectPtr = BufferObject; 387a159c266SJung-uk Kim 388895f26a9SJung-uk Kim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 389a159c266SJung-uk Kim return (AE_OK); 390a159c266SJung-uk Kim } 391a159c266SJung-uk Kim 392a159c266SJung-uk Kim 393a159c266SJung-uk Kim /****************************************************************************** 394a159c266SJung-uk Kim * 395a159c266SJung-uk Kim * FUNCTION: AcpiNsRepair_CID 396a159c266SJung-uk Kim * 397895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 398a159c266SJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 399a159c266SJung-uk Kim * evaluation of a method or object 400a159c266SJung-uk Kim * 401a159c266SJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 402a159c266SJung-uk Kim * 403a159c266SJung-uk Kim * DESCRIPTION: Repair for the _CID object. If a string, ensure that all 404a159c266SJung-uk Kim * letters are uppercase and that there is no leading asterisk. 405a159c266SJung-uk Kim * If a Package, ensure same for all string elements. 406a159c266SJung-uk Kim * 407a159c266SJung-uk Kim *****************************************************************************/ 408a159c266SJung-uk Kim 409a159c266SJung-uk Kim static ACPI_STATUS 410a159c266SJung-uk Kim AcpiNsRepair_CID ( 411895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 412a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 413a159c266SJung-uk Kim { 414a159c266SJung-uk Kim ACPI_STATUS Status; 415a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 416a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ElementPtr; 417a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *OriginalElement; 418a159c266SJung-uk Kim UINT16 OriginalRefCount; 419a159c266SJung-uk Kim UINT32 i; 420a159c266SJung-uk Kim 421a159c266SJung-uk Kim 422a159c266SJung-uk Kim /* Check for _CID as a simple string */ 423a159c266SJung-uk Kim 424a159c266SJung-uk Kim if (ReturnObject->Common.Type == ACPI_TYPE_STRING) 425a159c266SJung-uk Kim { 426895f26a9SJung-uk Kim Status = AcpiNsRepair_HID (Info, ReturnObjectPtr); 427a159c266SJung-uk Kim return (Status); 428a159c266SJung-uk Kim } 429a159c266SJung-uk Kim 430a159c266SJung-uk Kim /* Exit if not a Package */ 431a159c266SJung-uk Kim 432a159c266SJung-uk Kim if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE) 433a159c266SJung-uk Kim { 434a159c266SJung-uk Kim return (AE_OK); 435a159c266SJung-uk Kim } 436a159c266SJung-uk Kim 437a159c266SJung-uk Kim /* Examine each element of the _CID package */ 438a159c266SJung-uk Kim 439a159c266SJung-uk Kim ElementPtr = ReturnObject->Package.Elements; 440a159c266SJung-uk Kim for (i = 0; i < ReturnObject->Package.Count; i++) 441a159c266SJung-uk Kim { 442a159c266SJung-uk Kim OriginalElement = *ElementPtr; 443a159c266SJung-uk Kim OriginalRefCount = OriginalElement->Common.ReferenceCount; 444a159c266SJung-uk Kim 445895f26a9SJung-uk Kim Status = AcpiNsRepair_HID (Info, ElementPtr); 446a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 447a159c266SJung-uk Kim { 448a159c266SJung-uk Kim return (Status); 449a159c266SJung-uk Kim } 450a159c266SJung-uk Kim 451a159c266SJung-uk Kim /* Take care with reference counts */ 452a159c266SJung-uk Kim 453a159c266SJung-uk Kim if (OriginalElement != *ElementPtr) 454a159c266SJung-uk Kim { 455a159c266SJung-uk Kim /* Element was replaced */ 456a159c266SJung-uk Kim 457a159c266SJung-uk Kim (*ElementPtr)->Common.ReferenceCount = 458a159c266SJung-uk Kim OriginalRefCount; 459a159c266SJung-uk Kim 460a159c266SJung-uk Kim AcpiUtRemoveReference (OriginalElement); 461a159c266SJung-uk Kim } 462a159c266SJung-uk Kim 463a159c266SJung-uk Kim ElementPtr++; 464a159c266SJung-uk Kim } 465a159c266SJung-uk Kim 466a159c266SJung-uk Kim return (AE_OK); 467a159c266SJung-uk Kim } 468a159c266SJung-uk Kim 469a159c266SJung-uk Kim 470a159c266SJung-uk Kim /****************************************************************************** 471a159c266SJung-uk Kim * 472a9d8d09cSJung-uk Kim * FUNCTION: AcpiNsRepair_CST 473a9d8d09cSJung-uk Kim * 474a9d8d09cSJung-uk Kim * PARAMETERS: Info - Method execution information block 475a9d8d09cSJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 476a9d8d09cSJung-uk Kim * evaluation of a method or object 477a9d8d09cSJung-uk Kim * 478a9d8d09cSJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 479a9d8d09cSJung-uk Kim * 480a9d8d09cSJung-uk Kim * DESCRIPTION: Repair for the _CST object: 481a9d8d09cSJung-uk Kim * 1. Sort the list ascending by C state type 482a9d8d09cSJung-uk Kim * 2. Ensure type cannot be zero 483313a0c13SJung-uk Kim * 3. A subpackage count of zero means _CST is meaningless 484313a0c13SJung-uk Kim * 4. Count must match the number of C state subpackages 485a9d8d09cSJung-uk Kim * 486a9d8d09cSJung-uk Kim *****************************************************************************/ 487a9d8d09cSJung-uk Kim 488a9d8d09cSJung-uk Kim static ACPI_STATUS 489a9d8d09cSJung-uk Kim AcpiNsRepair_CST ( 490a9d8d09cSJung-uk Kim ACPI_EVALUATE_INFO *Info, 491a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 492a9d8d09cSJung-uk Kim { 493a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 494a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **OuterElements; 495a9d8d09cSJung-uk Kim UINT32 OuterElementCount; 496a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc; 497a9d8d09cSJung-uk Kim ACPI_STATUS Status; 498a9d8d09cSJung-uk Kim BOOLEAN Removing; 499a9d8d09cSJung-uk Kim UINT32 i; 500a9d8d09cSJung-uk Kim 501a9d8d09cSJung-uk Kim 502a9d8d09cSJung-uk Kim ACPI_FUNCTION_NAME (NsRepair_CST); 503a9d8d09cSJung-uk Kim 504a9d8d09cSJung-uk Kim 505a9d8d09cSJung-uk Kim /* 5068d744e47SJung-uk Kim * Check if the C-state type values are proportional. 507a9d8d09cSJung-uk Kim */ 508a9d8d09cSJung-uk Kim OuterElementCount = ReturnObject->Package.Count - 1; 509a9d8d09cSJung-uk Kim i = 0; 510a9d8d09cSJung-uk Kim while (i < OuterElementCount) 511a9d8d09cSJung-uk Kim { 512a9d8d09cSJung-uk Kim OuterElements = &ReturnObject->Package.Elements[i + 1]; 513a9d8d09cSJung-uk Kim Removing = FALSE; 514a9d8d09cSJung-uk Kim 515a9d8d09cSJung-uk Kim if ((*OuterElements)->Package.Count == 0) 516a9d8d09cSJung-uk Kim { 517*f8146b88SJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, 518*f8146b88SJung-uk Kim Info->FullPathname, Info->NodeFlags, 519a9d8d09cSJung-uk Kim "SubPackage[%u] - removing entry due to zero count", i)); 520a9d8d09cSJung-uk Kim Removing = TRUE; 5218d744e47SJung-uk Kim goto RemoveElement; 522a9d8d09cSJung-uk Kim } 523a9d8d09cSJung-uk Kim 524a9d8d09cSJung-uk Kim ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */ 525a9d8d09cSJung-uk Kim if ((UINT32) ObjDesc->Integer.Value == 0) 526a9d8d09cSJung-uk Kim { 527*f8146b88SJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, 528*f8146b88SJung-uk Kim Info->FullPathname, Info->NodeFlags, 529a9d8d09cSJung-uk Kim "SubPackage[%u] - removing entry due to invalid Type(0)", i)); 530a9d8d09cSJung-uk Kim Removing = TRUE; 531a9d8d09cSJung-uk Kim } 532a9d8d09cSJung-uk Kim 5338d744e47SJung-uk Kim RemoveElement: 534a9d8d09cSJung-uk Kim if (Removing) 535a9d8d09cSJung-uk Kim { 536a9d8d09cSJung-uk Kim AcpiNsRemoveElement (ReturnObject, i + 1); 537a9d8d09cSJung-uk Kim OuterElementCount--; 538a9d8d09cSJung-uk Kim } 539a9d8d09cSJung-uk Kim else 540a9d8d09cSJung-uk Kim { 541a9d8d09cSJung-uk Kim i++; 542a9d8d09cSJung-uk Kim } 543a9d8d09cSJung-uk Kim } 544a9d8d09cSJung-uk Kim 545a9d8d09cSJung-uk Kim /* Update top-level package count, Type "Integer" checked elsewhere */ 546a9d8d09cSJung-uk Kim 547a9d8d09cSJung-uk Kim ObjDesc = ReturnObject->Package.Elements[0]; 548a9d8d09cSJung-uk Kim ObjDesc->Integer.Value = OuterElementCount; 5498d744e47SJung-uk Kim 5508d744e47SJung-uk Kim /* 5518d744e47SJung-uk Kim * Entries (subpackages) in the _CST Package must be sorted by the 5528d744e47SJung-uk Kim * C-state type, in ascending order. 5538d744e47SJung-uk Kim */ 5548d744e47SJung-uk Kim Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1, 5558d744e47SJung-uk Kim ACPI_SORT_ASCENDING, "C-State Type"); 5568d744e47SJung-uk Kim if (ACPI_FAILURE (Status)) 5578d744e47SJung-uk Kim { 5588d744e47SJung-uk Kim return (Status); 5598d744e47SJung-uk Kim } 5608d744e47SJung-uk Kim 561a9d8d09cSJung-uk Kim return (AE_OK); 562a9d8d09cSJung-uk Kim } 563a9d8d09cSJung-uk Kim 564a9d8d09cSJung-uk Kim 565a9d8d09cSJung-uk Kim /****************************************************************************** 566a9d8d09cSJung-uk Kim * 567a159c266SJung-uk Kim * FUNCTION: AcpiNsRepair_HID 568a159c266SJung-uk Kim * 569895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 570a159c266SJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 571a159c266SJung-uk Kim * evaluation of a method or object 572a159c266SJung-uk Kim * 573a159c266SJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 574a159c266SJung-uk Kim * 575a159c266SJung-uk Kim * DESCRIPTION: Repair for the _HID object. If a string, ensure that all 576a159c266SJung-uk Kim * letters are uppercase and that there is no leading asterisk. 577a159c266SJung-uk Kim * 578a159c266SJung-uk Kim *****************************************************************************/ 579a159c266SJung-uk Kim 580a159c266SJung-uk Kim static ACPI_STATUS 581a159c266SJung-uk Kim AcpiNsRepair_HID ( 582895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 583a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 584a159c266SJung-uk Kim { 585a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 586a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *NewString; 587a159c266SJung-uk Kim char *Source; 588a159c266SJung-uk Kim char *Dest; 589a159c266SJung-uk Kim 590a159c266SJung-uk Kim 591a159c266SJung-uk Kim ACPI_FUNCTION_NAME (NsRepair_HID); 592a159c266SJung-uk Kim 593a159c266SJung-uk Kim 594a159c266SJung-uk Kim /* We only care about string _HID objects (not integers) */ 595a159c266SJung-uk Kim 596a159c266SJung-uk Kim if (ReturnObject->Common.Type != ACPI_TYPE_STRING) 597a159c266SJung-uk Kim { 598a159c266SJung-uk Kim return (AE_OK); 599a159c266SJung-uk Kim } 600a159c266SJung-uk Kim 601a159c266SJung-uk Kim if (ReturnObject->String.Length == 0) 602a159c266SJung-uk Kim { 603*f8146b88SJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, 604*f8146b88SJung-uk Kim Info->FullPathname, Info->NodeFlags, 605a159c266SJung-uk Kim "Invalid zero-length _HID or _CID string")); 606a159c266SJung-uk Kim 607a159c266SJung-uk Kim /* Return AE_OK anyway, let driver handle it */ 608a159c266SJung-uk Kim 609895f26a9SJung-uk Kim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 610a159c266SJung-uk Kim return (AE_OK); 611a159c266SJung-uk Kim } 612a159c266SJung-uk Kim 613a159c266SJung-uk Kim /* It is simplest to always create a new string object */ 614a159c266SJung-uk Kim 615a159c266SJung-uk Kim NewString = AcpiUtCreateStringObject (ReturnObject->String.Length); 616a159c266SJung-uk Kim if (!NewString) 617a159c266SJung-uk Kim { 618a159c266SJung-uk Kim return (AE_NO_MEMORY); 619a159c266SJung-uk Kim } 620a159c266SJung-uk Kim 621a159c266SJung-uk Kim /* 622a159c266SJung-uk Kim * Remove a leading asterisk if present. For some unknown reason, there 623a159c266SJung-uk Kim * are many machines in the field that contains IDs like this. 624a159c266SJung-uk Kim * 625a159c266SJung-uk Kim * Examples: "*PNP0C03", "*ACPI0003" 626a159c266SJung-uk Kim */ 627a159c266SJung-uk Kim Source = ReturnObject->String.Pointer; 628a159c266SJung-uk Kim if (*Source == '*') 629a159c266SJung-uk Kim { 630a159c266SJung-uk Kim Source++; 631a159c266SJung-uk Kim NewString->String.Length--; 632a159c266SJung-uk Kim 633a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 634895f26a9SJung-uk Kim "%s: Removed invalid leading asterisk\n", Info->FullPathname)); 635a159c266SJung-uk Kim } 636a159c266SJung-uk Kim 637a159c266SJung-uk Kim /* 638a159c266SJung-uk Kim * Copy and uppercase the string. From the ACPI 5.0 specification: 639a159c266SJung-uk Kim * 640a159c266SJung-uk Kim * A valid PNP ID must be of the form "AAA####" where A is an uppercase 641a159c266SJung-uk Kim * letter and # is a hex digit. A valid ACPI ID must be of the form 642a159c266SJung-uk Kim * "NNNN####" where N is an uppercase letter or decimal digit, and 643a159c266SJung-uk Kim * # is a hex digit. 644a159c266SJung-uk Kim */ 645a159c266SJung-uk Kim for (Dest = NewString->String.Pointer; *Source; Dest++, Source++) 646a159c266SJung-uk Kim { 6475ef50723SJung-uk Kim *Dest = (char) toupper ((int) *Source); 648a159c266SJung-uk Kim } 649a159c266SJung-uk Kim 650a159c266SJung-uk Kim AcpiUtRemoveReference (ReturnObject); 651a159c266SJung-uk Kim *ReturnObjectPtr = NewString; 652a159c266SJung-uk Kim return (AE_OK); 653a159c266SJung-uk Kim } 654a159c266SJung-uk Kim 655a159c266SJung-uk Kim 656a159c266SJung-uk Kim /****************************************************************************** 657a159c266SJung-uk Kim * 658a9d8d09cSJung-uk Kim * FUNCTION: AcpiNsRepair_PRT 659a159c266SJung-uk Kim * 660895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 661a159c266SJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 662a159c266SJung-uk Kim * evaluation of a method or object 663a159c266SJung-uk Kim * 664a159c266SJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 665a159c266SJung-uk Kim * 666a9d8d09cSJung-uk Kim * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed 667a9d8d09cSJung-uk Kim * SourceName and SourceIndex field, a common BIOS bug. 668a159c266SJung-uk Kim * 669a159c266SJung-uk Kim *****************************************************************************/ 670a159c266SJung-uk Kim 671a159c266SJung-uk Kim static ACPI_STATUS 672a9d8d09cSJung-uk Kim AcpiNsRepair_PRT ( 673895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 674a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 675a159c266SJung-uk Kim { 676a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *PackageObject = *ReturnObjectPtr; 677a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **TopObjectList; 678a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **SubObjectList; 679a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc; 680313a0c13SJung-uk Kim ACPI_OPERAND_OBJECT *SubPackage; 681a9d8d09cSJung-uk Kim UINT32 ElementCount; 682a9d8d09cSJung-uk Kim UINT32 Index; 683a159c266SJung-uk Kim 684a159c266SJung-uk Kim 685a9d8d09cSJung-uk Kim /* Each element in the _PRT package is a subpackage */ 686a9d8d09cSJung-uk Kim 687a9d8d09cSJung-uk Kim TopObjectList = PackageObject->Package.Elements; 688a9d8d09cSJung-uk Kim ElementCount = PackageObject->Package.Count; 689a9d8d09cSJung-uk Kim 690313a0c13SJung-uk Kim /* Examine each subpackage */ 691313a0c13SJung-uk Kim 692313a0c13SJung-uk Kim for (Index = 0; Index < ElementCount; Index++, TopObjectList++) 693a9d8d09cSJung-uk Kim { 694313a0c13SJung-uk Kim SubPackage = *TopObjectList; 695313a0c13SJung-uk Kim SubObjectList = SubPackage->Package.Elements; 696313a0c13SJung-uk Kim 697313a0c13SJung-uk Kim /* Check for minimum required element count */ 698313a0c13SJung-uk Kim 699313a0c13SJung-uk Kim if (SubPackage->Package.Count < 4) 700313a0c13SJung-uk Kim { 701313a0c13SJung-uk Kim continue; 702313a0c13SJung-uk Kim } 703a9d8d09cSJung-uk Kim 704a159c266SJung-uk Kim /* 705a9d8d09cSJung-uk Kim * If the BIOS has erroneously reversed the _PRT SourceName (index 2) 706a9d8d09cSJung-uk Kim * and the SourceIndex (index 3), fix it. _PRT is important enough to 707a9d8d09cSJung-uk Kim * workaround this BIOS error. This also provides compatibility with 708a9d8d09cSJung-uk Kim * other ACPI implementations. 709a159c266SJung-uk Kim */ 710a9d8d09cSJung-uk Kim ObjDesc = SubObjectList[3]; 711a9d8d09cSJung-uk Kim if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)) 712a159c266SJung-uk Kim { 713a9d8d09cSJung-uk Kim SubObjectList[3] = SubObjectList[2]; 714a9d8d09cSJung-uk Kim SubObjectList[2] = ObjDesc; 715a9d8d09cSJung-uk Kim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 716a9d8d09cSJung-uk Kim 717313a0c13SJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, 718313a0c13SJung-uk Kim Info->FullPathname, Info->NodeFlags, 719a9d8d09cSJung-uk Kim "PRT[%X]: Fixed reversed SourceName and SourceIndex", 720a9d8d09cSJung-uk Kim Index)); 721a159c266SJung-uk Kim } 722a9d8d09cSJung-uk Kim } 723a9d8d09cSJung-uk Kim 724a9d8d09cSJung-uk Kim return (AE_OK); 725a159c266SJung-uk Kim } 726a159c266SJung-uk Kim 727a159c266SJung-uk Kim 728a159c266SJung-uk Kim /****************************************************************************** 729a159c266SJung-uk Kim * 730a159c266SJung-uk Kim * FUNCTION: AcpiNsRepair_PSS 731a159c266SJung-uk Kim * 732895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 733a159c266SJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 734a159c266SJung-uk Kim * evaluation of a method or object 735a159c266SJung-uk Kim * 736a159c266SJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 737a159c266SJung-uk Kim * 738a159c266SJung-uk Kim * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list 739a159c266SJung-uk Kim * by the CPU frequencies. Check that the power dissipation values 740a159c266SJung-uk Kim * are all proportional to CPU frequency (i.e., sorting by 741a159c266SJung-uk Kim * frequency should be the same as sorting by power.) 742a159c266SJung-uk Kim * 743a159c266SJung-uk Kim *****************************************************************************/ 744a159c266SJung-uk Kim 745a159c266SJung-uk Kim static ACPI_STATUS 746a159c266SJung-uk Kim AcpiNsRepair_PSS ( 747895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 748a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 749a159c266SJung-uk Kim { 750a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 751a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **OuterElements; 752a159c266SJung-uk Kim UINT32 OuterElementCount; 753a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **Elements; 754a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc; 755a159c266SJung-uk Kim UINT32 PreviousValue; 756a159c266SJung-uk Kim ACPI_STATUS Status; 757a159c266SJung-uk Kim UINT32 i; 758a159c266SJung-uk Kim 759a159c266SJung-uk Kim 760a159c266SJung-uk Kim /* 761313a0c13SJung-uk Kim * Entries (subpackages) in the _PSS Package must be sorted by power 762a159c266SJung-uk Kim * dissipation, in descending order. If it appears that the list is 763a159c266SJung-uk Kim * incorrectly sorted, sort it. We sort by CpuFrequency, since this 764a159c266SJung-uk Kim * should be proportional to the power. 765a159c266SJung-uk Kim */ 766a9d8d09cSJung-uk Kim Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 6, 0, 767a159c266SJung-uk Kim ACPI_SORT_DESCENDING, "CpuFrequency"); 768a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 769a159c266SJung-uk Kim { 770a159c266SJung-uk Kim return (Status); 771a159c266SJung-uk Kim } 772a159c266SJung-uk Kim 773a159c266SJung-uk Kim /* 774a159c266SJung-uk Kim * We now know the list is correctly sorted by CPU frequency. Check if 775a159c266SJung-uk Kim * the power dissipation values are proportional. 776a159c266SJung-uk Kim */ 777a159c266SJung-uk Kim PreviousValue = ACPI_UINT32_MAX; 778a159c266SJung-uk Kim OuterElements = ReturnObject->Package.Elements; 779a159c266SJung-uk Kim OuterElementCount = ReturnObject->Package.Count; 780a159c266SJung-uk Kim 781a159c266SJung-uk Kim for (i = 0; i < OuterElementCount; i++) 782a159c266SJung-uk Kim { 783a159c266SJung-uk Kim Elements = (*OuterElements)->Package.Elements; 784a159c266SJung-uk Kim ObjDesc = Elements[1]; /* Index1 = PowerDissipation */ 785a159c266SJung-uk Kim 786a159c266SJung-uk Kim if ((UINT32) ObjDesc->Integer.Value > PreviousValue) 787a159c266SJung-uk Kim { 788*f8146b88SJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, 789*f8146b88SJung-uk Kim Info->FullPathname, Info->NodeFlags, 790a159c266SJung-uk Kim "SubPackage[%u,%u] - suspicious power dissipation values", 791a159c266SJung-uk Kim i-1, i)); 792a159c266SJung-uk Kim } 793a159c266SJung-uk Kim 794a159c266SJung-uk Kim PreviousValue = (UINT32) ObjDesc->Integer.Value; 795a159c266SJung-uk Kim OuterElements++; 796a159c266SJung-uk Kim } 797a159c266SJung-uk Kim 798a159c266SJung-uk Kim return (AE_OK); 799a159c266SJung-uk Kim } 800a159c266SJung-uk Kim 801a159c266SJung-uk Kim 802a159c266SJung-uk Kim /****************************************************************************** 803a159c266SJung-uk Kim * 804a9d8d09cSJung-uk Kim * FUNCTION: AcpiNsRepair_TSS 805a9d8d09cSJung-uk Kim * 806a9d8d09cSJung-uk Kim * PARAMETERS: Info - Method execution information block 807a9d8d09cSJung-uk Kim * ReturnObjectPtr - Pointer to the object returned from the 808a9d8d09cSJung-uk Kim * evaluation of a method or object 809a9d8d09cSJung-uk Kim * 810a9d8d09cSJung-uk Kim * RETURN: Status. AE_OK if object is OK or was repaired successfully 811a9d8d09cSJung-uk Kim * 812a9d8d09cSJung-uk Kim * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list 813a9d8d09cSJung-uk Kim * descending by the power dissipation values. 814a9d8d09cSJung-uk Kim * 815a9d8d09cSJung-uk Kim *****************************************************************************/ 816a9d8d09cSJung-uk Kim 817a9d8d09cSJung-uk Kim static ACPI_STATUS 818a9d8d09cSJung-uk Kim AcpiNsRepair_TSS ( 819a9d8d09cSJung-uk Kim ACPI_EVALUATE_INFO *Info, 820a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **ReturnObjectPtr) 821a9d8d09cSJung-uk Kim { 822a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 823a9d8d09cSJung-uk Kim ACPI_STATUS Status; 824a9d8d09cSJung-uk Kim ACPI_NAMESPACE_NODE *Node; 825a9d8d09cSJung-uk Kim 826a9d8d09cSJung-uk Kim 827a9d8d09cSJung-uk Kim /* 828a9d8d09cSJung-uk Kim * We can only sort the _TSS return package if there is no _PSS in the 829a9d8d09cSJung-uk Kim * same scope. This is because if _PSS is present, the ACPI specification 830a9d8d09cSJung-uk Kim * dictates that the _TSS Power Dissipation field is to be ignored, and 831a9d8d09cSJung-uk Kim * therefore some BIOSs leave garbage values in the _TSS Power field(s). 832a9d8d09cSJung-uk Kim * In this case, it is best to just return the _TSS package as-is. 833a9d8d09cSJung-uk Kim * (May, 2011) 834a9d8d09cSJung-uk Kim */ 835a9d8d09cSJung-uk Kim Status = AcpiNsGetNode (Info->Node, "^_PSS", 836a9d8d09cSJung-uk Kim ACPI_NS_NO_UPSEARCH, &Node); 837a9d8d09cSJung-uk Kim if (ACPI_SUCCESS (Status)) 838a9d8d09cSJung-uk Kim { 839a9d8d09cSJung-uk Kim return (AE_OK); 840a9d8d09cSJung-uk Kim } 841a9d8d09cSJung-uk Kim 842a9d8d09cSJung-uk Kim Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1, 843a9d8d09cSJung-uk Kim ACPI_SORT_DESCENDING, "PowerDissipation"); 844a9d8d09cSJung-uk Kim 845a9d8d09cSJung-uk Kim return (Status); 846a9d8d09cSJung-uk Kim } 847a9d8d09cSJung-uk Kim 848a9d8d09cSJung-uk Kim 849a9d8d09cSJung-uk Kim /****************************************************************************** 850a9d8d09cSJung-uk Kim * 851a159c266SJung-uk Kim * FUNCTION: AcpiNsCheckSortedList 852a159c266SJung-uk Kim * 853895f26a9SJung-uk Kim * PARAMETERS: Info - Method execution information block 854a159c266SJung-uk Kim * ReturnObject - Pointer to the top-level returned object 855313a0c13SJung-uk Kim * StartIndex - Index of the first subpackage 856313a0c13SJung-uk Kim * ExpectedCount - Minimum length of each subpackage 857313a0c13SJung-uk Kim * SortIndex - Subpackage entry to sort on 858a159c266SJung-uk Kim * SortDirection - Ascending or descending 859a159c266SJung-uk Kim * SortKeyName - Name of the SortIndex field 860a159c266SJung-uk Kim * 861a159c266SJung-uk Kim * RETURN: Status. AE_OK if the list is valid and is sorted correctly or 862a159c266SJung-uk Kim * has been repaired by sorting the list. 863a159c266SJung-uk Kim * 864a159c266SJung-uk Kim * DESCRIPTION: Check if the package list is valid and sorted correctly by the 865a159c266SJung-uk Kim * SortIndex. If not, then sort the list. 866a159c266SJung-uk Kim * 867a159c266SJung-uk Kim *****************************************************************************/ 868a159c266SJung-uk Kim 869a159c266SJung-uk Kim static ACPI_STATUS 870a159c266SJung-uk Kim AcpiNsCheckSortedList ( 871895f26a9SJung-uk Kim ACPI_EVALUATE_INFO *Info, 872a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ReturnObject, 873a9d8d09cSJung-uk Kim UINT32 StartIndex, 874a159c266SJung-uk Kim UINT32 ExpectedCount, 875a159c266SJung-uk Kim UINT32 SortIndex, 876a159c266SJung-uk Kim UINT8 SortDirection, 877a159c266SJung-uk Kim char *SortKeyName) 878a159c266SJung-uk Kim { 879a159c266SJung-uk Kim UINT32 OuterElementCount; 880a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **OuterElements; 881a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **Elements; 882a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc; 883a159c266SJung-uk Kim UINT32 i; 884a159c266SJung-uk Kim UINT32 PreviousValue; 885a159c266SJung-uk Kim 886a159c266SJung-uk Kim 887a159c266SJung-uk Kim ACPI_FUNCTION_NAME (NsCheckSortedList); 888a159c266SJung-uk Kim 889a159c266SJung-uk Kim 890a159c266SJung-uk Kim /* The top-level object must be a package */ 891a159c266SJung-uk Kim 892a159c266SJung-uk Kim if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE) 893a159c266SJung-uk Kim { 894a159c266SJung-uk Kim return (AE_AML_OPERAND_TYPE); 895a159c266SJung-uk Kim } 896a159c266SJung-uk Kim 897a159c266SJung-uk Kim /* 898313a0c13SJung-uk Kim * NOTE: assumes list of subpackages contains no NULL elements. 899a159c266SJung-uk Kim * Any NULL elements should have been removed by earlier call 900a159c266SJung-uk Kim * to AcpiNsRemoveNullElements. 901a159c266SJung-uk Kim */ 902a159c266SJung-uk Kim OuterElementCount = ReturnObject->Package.Count; 903a9d8d09cSJung-uk Kim if (!OuterElementCount || StartIndex >= OuterElementCount) 904a159c266SJung-uk Kim { 905a159c266SJung-uk Kim return (AE_AML_PACKAGE_LIMIT); 906a159c266SJung-uk Kim } 907a159c266SJung-uk Kim 908a9d8d09cSJung-uk Kim OuterElements = &ReturnObject->Package.Elements[StartIndex]; 909a9d8d09cSJung-uk Kim OuterElementCount -= StartIndex; 910a9d8d09cSJung-uk Kim 911a159c266SJung-uk Kim PreviousValue = 0; 912a159c266SJung-uk Kim if (SortDirection == ACPI_SORT_DESCENDING) 913a159c266SJung-uk Kim { 914a159c266SJung-uk Kim PreviousValue = ACPI_UINT32_MAX; 915a159c266SJung-uk Kim } 916a159c266SJung-uk Kim 917a159c266SJung-uk Kim /* Examine each subpackage */ 918a159c266SJung-uk Kim 919a159c266SJung-uk Kim for (i = 0; i < OuterElementCount; i++) 920a159c266SJung-uk Kim { 921a159c266SJung-uk Kim /* Each element of the top-level package must also be a package */ 922a159c266SJung-uk Kim 923a159c266SJung-uk Kim if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE) 924a159c266SJung-uk Kim { 925a159c266SJung-uk Kim return (AE_AML_OPERAND_TYPE); 926a159c266SJung-uk Kim } 927a159c266SJung-uk Kim 928313a0c13SJung-uk Kim /* Each subpackage must have the minimum length */ 929a159c266SJung-uk Kim 930a159c266SJung-uk Kim if ((*OuterElements)->Package.Count < ExpectedCount) 931a159c266SJung-uk Kim { 932a159c266SJung-uk Kim return (AE_AML_PACKAGE_LIMIT); 933a159c266SJung-uk Kim } 934a159c266SJung-uk Kim 935a159c266SJung-uk Kim Elements = (*OuterElements)->Package.Elements; 936a159c266SJung-uk Kim ObjDesc = Elements[SortIndex]; 937a159c266SJung-uk Kim 938a159c266SJung-uk Kim if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER) 939a159c266SJung-uk Kim { 940a159c266SJung-uk Kim return (AE_AML_OPERAND_TYPE); 941a159c266SJung-uk Kim } 942a159c266SJung-uk Kim 943a159c266SJung-uk Kim /* 944a159c266SJung-uk Kim * The list must be sorted in the specified order. If we detect a 945a159c266SJung-uk Kim * discrepancy, sort the entire list. 946a159c266SJung-uk Kim */ 947a159c266SJung-uk Kim if (((SortDirection == ACPI_SORT_ASCENDING) && 948a159c266SJung-uk Kim (ObjDesc->Integer.Value < PreviousValue)) || 949a159c266SJung-uk Kim ((SortDirection == ACPI_SORT_DESCENDING) && 950a159c266SJung-uk Kim (ObjDesc->Integer.Value > PreviousValue))) 951a159c266SJung-uk Kim { 952a9d8d09cSJung-uk Kim AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex], 953a159c266SJung-uk Kim OuterElementCount, SortIndex, SortDirection); 954a159c266SJung-uk Kim 955895f26a9SJung-uk Kim Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 956a159c266SJung-uk Kim 957a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 958a159c266SJung-uk Kim "%s: Repaired unsorted list - now sorted by %s\n", 959895f26a9SJung-uk Kim Info->FullPathname, SortKeyName)); 960a159c266SJung-uk Kim return (AE_OK); 961a159c266SJung-uk Kim } 962a159c266SJung-uk Kim 963a159c266SJung-uk Kim PreviousValue = (UINT32) ObjDesc->Integer.Value; 964a159c266SJung-uk Kim OuterElements++; 965a159c266SJung-uk Kim } 966a159c266SJung-uk Kim 967a159c266SJung-uk Kim return (AE_OK); 968a159c266SJung-uk Kim } 969a159c266SJung-uk Kim 970a159c266SJung-uk Kim 971a159c266SJung-uk Kim /****************************************************************************** 972a159c266SJung-uk Kim * 973a159c266SJung-uk Kim * FUNCTION: AcpiNsSortList 974a159c266SJung-uk Kim * 975a159c266SJung-uk Kim * PARAMETERS: Elements - Package object element list 976a159c266SJung-uk Kim * Count - Element count for above 977a159c266SJung-uk Kim * Index - Sort by which package element 978a159c266SJung-uk Kim * SortDirection - Ascending or Descending sort 979a159c266SJung-uk Kim * 980a159c266SJung-uk Kim * RETURN: None 981a159c266SJung-uk Kim * 982a159c266SJung-uk Kim * DESCRIPTION: Sort the objects that are in a package element list. 983a159c266SJung-uk Kim * 984a159c266SJung-uk Kim * NOTE: Assumes that all NULL elements have been removed from the package, 985a159c266SJung-uk Kim * and that all elements have been verified to be of type Integer. 986a159c266SJung-uk Kim * 987a159c266SJung-uk Kim *****************************************************************************/ 988a159c266SJung-uk Kim 989a159c266SJung-uk Kim static void 990a159c266SJung-uk Kim AcpiNsSortList ( 991a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **Elements, 992a159c266SJung-uk Kim UINT32 Count, 993a159c266SJung-uk Kim UINT32 Index, 994a159c266SJung-uk Kim UINT8 SortDirection) 995a159c266SJung-uk Kim { 996a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc1; 997a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc2; 998a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *TempObj; 999a159c266SJung-uk Kim UINT32 i; 1000a159c266SJung-uk Kim UINT32 j; 1001a159c266SJung-uk Kim 1002a159c266SJung-uk Kim 1003a159c266SJung-uk Kim /* Simple bubble sort */ 1004a159c266SJung-uk Kim 1005a159c266SJung-uk Kim for (i = 1; i < Count; i++) 1006a159c266SJung-uk Kim { 1007a159c266SJung-uk Kim for (j = (Count - 1); j >= i; j--) 1008a159c266SJung-uk Kim { 1009a159c266SJung-uk Kim ObjDesc1 = Elements[j-1]->Package.Elements[Index]; 1010a159c266SJung-uk Kim ObjDesc2 = Elements[j]->Package.Elements[Index]; 1011a159c266SJung-uk Kim 1012a159c266SJung-uk Kim if (((SortDirection == ACPI_SORT_ASCENDING) && 1013a159c266SJung-uk Kim (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) || 1014a159c266SJung-uk Kim 1015a159c266SJung-uk Kim ((SortDirection == ACPI_SORT_DESCENDING) && 1016a159c266SJung-uk Kim (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value))) 1017a159c266SJung-uk Kim { 1018a159c266SJung-uk Kim TempObj = Elements[j-1]; 1019a159c266SJung-uk Kim Elements[j-1] = Elements[j]; 1020a159c266SJung-uk Kim Elements[j] = TempObj; 1021a159c266SJung-uk Kim } 1022a159c266SJung-uk Kim } 1023a159c266SJung-uk Kim } 1024a159c266SJung-uk Kim } 1025a9d8d09cSJung-uk Kim 1026a9d8d09cSJung-uk Kim 1027a9d8d09cSJung-uk Kim /****************************************************************************** 1028a9d8d09cSJung-uk Kim * 1029a9d8d09cSJung-uk Kim * FUNCTION: AcpiNsRemoveElement 1030a9d8d09cSJung-uk Kim * 1031a9d8d09cSJung-uk Kim * PARAMETERS: ObjDesc - Package object element list 1032a9d8d09cSJung-uk Kim * Index - Index of element to remove 1033a9d8d09cSJung-uk Kim * 1034a9d8d09cSJung-uk Kim * RETURN: None 1035a9d8d09cSJung-uk Kim * 1036a9d8d09cSJung-uk Kim * DESCRIPTION: Remove the requested element of a package and delete it. 1037a9d8d09cSJung-uk Kim * 1038a9d8d09cSJung-uk Kim *****************************************************************************/ 1039a9d8d09cSJung-uk Kim 1040a9d8d09cSJung-uk Kim static void 1041a9d8d09cSJung-uk Kim AcpiNsRemoveElement ( 1042a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc, 1043a9d8d09cSJung-uk Kim UINT32 Index) 1044a9d8d09cSJung-uk Kim { 1045a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **Source; 1046a9d8d09cSJung-uk Kim ACPI_OPERAND_OBJECT **Dest; 1047a9d8d09cSJung-uk Kim UINT32 Count; 1048a9d8d09cSJung-uk Kim UINT32 NewCount; 1049a9d8d09cSJung-uk Kim UINT32 i; 1050a9d8d09cSJung-uk Kim 1051a9d8d09cSJung-uk Kim 1052a9d8d09cSJung-uk Kim ACPI_FUNCTION_NAME (NsRemoveElement); 1053a9d8d09cSJung-uk Kim 1054a9d8d09cSJung-uk Kim 1055a9d8d09cSJung-uk Kim Count = ObjDesc->Package.Count; 1056a9d8d09cSJung-uk Kim NewCount = Count - 1; 1057a9d8d09cSJung-uk Kim 1058a9d8d09cSJung-uk Kim Source = ObjDesc->Package.Elements; 1059a9d8d09cSJung-uk Kim Dest = Source; 1060a9d8d09cSJung-uk Kim 1061a9d8d09cSJung-uk Kim /* Examine all elements of the package object, remove matched index */ 1062a9d8d09cSJung-uk Kim 1063a9d8d09cSJung-uk Kim for (i = 0; i < Count; i++) 1064a9d8d09cSJung-uk Kim { 1065a9d8d09cSJung-uk Kim if (i == Index) 1066a9d8d09cSJung-uk Kim { 1067a9d8d09cSJung-uk Kim AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */ 1068a9d8d09cSJung-uk Kim AcpiUtRemoveReference (*Source); 1069a9d8d09cSJung-uk Kim } 1070a9d8d09cSJung-uk Kim else 1071a9d8d09cSJung-uk Kim { 1072a9d8d09cSJung-uk Kim *Dest = *Source; 1073a9d8d09cSJung-uk Kim Dest++; 1074a9d8d09cSJung-uk Kim } 1075*f8146b88SJung-uk Kim 1076a9d8d09cSJung-uk Kim Source++; 1077a9d8d09cSJung-uk Kim } 1078a9d8d09cSJung-uk Kim 1079a9d8d09cSJung-uk Kim /* NULL terminate list and update the package count */ 1080a9d8d09cSJung-uk Kim 1081a9d8d09cSJung-uk Kim *Dest = NULL; 1082a9d8d09cSJung-uk Kim ObjDesc->Package.Count = NewCount; 1083a9d8d09cSJung-uk Kim } 1084