1ed17e06eSJung-uk Kim /****************************************************************************** 2ed17e06eSJung-uk Kim * 3ed17e06eSJung-uk Kim * Module Name: dmdeferred - Disassembly of deferred AML opcodes 4ed17e06eSJung-uk Kim * 5ed17e06eSJung-uk Kim *****************************************************************************/ 6ed17e06eSJung-uk Kim 7ed17e06eSJung-uk Kim /* 8efcc2a30SJung-uk Kim * Copyright (C) 2000 - 2013, Intel Corp. 9ed17e06eSJung-uk Kim * All rights reserved. 10ed17e06eSJung-uk Kim * 11ed17e06eSJung-uk Kim * Redistribution and use in source and binary forms, with or without 12ed17e06eSJung-uk Kim * modification, are permitted provided that the following conditions 13ed17e06eSJung-uk Kim * are met: 14ed17e06eSJung-uk Kim * 1. Redistributions of source code must retain the above copyright 15ed17e06eSJung-uk Kim * notice, this list of conditions, and the following disclaimer, 16ed17e06eSJung-uk Kim * without modification. 17ed17e06eSJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18ed17e06eSJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 19ed17e06eSJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 20ed17e06eSJung-uk Kim * including a substantially similar Disclaimer requirement for further 21ed17e06eSJung-uk Kim * binary redistribution. 22ed17e06eSJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 23ed17e06eSJung-uk Kim * of any contributors may be used to endorse or promote products derived 24ed17e06eSJung-uk Kim * from this software without specific prior written permission. 25ed17e06eSJung-uk Kim * 26ed17e06eSJung-uk Kim * Alternatively, this software may be distributed under the terms of the 27ed17e06eSJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 28ed17e06eSJung-uk Kim * Software Foundation. 29ed17e06eSJung-uk Kim * 30ed17e06eSJung-uk Kim * NO WARRANTY 31ed17e06eSJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32ed17e06eSJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33ed17e06eSJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34ed17e06eSJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35ed17e06eSJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36ed17e06eSJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37ed17e06eSJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38ed17e06eSJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39ed17e06eSJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40ed17e06eSJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41ed17e06eSJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 42ed17e06eSJung-uk Kim */ 43ed17e06eSJung-uk Kim 44ed17e06eSJung-uk Kim 45ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 46ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 47ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/acdispat.h> 48ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h> 49ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/acdisasm.h> 50ed17e06eSJung-uk Kim #include <contrib/dev/acpica/include/acparser.h> 51ed17e06eSJung-uk Kim 52ed17e06eSJung-uk Kim #define _COMPONENT ACPI_CA_DISASSEMBLER 53ed17e06eSJung-uk Kim ACPI_MODULE_NAME ("dmdeferred") 54ed17e06eSJung-uk Kim 55ed17e06eSJung-uk Kim 56ed17e06eSJung-uk Kim /* Local prototypes */ 57ed17e06eSJung-uk Kim 58ed17e06eSJung-uk Kim static ACPI_STATUS 59ed17e06eSJung-uk Kim AcpiDmDeferredParse ( 60ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *Op, 61ed17e06eSJung-uk Kim UINT8 *Aml, 62ed17e06eSJung-uk Kim UINT32 AmlLength); 63ed17e06eSJung-uk Kim 64ed17e06eSJung-uk Kim 65ed17e06eSJung-uk Kim /****************************************************************************** 66ed17e06eSJung-uk Kim * 67ed17e06eSJung-uk Kim * FUNCTION: AcpiDmParseDeferredOps 68ed17e06eSJung-uk Kim * 69ed17e06eSJung-uk Kim * PARAMETERS: Root - Root of the parse tree 70ed17e06eSJung-uk Kim * 71ed17e06eSJung-uk Kim * RETURN: Status 72ed17e06eSJung-uk Kim * 73ed17e06eSJung-uk Kim * DESCRIPTION: Parse the deferred opcodes (Methods, regions, etc.) 74ed17e06eSJung-uk Kim * 75ed17e06eSJung-uk Kim *****************************************************************************/ 76ed17e06eSJung-uk Kim 77ed17e06eSJung-uk Kim ACPI_STATUS 78ed17e06eSJung-uk Kim AcpiDmParseDeferredOps ( 79ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *Root) 80ed17e06eSJung-uk Kim { 81ed17e06eSJung-uk Kim const ACPI_OPCODE_INFO *OpInfo; 82ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *Op = Root; 83ed17e06eSJung-uk Kim ACPI_STATUS Status; 84ed17e06eSJung-uk Kim 85ed17e06eSJung-uk Kim 86efcc2a30SJung-uk Kim ACPI_FUNCTION_ENTRY (); 87ed17e06eSJung-uk Kim 88ed17e06eSJung-uk Kim 89ed17e06eSJung-uk Kim /* Traverse the entire parse tree */ 90ed17e06eSJung-uk Kim 91ed17e06eSJung-uk Kim while (Op) 92ed17e06eSJung-uk Kim { 93ed17e06eSJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 94ed17e06eSJung-uk Kim if (!(OpInfo->Flags & AML_DEFER)) 95ed17e06eSJung-uk Kim { 96ed17e06eSJung-uk Kim Op = AcpiPsGetDepthNext (Root, Op); 97ed17e06eSJung-uk Kim continue; 98ed17e06eSJung-uk Kim } 99ed17e06eSJung-uk Kim 100ed17e06eSJung-uk Kim /* Now we know we have a deferred opcode */ 101ed17e06eSJung-uk Kim 102ed17e06eSJung-uk Kim switch (Op->Common.AmlOpcode) 103ed17e06eSJung-uk Kim { 104ed17e06eSJung-uk Kim case AML_METHOD_OP: 105ed17e06eSJung-uk Kim case AML_BUFFER_OP: 106ed17e06eSJung-uk Kim case AML_PACKAGE_OP: 107ed17e06eSJung-uk Kim case AML_VAR_PACKAGE_OP: 108ed17e06eSJung-uk Kim 109ed17e06eSJung-uk Kim Status = AcpiDmDeferredParse (Op, Op->Named.Data, Op->Named.Length); 110ed17e06eSJung-uk Kim if (ACPI_FAILURE (Status)) 111ed17e06eSJung-uk Kim { 112ed17e06eSJung-uk Kim return (Status); 113ed17e06eSJung-uk Kim } 114ed17e06eSJung-uk Kim break; 115ed17e06eSJung-uk Kim 116ed17e06eSJung-uk Kim /* We don't need to do anything for these deferred opcodes */ 117ed17e06eSJung-uk Kim 118ed17e06eSJung-uk Kim case AML_REGION_OP: 119ed17e06eSJung-uk Kim case AML_DATA_REGION_OP: 120ed17e06eSJung-uk Kim case AML_CREATE_QWORD_FIELD_OP: 121ed17e06eSJung-uk Kim case AML_CREATE_DWORD_FIELD_OP: 122ed17e06eSJung-uk Kim case AML_CREATE_WORD_FIELD_OP: 123ed17e06eSJung-uk Kim case AML_CREATE_BYTE_FIELD_OP: 124ed17e06eSJung-uk Kim case AML_CREATE_BIT_FIELD_OP: 125ed17e06eSJung-uk Kim case AML_CREATE_FIELD_OP: 126ed17e06eSJung-uk Kim case AML_BANK_FIELD_OP: 127ed17e06eSJung-uk Kim 128ed17e06eSJung-uk Kim break; 129ed17e06eSJung-uk Kim 130ed17e06eSJung-uk Kim default: 131*a9d8d09cSJung-uk Kim 132ed17e06eSJung-uk Kim ACPI_ERROR ((AE_INFO, "Unhandled deferred AML opcode [0x%.4X]", 133ed17e06eSJung-uk Kim Op->Common.AmlOpcode)); 134ed17e06eSJung-uk Kim break; 135ed17e06eSJung-uk Kim } 136ed17e06eSJung-uk Kim 137ed17e06eSJung-uk Kim Op = AcpiPsGetDepthNext (Root, Op); 138ed17e06eSJung-uk Kim } 139ed17e06eSJung-uk Kim 140ed17e06eSJung-uk Kim return (AE_OK); 141ed17e06eSJung-uk Kim } 142ed17e06eSJung-uk Kim 143ed17e06eSJung-uk Kim 144ed17e06eSJung-uk Kim /****************************************************************************** 145ed17e06eSJung-uk Kim * 146ed17e06eSJung-uk Kim * FUNCTION: AcpiDmDeferredParse 147ed17e06eSJung-uk Kim * 148ed17e06eSJung-uk Kim * PARAMETERS: Op - Root Op of the deferred opcode 149ed17e06eSJung-uk Kim * Aml - Pointer to the raw AML 150ed17e06eSJung-uk Kim * AmlLength - Length of the AML 151ed17e06eSJung-uk Kim * 152ed17e06eSJung-uk Kim * RETURN: Status 153ed17e06eSJung-uk Kim * 154ed17e06eSJung-uk Kim * DESCRIPTION: Parse one deferred opcode 155ed17e06eSJung-uk Kim * (Methods, operation regions, etc.) 156ed17e06eSJung-uk Kim * 157ed17e06eSJung-uk Kim *****************************************************************************/ 158ed17e06eSJung-uk Kim 159ed17e06eSJung-uk Kim static ACPI_STATUS 160ed17e06eSJung-uk Kim AcpiDmDeferredParse ( 161ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *Op, 162ed17e06eSJung-uk Kim UINT8 *Aml, 163ed17e06eSJung-uk Kim UINT32 AmlLength) 164ed17e06eSJung-uk Kim { 165ed17e06eSJung-uk Kim ACPI_WALK_STATE *WalkState; 166ed17e06eSJung-uk Kim ACPI_STATUS Status; 167ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *SearchOp; 168ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *StartOp; 169ed17e06eSJung-uk Kim UINT32 BaseAmlOffset; 170ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *NewRootOp; 171ed17e06eSJung-uk Kim ACPI_PARSE_OBJECT *ExtraOp; 172ed17e06eSJung-uk Kim 173ed17e06eSJung-uk Kim 174ed17e06eSJung-uk Kim ACPI_FUNCTION_TRACE (DmDeferredParse); 175ed17e06eSJung-uk Kim 176ed17e06eSJung-uk Kim 177ed17e06eSJung-uk Kim if (!Aml || !AmlLength) 178ed17e06eSJung-uk Kim { 179ed17e06eSJung-uk Kim return_ACPI_STATUS (AE_OK); 180ed17e06eSJung-uk Kim } 181ed17e06eSJung-uk Kim 182ed17e06eSJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing deferred opcode %s [%4.4s]\n", 183ed17e06eSJung-uk Kim Op->Common.AmlOpName, (char *) &Op->Named.Name)); 184ed17e06eSJung-uk Kim 185ed17e06eSJung-uk Kim /* Need a new walk state to parse the AML */ 186ed17e06eSJung-uk Kim 187ed17e06eSJung-uk Kim WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL); 188ed17e06eSJung-uk Kim if (!WalkState) 189ed17e06eSJung-uk Kim { 190ed17e06eSJung-uk Kim return_ACPI_STATUS (AE_NO_MEMORY); 191ed17e06eSJung-uk Kim } 192ed17e06eSJung-uk Kim 193ed17e06eSJung-uk Kim Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Aml, 194ed17e06eSJung-uk Kim AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 195ed17e06eSJung-uk Kim if (ACPI_FAILURE (Status)) 196ed17e06eSJung-uk Kim { 197ed17e06eSJung-uk Kim return_ACPI_STATUS (Status); 198ed17e06eSJung-uk Kim } 199ed17e06eSJung-uk Kim 200ed17e06eSJung-uk Kim /* Parse the AML for this deferred opcode */ 201ed17e06eSJung-uk Kim 202ed17e06eSJung-uk Kim WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 203ed17e06eSJung-uk Kim WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; 204ed17e06eSJung-uk Kim Status = AcpiPsParseAml (WalkState); 205ed17e06eSJung-uk Kim 206ed17e06eSJung-uk Kim /* 207ed17e06eSJung-uk Kim * We need to update all of the AML offsets, since the parser thought 208ed17e06eSJung-uk Kim * that the method began at offset zero. In reality, it began somewhere 209ed17e06eSJung-uk Kim * within the ACPI table, at the BaseAmlOffset. Walk the entire tree that 210ed17e06eSJung-uk Kim * was just created and update the AmlOffset in each Op. 211ed17e06eSJung-uk Kim */ 212ed17e06eSJung-uk Kim BaseAmlOffset = (Op->Common.Value.Arg)->Common.AmlOffset + 1; 213ed17e06eSJung-uk Kim StartOp = (Op->Common.Value.Arg)->Common.Next; 214ed17e06eSJung-uk Kim SearchOp = StartOp; 215ed17e06eSJung-uk Kim 216ed17e06eSJung-uk Kim while (SearchOp) 217ed17e06eSJung-uk Kim { 218ed17e06eSJung-uk Kim SearchOp->Common.AmlOffset += BaseAmlOffset; 219ed17e06eSJung-uk Kim SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); 220ed17e06eSJung-uk Kim } 221ed17e06eSJung-uk Kim 222ed17e06eSJung-uk Kim /* 223ed17e06eSJung-uk Kim * For Buffer and Package opcodes, link the newly parsed subtree 224ed17e06eSJung-uk Kim * into the main parse tree 225ed17e06eSJung-uk Kim */ 226ed17e06eSJung-uk Kim switch (Op->Common.AmlOpcode) 227ed17e06eSJung-uk Kim { 228ed17e06eSJung-uk Kim case AML_BUFFER_OP: 229ed17e06eSJung-uk Kim case AML_PACKAGE_OP: 230ed17e06eSJung-uk Kim case AML_VAR_PACKAGE_OP: 231ed17e06eSJung-uk Kim 232ed17e06eSJung-uk Kim switch (Op->Common.AmlOpcode) 233ed17e06eSJung-uk Kim { 234ed17e06eSJung-uk Kim case AML_PACKAGE_OP: 235ed17e06eSJung-uk Kim 236ed17e06eSJung-uk Kim ExtraOp = Op->Common.Value.Arg; 237ed17e06eSJung-uk Kim NewRootOp = ExtraOp->Common.Next; 238ed17e06eSJung-uk Kim ACPI_FREE (ExtraOp); 239ed17e06eSJung-uk Kim break; 240ed17e06eSJung-uk Kim 241ed17e06eSJung-uk Kim case AML_VAR_PACKAGE_OP: 242ed17e06eSJung-uk Kim case AML_BUFFER_OP: 243ed17e06eSJung-uk Kim default: 244ed17e06eSJung-uk Kim 245ed17e06eSJung-uk Kim NewRootOp = Op->Common.Value.Arg; 246ed17e06eSJung-uk Kim break; 247ed17e06eSJung-uk Kim } 248ed17e06eSJung-uk Kim 249ed17e06eSJung-uk Kim Op->Common.Value.Arg = NewRootOp->Common.Value.Arg; 250ed17e06eSJung-uk Kim 251ed17e06eSJung-uk Kim /* Must point all parents to the main tree */ 252ed17e06eSJung-uk Kim 253ed17e06eSJung-uk Kim StartOp = Op; 254ed17e06eSJung-uk Kim SearchOp = StartOp; 255ed17e06eSJung-uk Kim while (SearchOp) 256ed17e06eSJung-uk Kim { 257ed17e06eSJung-uk Kim if (SearchOp->Common.Parent == NewRootOp) 258ed17e06eSJung-uk Kim { 259ed17e06eSJung-uk Kim SearchOp->Common.Parent = Op; 260ed17e06eSJung-uk Kim } 261ed17e06eSJung-uk Kim 262ed17e06eSJung-uk Kim SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); 263ed17e06eSJung-uk Kim } 264ed17e06eSJung-uk Kim 265ed17e06eSJung-uk Kim ACPI_FREE (NewRootOp); 266ed17e06eSJung-uk Kim break; 267ed17e06eSJung-uk Kim 268ed17e06eSJung-uk Kim default: 269*a9d8d09cSJung-uk Kim 270ed17e06eSJung-uk Kim break; 271ed17e06eSJung-uk Kim } 272ed17e06eSJung-uk Kim 273ed17e06eSJung-uk Kim return_ACPI_STATUS (AE_OK); 274ed17e06eSJung-uk Kim } 275