dmdeferred.c revision 243347
1243044Sjkim/****************************************************************************** 2243044Sjkim * 3243044Sjkim * Module Name: dmdeferred - Disassembly of deferred AML opcodes 4243044Sjkim * 5243044Sjkim *****************************************************************************/ 6243044Sjkim 7243044Sjkim/* 8243044Sjkim * Copyright (C) 2000 - 2012, Intel Corp. 9243044Sjkim * All rights reserved. 10243044Sjkim * 11243044Sjkim * Redistribution and use in source and binary forms, with or without 12243044Sjkim * modification, are permitted provided that the following conditions 13243044Sjkim * are met: 14243044Sjkim * 1. Redistributions of source code must retain the above copyright 15243044Sjkim * notice, this list of conditions, and the following disclaimer, 16243044Sjkim * without modification. 17243044Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18243044Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19243044Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20243044Sjkim * including a substantially similar Disclaimer requirement for further 21243044Sjkim * binary redistribution. 22243044Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23243044Sjkim * of any contributors may be used to endorse or promote products derived 24243044Sjkim * from this software without specific prior written permission. 25243044Sjkim * 26243044Sjkim * Alternatively, this software may be distributed under the terms of the 27243044Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28243044Sjkim * Software Foundation. 29243044Sjkim * 30243044Sjkim * NO WARRANTY 31243044Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32243044Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33243044Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34243044Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35243044Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36243044Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37243044Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38243044Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39243044Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40243044Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41243044Sjkim * POSSIBILITY OF SUCH DAMAGES. 42243044Sjkim */ 43243044Sjkim 44243044Sjkim 45243347Sjkim#include <contrib/dev/acpica/include/acpi.h> 46243347Sjkim#include <contrib/dev/acpica/include/accommon.h> 47243347Sjkim#include <contrib/dev/acpica/include/acdispat.h> 48243347Sjkim#include <contrib/dev/acpica/include/amlcode.h> 49243347Sjkim#include <contrib/dev/acpica/include/acdisasm.h> 50243347Sjkim#include <contrib/dev/acpica/include/acparser.h> 51243044Sjkim 52243044Sjkim#define _COMPONENT ACPI_CA_DISASSEMBLER 53243044Sjkim ACPI_MODULE_NAME ("dmdeferred") 54243044Sjkim 55243044Sjkim 56243044Sjkim/* Local prototypes */ 57243044Sjkim 58243044Sjkimstatic ACPI_STATUS 59243044SjkimAcpiDmDeferredParse ( 60243044Sjkim ACPI_PARSE_OBJECT *Op, 61243044Sjkim UINT8 *Aml, 62243044Sjkim UINT32 AmlLength); 63243044Sjkim 64243044Sjkim 65243044Sjkim/****************************************************************************** 66243044Sjkim * 67243044Sjkim * FUNCTION: AcpiDmParseDeferredOps 68243044Sjkim * 69243044Sjkim * PARAMETERS: Root - Root of the parse tree 70243044Sjkim * 71243044Sjkim * RETURN: Status 72243044Sjkim * 73243044Sjkim * DESCRIPTION: Parse the deferred opcodes (Methods, regions, etc.) 74243044Sjkim * 75243044Sjkim *****************************************************************************/ 76243044Sjkim 77243044SjkimACPI_STATUS 78243044SjkimAcpiDmParseDeferredOps ( 79243044Sjkim ACPI_PARSE_OBJECT *Root) 80243044Sjkim{ 81243044Sjkim const ACPI_OPCODE_INFO *OpInfo; 82243044Sjkim ACPI_PARSE_OBJECT *Op = Root; 83243044Sjkim ACPI_STATUS Status; 84243044Sjkim 85243044Sjkim 86243044Sjkim ACPI_FUNCTION_NAME (DmParseDeferredOps); 87243044Sjkim 88243044Sjkim 89243044Sjkim /* Traverse the entire parse tree */ 90243044Sjkim 91243044Sjkim while (Op) 92243044Sjkim { 93243044Sjkim OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 94243044Sjkim if (!(OpInfo->Flags & AML_DEFER)) 95243044Sjkim { 96243044Sjkim Op = AcpiPsGetDepthNext (Root, Op); 97243044Sjkim continue; 98243044Sjkim } 99243044Sjkim 100243044Sjkim /* Now we know we have a deferred opcode */ 101243044Sjkim 102243044Sjkim switch (Op->Common.AmlOpcode) 103243044Sjkim { 104243044Sjkim case AML_METHOD_OP: 105243044Sjkim case AML_BUFFER_OP: 106243044Sjkim case AML_PACKAGE_OP: 107243044Sjkim case AML_VAR_PACKAGE_OP: 108243044Sjkim 109243044Sjkim Status = AcpiDmDeferredParse (Op, Op->Named.Data, Op->Named.Length); 110243044Sjkim if (ACPI_FAILURE (Status)) 111243044Sjkim { 112243044Sjkim return (Status); 113243044Sjkim } 114243044Sjkim break; 115243044Sjkim 116243044Sjkim /* We don't need to do anything for these deferred opcodes */ 117243044Sjkim 118243044Sjkim case AML_REGION_OP: 119243044Sjkim case AML_DATA_REGION_OP: 120243044Sjkim case AML_CREATE_QWORD_FIELD_OP: 121243044Sjkim case AML_CREATE_DWORD_FIELD_OP: 122243044Sjkim case AML_CREATE_WORD_FIELD_OP: 123243044Sjkim case AML_CREATE_BYTE_FIELD_OP: 124243044Sjkim case AML_CREATE_BIT_FIELD_OP: 125243044Sjkim case AML_CREATE_FIELD_OP: 126243044Sjkim case AML_BANK_FIELD_OP: 127243044Sjkim 128243044Sjkim break; 129243044Sjkim 130243044Sjkim default: 131243044Sjkim ACPI_ERROR ((AE_INFO, "Unhandled deferred AML opcode [0x%.4X]", 132243044Sjkim Op->Common.AmlOpcode)); 133243044Sjkim break; 134243044Sjkim } 135243044Sjkim 136243044Sjkim Op = AcpiPsGetDepthNext (Root, Op); 137243044Sjkim } 138243044Sjkim 139243044Sjkim return (AE_OK); 140243044Sjkim} 141243044Sjkim 142243044Sjkim 143243044Sjkim/****************************************************************************** 144243044Sjkim * 145243044Sjkim * FUNCTION: AcpiDmDeferredParse 146243044Sjkim * 147243044Sjkim * PARAMETERS: Op - Root Op of the deferred opcode 148243044Sjkim * Aml - Pointer to the raw AML 149243044Sjkim * AmlLength - Length of the AML 150243044Sjkim * 151243044Sjkim * RETURN: Status 152243044Sjkim * 153243044Sjkim * DESCRIPTION: Parse one deferred opcode 154243044Sjkim * (Methods, operation regions, etc.) 155243044Sjkim * 156243044Sjkim *****************************************************************************/ 157243044Sjkim 158243044Sjkimstatic ACPI_STATUS 159243044SjkimAcpiDmDeferredParse ( 160243044Sjkim ACPI_PARSE_OBJECT *Op, 161243044Sjkim UINT8 *Aml, 162243044Sjkim UINT32 AmlLength) 163243044Sjkim{ 164243044Sjkim ACPI_WALK_STATE *WalkState; 165243044Sjkim ACPI_STATUS Status; 166243044Sjkim ACPI_PARSE_OBJECT *SearchOp; 167243044Sjkim ACPI_PARSE_OBJECT *StartOp; 168243044Sjkim UINT32 BaseAmlOffset; 169243044Sjkim ACPI_PARSE_OBJECT *NewRootOp; 170243044Sjkim ACPI_PARSE_OBJECT *ExtraOp; 171243044Sjkim 172243044Sjkim 173243044Sjkim ACPI_FUNCTION_TRACE (DmDeferredParse); 174243044Sjkim 175243044Sjkim 176243044Sjkim if (!Aml || !AmlLength) 177243044Sjkim { 178243044Sjkim return_ACPI_STATUS (AE_OK); 179243044Sjkim } 180243044Sjkim 181243044Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing deferred opcode %s [%4.4s]\n", 182243044Sjkim Op->Common.AmlOpName, (char *) &Op->Named.Name)); 183243044Sjkim 184243044Sjkim /* Need a new walk state to parse the AML */ 185243044Sjkim 186243044Sjkim WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL); 187243044Sjkim if (!WalkState) 188243044Sjkim { 189243044Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 190243044Sjkim } 191243044Sjkim 192243044Sjkim Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Aml, 193243044Sjkim AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 194243044Sjkim if (ACPI_FAILURE (Status)) 195243044Sjkim { 196243044Sjkim return_ACPI_STATUS (Status); 197243044Sjkim } 198243044Sjkim 199243044Sjkim /* Parse the AML for this deferred opcode */ 200243044Sjkim 201243044Sjkim WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 202243044Sjkim WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; 203243044Sjkim Status = AcpiPsParseAml (WalkState); 204243044Sjkim 205243044Sjkim /* 206243044Sjkim * We need to update all of the AML offsets, since the parser thought 207243044Sjkim * that the method began at offset zero. In reality, it began somewhere 208243044Sjkim * within the ACPI table, at the BaseAmlOffset. Walk the entire tree that 209243044Sjkim * was just created and update the AmlOffset in each Op. 210243044Sjkim */ 211243044Sjkim BaseAmlOffset = (Op->Common.Value.Arg)->Common.AmlOffset + 1; 212243044Sjkim StartOp = (Op->Common.Value.Arg)->Common.Next; 213243044Sjkim SearchOp = StartOp; 214243044Sjkim 215243044Sjkim while (SearchOp) 216243044Sjkim { 217243044Sjkim SearchOp->Common.AmlOffset += BaseAmlOffset; 218243044Sjkim SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); 219243044Sjkim } 220243044Sjkim 221243044Sjkim /* 222243044Sjkim * For Buffer and Package opcodes, link the newly parsed subtree 223243044Sjkim * into the main parse tree 224243044Sjkim */ 225243044Sjkim switch (Op->Common.AmlOpcode) 226243044Sjkim { 227243044Sjkim case AML_BUFFER_OP: 228243044Sjkim case AML_PACKAGE_OP: 229243044Sjkim case AML_VAR_PACKAGE_OP: 230243044Sjkim 231243044Sjkim switch (Op->Common.AmlOpcode) 232243044Sjkim { 233243044Sjkim case AML_PACKAGE_OP: 234243044Sjkim 235243044Sjkim ExtraOp = Op->Common.Value.Arg; 236243044Sjkim NewRootOp = ExtraOp->Common.Next; 237243044Sjkim ACPI_FREE (ExtraOp); 238243044Sjkim break; 239243044Sjkim 240243044Sjkim case AML_VAR_PACKAGE_OP: 241243044Sjkim case AML_BUFFER_OP: 242243044Sjkim default: 243243044Sjkim 244243044Sjkim NewRootOp = Op->Common.Value.Arg; 245243044Sjkim break; 246243044Sjkim } 247243044Sjkim 248243044Sjkim Op->Common.Value.Arg = NewRootOp->Common.Value.Arg; 249243044Sjkim 250243044Sjkim /* Must point all parents to the main tree */ 251243044Sjkim 252243044Sjkim StartOp = Op; 253243044Sjkim SearchOp = StartOp; 254243044Sjkim while (SearchOp) 255243044Sjkim { 256243044Sjkim if (SearchOp->Common.Parent == NewRootOp) 257243044Sjkim { 258243044Sjkim SearchOp->Common.Parent = Op; 259243044Sjkim } 260243044Sjkim 261243044Sjkim SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); 262243044Sjkim } 263243044Sjkim 264243044Sjkim ACPI_FREE (NewRootOp); 265243044Sjkim break; 266243044Sjkim 267243044Sjkim default: 268243044Sjkim break; 269243044Sjkim } 270243044Sjkim 271243044Sjkim return_ACPI_STATUS (AE_OK); 272243044Sjkim} 273