1243044Sjkim/****************************************************************************** 2243044Sjkim * 3243044Sjkim * Module Name: dmdeferred - Disassembly of deferred AML opcodes 4243044Sjkim * 5243044Sjkim *****************************************************************************/ 6243044Sjkim 7243044Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, 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 44243347Sjkim#include <contrib/dev/acpica/include/acpi.h> 45243347Sjkim#include <contrib/dev/acpica/include/accommon.h> 46243347Sjkim#include <contrib/dev/acpica/include/acdispat.h> 47243347Sjkim#include <contrib/dev/acpica/include/amlcode.h> 48243347Sjkim#include <contrib/dev/acpica/include/acdisasm.h> 49243347Sjkim#include <contrib/dev/acpica/include/acparser.h> 50243044Sjkim 51243044Sjkim#define _COMPONENT ACPI_CA_DISASSEMBLER 52243044Sjkim ACPI_MODULE_NAME ("dmdeferred") 53243044Sjkim 54243044Sjkim 55243044Sjkim/* Local prototypes */ 56243044Sjkim 57243044Sjkimstatic ACPI_STATUS 58243044SjkimAcpiDmDeferredParse ( 59243044Sjkim ACPI_PARSE_OBJECT *Op, 60243044Sjkim UINT8 *Aml, 61243044Sjkim UINT32 AmlLength); 62243044Sjkim 63243044Sjkim 64243044Sjkim/****************************************************************************** 65243044Sjkim * 66243044Sjkim * FUNCTION: AcpiDmParseDeferredOps 67243044Sjkim * 68243044Sjkim * PARAMETERS: Root - Root of the parse tree 69243044Sjkim * 70243044Sjkim * RETURN: Status 71243044Sjkim * 72243044Sjkim * DESCRIPTION: Parse the deferred opcodes (Methods, regions, etc.) 73243044Sjkim * 74243044Sjkim *****************************************************************************/ 75243044Sjkim 76243044SjkimACPI_STATUS 77243044SjkimAcpiDmParseDeferredOps ( 78243044Sjkim ACPI_PARSE_OBJECT *Root) 79243044Sjkim{ 80243044Sjkim const ACPI_OPCODE_INFO *OpInfo; 81243044Sjkim ACPI_PARSE_OBJECT *Op = Root; 82243044Sjkim ACPI_STATUS Status; 83243044Sjkim 84243044Sjkim 85245582Sjkim ACPI_FUNCTION_ENTRY (); 86243044Sjkim 87243044Sjkim 88243044Sjkim /* Traverse the entire parse tree */ 89243044Sjkim 90243044Sjkim while (Op) 91243044Sjkim { 92243044Sjkim OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 93243044Sjkim if (!(OpInfo->Flags & AML_DEFER)) 94243044Sjkim { 95243044Sjkim Op = AcpiPsGetDepthNext (Root, Op); 96243044Sjkim continue; 97243044Sjkim } 98243044Sjkim 99243044Sjkim /* Now we know we have a deferred opcode */ 100243044Sjkim 101243044Sjkim switch (Op->Common.AmlOpcode) 102243044Sjkim { 103243044Sjkim case AML_METHOD_OP: 104243044Sjkim case AML_BUFFER_OP: 105243044Sjkim case AML_PACKAGE_OP: 106243044Sjkim case AML_VAR_PACKAGE_OP: 107243044Sjkim 108306536Sjkim Status = AcpiDmDeferredParse ( 109306536Sjkim 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: 131250838Sjkim 132243044Sjkim ACPI_ERROR ((AE_INFO, "Unhandled deferred AML opcode [0x%.4X]", 133243044Sjkim Op->Common.AmlOpcode)); 134243044Sjkim break; 135243044Sjkim } 136243044Sjkim 137243044Sjkim Op = AcpiPsGetDepthNext (Root, Op); 138243044Sjkim } 139243044Sjkim 140243044Sjkim return (AE_OK); 141243044Sjkim} 142243044Sjkim 143243044Sjkim 144243044Sjkim/****************************************************************************** 145243044Sjkim * 146243044Sjkim * FUNCTION: AcpiDmDeferredParse 147243044Sjkim * 148243044Sjkim * PARAMETERS: Op - Root Op of the deferred opcode 149243044Sjkim * Aml - Pointer to the raw AML 150243044Sjkim * AmlLength - Length of the AML 151243044Sjkim * 152243044Sjkim * RETURN: Status 153243044Sjkim * 154243044Sjkim * DESCRIPTION: Parse one deferred opcode 155243044Sjkim * (Methods, operation regions, etc.) 156243044Sjkim * 157243044Sjkim *****************************************************************************/ 158243044Sjkim 159243044Sjkimstatic ACPI_STATUS 160243044SjkimAcpiDmDeferredParse ( 161243044Sjkim ACPI_PARSE_OBJECT *Op, 162243044Sjkim UINT8 *Aml, 163243044Sjkim UINT32 AmlLength) 164243044Sjkim{ 165243044Sjkim ACPI_WALK_STATE *WalkState; 166243044Sjkim ACPI_STATUS Status; 167243044Sjkim ACPI_PARSE_OBJECT *SearchOp; 168243044Sjkim ACPI_PARSE_OBJECT *StartOp; 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 StartOp = (Op->Common.Value.Arg)->Common.Next; 206243044Sjkim SearchOp = StartOp; 207243044Sjkim while (SearchOp) 208243044Sjkim { 209243044Sjkim SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); 210243044Sjkim } 211243044Sjkim 212243044Sjkim /* 213243044Sjkim * For Buffer and Package opcodes, link the newly parsed subtree 214243044Sjkim * into the main parse tree 215243044Sjkim */ 216243044Sjkim switch (Op->Common.AmlOpcode) 217243044Sjkim { 218243044Sjkim case AML_BUFFER_OP: 219243044Sjkim case AML_PACKAGE_OP: 220243044Sjkim case AML_VAR_PACKAGE_OP: 221243044Sjkim 222243044Sjkim switch (Op->Common.AmlOpcode) 223243044Sjkim { 224243044Sjkim case AML_PACKAGE_OP: 225243044Sjkim 226243044Sjkim ExtraOp = Op->Common.Value.Arg; 227243044Sjkim NewRootOp = ExtraOp->Common.Next; 228243044Sjkim ACPI_FREE (ExtraOp); 229243044Sjkim break; 230243044Sjkim 231243044Sjkim case AML_VAR_PACKAGE_OP: 232243044Sjkim case AML_BUFFER_OP: 233243044Sjkim default: 234243044Sjkim 235243044Sjkim NewRootOp = Op->Common.Value.Arg; 236243044Sjkim break; 237243044Sjkim } 238243044Sjkim 239243044Sjkim Op->Common.Value.Arg = NewRootOp->Common.Value.Arg; 240243044Sjkim 241243044Sjkim /* Must point all parents to the main tree */ 242243044Sjkim 243243044Sjkim StartOp = Op; 244243044Sjkim SearchOp = StartOp; 245243044Sjkim while (SearchOp) 246243044Sjkim { 247243044Sjkim if (SearchOp->Common.Parent == NewRootOp) 248243044Sjkim { 249243044Sjkim SearchOp->Common.Parent = Op; 250243044Sjkim } 251243044Sjkim 252243044Sjkim SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); 253243044Sjkim } 254243044Sjkim 255243044Sjkim ACPI_FREE (NewRootOp); 256243044Sjkim break; 257243044Sjkim 258243044Sjkim default: 259250838Sjkim 260243044Sjkim break; 261243044Sjkim } 262243044Sjkim 263243044Sjkim return_ACPI_STATUS (AE_OK); 264243044Sjkim} 265