dmdeferred.c revision 245582
1100966Siwasaki/****************************************************************************** 2100966Siwasaki * 3100966Siwasaki * Module Name: dmdeferred - Disassembly of deferred AML opcodes 4100966Siwasaki * 5100966Siwasaki *****************************************************************************/ 6100966Siwasaki 7217365Sjkim/* 8278970Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 9100966Siwasaki * All rights reserved. 10100966Siwasaki * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 25100966Siwasaki * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 29100966Siwasaki * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 43100966Siwasaki 44193341Sjkim 45193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 46193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 47193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 48193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 49193341Sjkim#include <contrib/dev/acpica/include/acdisasm.h> 50100966Siwasaki#include <contrib/dev/acpica/include/acparser.h> 51100966Siwasaki 52100966Siwasaki#define _COMPONENT ACPI_CA_DISASSEMBLER 53100966Siwasaki ACPI_MODULE_NAME ("dmdeferred") 54102550Siwasaki 55100966Siwasaki 56100966Siwasaki/* Local prototypes */ 57100966Siwasaki 58151937Sjkimstatic ACPI_STATUS 59100966SiwasakiAcpiDmDeferredParse ( 60198237Sjkim ACPI_PARSE_OBJECT *Op, 61198237Sjkim UINT8 *Aml, 62198237Sjkim UINT32 AmlLength); 63198237Sjkim 64198237Sjkim 65198237Sjkim/****************************************************************************** 66198237Sjkim * 67198237Sjkim * FUNCTION: AcpiDmParseDeferredOps 68198237Sjkim * 69198237Sjkim * PARAMETERS: Root - Root of the parse tree 70198237Sjkim * 71151937Sjkim * RETURN: Status 72100966Siwasaki * 73151937Sjkim * DESCRIPTION: Parse the deferred opcodes (Methods, regions, etc.) 74151937Sjkim * 75151937Sjkim *****************************************************************************/ 76151937Sjkim 77151937SjkimACPI_STATUS 78151937SjkimAcpiDmParseDeferredOps ( 79151937Sjkim ACPI_PARSE_OBJECT *Root) 80151937Sjkim{ 81151937Sjkim const ACPI_OPCODE_INFO *OpInfo; 82151937Sjkim ACPI_PARSE_OBJECT *Op = Root; 83151937Sjkim ACPI_STATUS Status; 84151937Sjkim 85151937Sjkim 86151937Sjkim ACPI_FUNCTION_ENTRY (); 87151937Sjkim 88151937Sjkim 89151937Sjkim /* Traverse the entire parse tree */ 90100966Siwasaki 91100966Siwasaki while (Op) 92100966Siwasaki { 93100966Siwasaki OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 94151937Sjkim if (!(OpInfo->Flags & AML_DEFER)) 95151937Sjkim { 96100966Siwasaki Op = AcpiPsGetDepthNext (Root, Op); 97100966Siwasaki continue; 98100966Siwasaki } 99100966Siwasaki 100241973Sjkim /* Now we know we have a deferred opcode */ 101100966Siwasaki 102100966Siwasaki switch (Op->Common.AmlOpcode) 103100966Siwasaki { 104100966Siwasaki case AML_METHOD_OP: 105100966Siwasaki case AML_BUFFER_OP: 106100966Siwasaki case AML_PACKAGE_OP: 107100966Siwasaki case AML_VAR_PACKAGE_OP: 108100966Siwasaki 109100966Siwasaki Status = AcpiDmDeferredParse (Op, Op->Named.Data, Op->Named.Length); 110100966Siwasaki if (ACPI_FAILURE (Status)) 111100966Siwasaki { 112100966Siwasaki return (Status); 113100966Siwasaki } 114100966Siwasaki break; 115100966Siwasaki 116100966Siwasaki /* We don't need to do anything for these deferred opcodes */ 117100966Siwasaki 118100966Siwasaki case AML_REGION_OP: 119100966Siwasaki case AML_DATA_REGION_OP: 120167802Sjkim case AML_CREATE_QWORD_FIELD_OP: 121100966Siwasaki case AML_CREATE_DWORD_FIELD_OP: 122167802Sjkim case AML_CREATE_WORD_FIELD_OP: 123151937Sjkim case AML_CREATE_BYTE_FIELD_OP: 124100966Siwasaki case AML_CREATE_BIT_FIELD_OP: 125100966Siwasaki case AML_CREATE_FIELD_OP: 126100966Siwasaki case AML_BANK_FIELD_OP: 127100966Siwasaki 128100966Siwasaki break; 129100966Siwasaki 130100966Siwasaki default: 131100966Siwasaki ACPI_ERROR ((AE_INFO, "Unhandled deferred AML opcode [0x%.4X]", 132100966Siwasaki Op->Common.AmlOpcode)); 133151937Sjkim break; 134151937Sjkim } 135100966Siwasaki 136100966Siwasaki Op = AcpiPsGetDepthNext (Root, Op); 137100966Siwasaki } 138100966Siwasaki 139100966Siwasaki return (AE_OK); 140100966Siwasaki} 141100966Siwasaki 142100966Siwasaki 143100966Siwasaki/****************************************************************************** 144167802Sjkim * 145100966Siwasaki * FUNCTION: AcpiDmDeferredParse 146100966Siwasaki * 147100966Siwasaki * PARAMETERS: Op - Root Op of the deferred opcode 148100966Siwasaki * Aml - Pointer to the raw AML 149100966Siwasaki * AmlLength - Length of the AML 150100966Siwasaki * 151100966Siwasaki * RETURN: Status 152100966Siwasaki * 153100966Siwasaki * DESCRIPTION: Parse one deferred opcode 154100966Siwasaki * (Methods, operation regions, etc.) 155100966Siwasaki * 156100966Siwasaki *****************************************************************************/ 157100966Siwasaki 158100966Siwasakistatic ACPI_STATUS 159100966SiwasakiAcpiDmDeferredParse ( 160100966Siwasaki ACPI_PARSE_OBJECT *Op, 161100966Siwasaki UINT8 *Aml, 162100966Siwasaki UINT32 AmlLength) 163100966Siwasaki{ 164100966Siwasaki ACPI_WALK_STATE *WalkState; 165167802Sjkim ACPI_STATUS Status; 166100966Siwasaki ACPI_PARSE_OBJECT *SearchOp; 167167802Sjkim ACPI_PARSE_OBJECT *StartOp; 168167802Sjkim UINT32 BaseAmlOffset; 169167802Sjkim ACPI_PARSE_OBJECT *NewRootOp; 170167802Sjkim ACPI_PARSE_OBJECT *ExtraOp; 171167802Sjkim 172100966Siwasaki 173100966Siwasaki ACPI_FUNCTION_TRACE (DmDeferredParse); 174100966Siwasaki 175100966Siwasaki 176117521Snjl if (!Aml || !AmlLength) 177117521Snjl { 178100966Siwasaki return_ACPI_STATUS (AE_OK); 179100966Siwasaki } 180100966Siwasaki 181100966Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing deferred opcode %s [%4.4s]\n", 182100966Siwasaki Op->Common.AmlOpName, (char *) &Op->Named.Name)); 183100966Siwasaki 184100966Siwasaki /* Need a new walk state to parse the AML */ 185100966Siwasaki 186100966Siwasaki WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL); 187100966Siwasaki if (!WalkState) 188100966Siwasaki { 189100966Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 190100966Siwasaki } 191100966Siwasaki 192100966Siwasaki Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Aml, 193100966Siwasaki AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 194100966Siwasaki if (ACPI_FAILURE (Status)) 195100966Siwasaki { 196100966Siwasaki return_ACPI_STATUS (Status); 197100966Siwasaki } 198100966Siwasaki 199100966Siwasaki /* Parse the AML for this deferred opcode */ 200100966Siwasaki 201100966Siwasaki WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 202100966Siwasaki WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; 203100966Siwasaki Status = AcpiPsParseAml (WalkState); 204100966Siwasaki 205100966Siwasaki /* 206100966Siwasaki * We need to update all of the AML offsets, since the parser thought 207100966Siwasaki * that the method began at offset zero. In reality, it began somewhere 208100966Siwasaki * within the ACPI table, at the BaseAmlOffset. Walk the entire tree that 209100966Siwasaki * was just created and update the AmlOffset in each Op. 210100966Siwasaki */ 211100966Siwasaki BaseAmlOffset = (Op->Common.Value.Arg)->Common.AmlOffset + 1; 212100966Siwasaki StartOp = (Op->Common.Value.Arg)->Common.Next; 213100966Siwasaki SearchOp = StartOp; 214100966Siwasaki 215100966Siwasaki while (SearchOp) 216100966Siwasaki { 217100966Siwasaki SearchOp->Common.AmlOffset += BaseAmlOffset; 218100966Siwasaki SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); 219100966Siwasaki } 220100966Siwasaki 221100966Siwasaki /* 222100966Siwasaki * For Buffer and Package opcodes, link the newly parsed subtree 223100966Siwasaki * into the main parse tree 224100966Siwasaki */ 225100966Siwasaki switch (Op->Common.AmlOpcode) 226100966Siwasaki { 227100966Siwasaki case AML_BUFFER_OP: 228100966Siwasaki case AML_PACKAGE_OP: 229100966Siwasaki case AML_VAR_PACKAGE_OP: 230100966Siwasaki 231100966Siwasaki switch (Op->Common.AmlOpcode) 232100966Siwasaki { 233100966Siwasaki case AML_PACKAGE_OP: 234100966Siwasaki 235100966Siwasaki ExtraOp = Op->Common.Value.Arg; 236100966Siwasaki NewRootOp = ExtraOp->Common.Next; 237100966Siwasaki ACPI_FREE (ExtraOp); 238100966Siwasaki break; 239100966Siwasaki 240100966Siwasaki case AML_VAR_PACKAGE_OP: 241100966Siwasaki case AML_BUFFER_OP: 242100966Siwasaki default: 243100966Siwasaki 244100966Siwasaki NewRootOp = Op->Common.Value.Arg; 245100966Siwasaki break; 246100966Siwasaki } 247151937Sjkim 248100966Siwasaki Op->Common.Value.Arg = NewRootOp->Common.Value.Arg; 249100966Siwasaki 250100966Siwasaki /* Must point all parents to the main tree */ 251100966Siwasaki 252100966Siwasaki StartOp = Op; 253151937Sjkim SearchOp = StartOp; 254100966Siwasaki while (SearchOp) 255100966Siwasaki { 256100966Siwasaki if (SearchOp->Common.Parent == NewRootOp) 257100966Siwasaki { 258100966Siwasaki SearchOp->Common.Parent = Op; 259100966Siwasaki } 260100966Siwasaki 261100966Siwasaki SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); 262100966Siwasaki } 263100966Siwasaki 264100966Siwasaki ACPI_FREE (NewRootOp); 265100966Siwasaki break; 266100966Siwasaki 267100966Siwasaki default: 268100966Siwasaki break; 269100966Siwasaki } 270100966Siwasaki 271100966Siwasaki return_ACPI_STATUS (AE_OK); 272100966Siwasaki} 273100966Siwasaki