167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: dswstate - Dispatcher parse tree walk management routines 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8298714Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 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. 2567754Smsmith * 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. 2967754Smsmith * 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 */ 4367754Smsmith 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 47193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 48193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 4967754Smsmith 5077424Smsmith#define _COMPONENT ACPI_DISPATCHER 5191116Smsmith ACPI_MODULE_NAME ("dswstate") 5267754Smsmith 53151937Sjkim/* Local prototypes */ 5467754Smsmith 55167802Sjkimstatic ACPI_STATUS 56167802SjkimAcpiDsResultStackPush ( 57151937Sjkim ACPI_WALK_STATE *WalkState); 5867754Smsmith 59167802Sjkimstatic ACPI_STATUS 60167802SjkimAcpiDsResultStackPop ( 61151937Sjkim ACPI_WALK_STATE *WalkState); 6267754Smsmith 6377424Smsmith 6467754Smsmith/******************************************************************************* 6567754Smsmith * 66167802Sjkim * FUNCTION: AcpiDsResultPop 6767754Smsmith * 6867754Smsmith * PARAMETERS: Object - Where to return the popped object 6967754Smsmith * WalkState - Current Walk state 7067754Smsmith * 7167754Smsmith * RETURN: Status 7267754Smsmith * 73167802Sjkim * DESCRIPTION: Pop an object off the top of this walk's result stack 7467754Smsmith * 7567754Smsmith ******************************************************************************/ 7667754Smsmith 7767754SmsmithACPI_STATUS 78167802SjkimAcpiDsResultPop ( 7967754Smsmith ACPI_OPERAND_OBJECT **Object, 8067754Smsmith ACPI_WALK_STATE *WalkState) 8167754Smsmith{ 82193267Sjkim UINT32 Index; 8369746Smsmith ACPI_GENERIC_STATE *State; 84167802Sjkim ACPI_STATUS Status; 8567754Smsmith 8667754Smsmith 87167802Sjkim ACPI_FUNCTION_NAME (DsResultPop); 8877424Smsmith 8977424Smsmith 9069746Smsmith State = WalkState->Results; 91167802Sjkim 92167802Sjkim /* Incorrect state of result stack */ 93167802Sjkim 94167802Sjkim if (State && !WalkState->ResultCount) 9569746Smsmith { 96167802Sjkim ACPI_ERROR ((AE_INFO, "No results on result stack")); 97167802Sjkim return (AE_AML_INTERNAL); 9869746Smsmith } 9967754Smsmith 100167802Sjkim if (!State && WalkState->ResultCount) 10167754Smsmith { 102167802Sjkim ACPI_ERROR ((AE_INFO, "No result state for result stack")); 103167802Sjkim return (AE_AML_INTERNAL); 10469746Smsmith } 10569746Smsmith 106167802Sjkim /* Empty result stack */ 10769746Smsmith 108167802Sjkim if (!State) 10969746Smsmith { 110167802Sjkim ACPI_ERROR ((AE_INFO, "Result stack is empty! State=%p", WalkState)); 11171867Smsmith return (AE_AML_NO_RETURN_VALUE); 11267754Smsmith } 11367754Smsmith 114167802Sjkim /* Return object of the top element and clean that top element result stack */ 11567754Smsmith 116167802Sjkim WalkState->ResultCount--; 117193267Sjkim Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM; 11867754Smsmith 11969746Smsmith *Object = State->Results.ObjDesc [Index]; 120167802Sjkim if (!*Object) 12169746Smsmith { 122167802Sjkim ACPI_ERROR ((AE_INFO, "No result objects on result stack, State=%p", 12369746Smsmith WalkState)); 12471867Smsmith return (AE_AML_NO_RETURN_VALUE); 12569746Smsmith } 12669746Smsmith 127167802Sjkim State->Results.ObjDesc [Index] = NULL; 128167802Sjkim if (Index == 0) 12969746Smsmith { 130167802Sjkim Status = AcpiDsResultStackPop (WalkState); 131167802Sjkim if (ACPI_FAILURE (Status)) 13269746Smsmith { 133167802Sjkim return (Status); 13469746Smsmith } 13569746Smsmith } 13669746Smsmith 137167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 138167802Sjkim "Obj=%p [%s] Index=%X State=%p Num=%X\n", *Object, 139167802Sjkim AcpiUtGetObjectTypeName (*Object), 140193267Sjkim Index, WalkState, WalkState->ResultCount)); 141167802Sjkim 142167802Sjkim return (AE_OK); 14369746Smsmith} 14469746Smsmith 145123315Snjl 14669746Smsmith/******************************************************************************* 14769746Smsmith * 148167802Sjkim * FUNCTION: AcpiDsResultPush 14969746Smsmith * 15069746Smsmith * PARAMETERS: Object - Where to return the popped object 15169746Smsmith * WalkState - Current Walk state 15269746Smsmith * 15369746Smsmith * RETURN: Status 15469746Smsmith * 155167802Sjkim * DESCRIPTION: Push an object onto the current result stack 15669746Smsmith * 15769746Smsmith ******************************************************************************/ 15869746Smsmith 15969746SmsmithACPI_STATUS 160167802SjkimAcpiDsResultPush ( 161167802Sjkim ACPI_OPERAND_OBJECT *Object, 16269746Smsmith ACPI_WALK_STATE *WalkState) 16369746Smsmith{ 164167802Sjkim ACPI_GENERIC_STATE *State; 165167802Sjkim ACPI_STATUS Status; 166193267Sjkim UINT32 Index; 16769746Smsmith 16869746Smsmith 169167802Sjkim ACPI_FUNCTION_NAME (DsResultPush); 17077424Smsmith 17177424Smsmith 172167802Sjkim if (WalkState->ResultCount > WalkState->ResultSize) 17369746Smsmith { 174167802Sjkim ACPI_ERROR ((AE_INFO, "Result stack is full")); 175167802Sjkim return (AE_AML_INTERNAL); 17669746Smsmith } 177167802Sjkim else if (WalkState->ResultCount == WalkState->ResultSize) 17869746Smsmith { 179167802Sjkim /* Extend the result stack */ 18069746Smsmith 181167802Sjkim Status = AcpiDsResultStackPush (WalkState); 182167802Sjkim if (ACPI_FAILURE (Status)) 183167802Sjkim { 184167802Sjkim ACPI_ERROR ((AE_INFO, "Failed to extend the result stack")); 185167802Sjkim return (Status); 186167802Sjkim } 18769746Smsmith } 18869746Smsmith 189167802Sjkim if (!(WalkState->ResultCount < WalkState->ResultSize)) 19067754Smsmith { 191167802Sjkim ACPI_ERROR ((AE_INFO, "No free elements in result stack")); 192167802Sjkim return (AE_AML_INTERNAL); 19367754Smsmith } 19467754Smsmith 19569746Smsmith State = WalkState->Results; 19669746Smsmith if (!State) 19769746Smsmith { 198167802Sjkim ACPI_ERROR ((AE_INFO, "No result stack frame during push")); 19971867Smsmith return (AE_AML_INTERNAL); 20069746Smsmith } 20169746Smsmith 20269746Smsmith if (!Object) 20369746Smsmith { 204167802Sjkim ACPI_ERROR ((AE_INFO, 205204773Sjkim "Null Object! Obj=%p State=%p Num=%u", 206167802Sjkim Object, WalkState, WalkState->ResultCount)); 20769746Smsmith return (AE_BAD_PARAMETER); 20869746Smsmith } 20969746Smsmith 210167802Sjkim /* Assign the address of object to the top free element of result stack */ 21169746Smsmith 212193267Sjkim Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM; 213167802Sjkim State->Results.ObjDesc [Index] = Object; 214167802Sjkim WalkState->ResultCount++; 215167802Sjkim 21682367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n", 217167802Sjkim Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object), 218167802Sjkim WalkState, WalkState->ResultCount, WalkState->CurrentResult)); 21967754Smsmith 22067754Smsmith return (AE_OK); 22167754Smsmith} 22267754Smsmith 22367754Smsmith 22467754Smsmith/******************************************************************************* 22567754Smsmith * 22669746Smsmith * FUNCTION: AcpiDsResultStackPush 22769746Smsmith * 228123315Snjl * PARAMETERS: WalkState - Current Walk state 22969746Smsmith * 23069746Smsmith * RETURN: Status 23169746Smsmith * 232167802Sjkim * DESCRIPTION: Push an object onto the WalkState result stack 23369746Smsmith * 23469746Smsmith ******************************************************************************/ 23569746Smsmith 236167802Sjkimstatic ACPI_STATUS 23769746SmsmithAcpiDsResultStackPush ( 23869746Smsmith ACPI_WALK_STATE *WalkState) 23969746Smsmith{ 24069746Smsmith ACPI_GENERIC_STATE *State; 24169746Smsmith 24270243Smsmith 243167802Sjkim ACPI_FUNCTION_NAME (DsResultStackPush); 24482367Smsmith 245167802Sjkim 246167802Sjkim /* Check for stack overflow */ 247167802Sjkim 248193267Sjkim if (((UINT32) WalkState->ResultSize + ACPI_RESULTS_FRAME_OBJ_NUM) > 249167802Sjkim ACPI_RESULTS_OBJ_NUM_MAX) 250167802Sjkim { 251204773Sjkim ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%u", 252167802Sjkim WalkState, WalkState->ResultSize)); 253167802Sjkim return (AE_STACK_OVERFLOW); 254167802Sjkim } 255167802Sjkim 25677424Smsmith State = AcpiUtCreateGenericState (); 25769746Smsmith if (!State) 25869746Smsmith { 25969746Smsmith return (AE_NO_MEMORY); 26069746Smsmith } 26169746Smsmith 262167802Sjkim State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_RESULT; 26377424Smsmith AcpiUtPushGenericState (&WalkState->Results, State); 26470243Smsmith 265167802Sjkim /* Increase the length of the result stack by the length of frame */ 266167802Sjkim 267167802Sjkim WalkState->ResultSize += ACPI_RESULTS_FRAME_OBJ_NUM; 268167802Sjkim 26982367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n", 27069746Smsmith State, WalkState)); 27169746Smsmith 27269746Smsmith return (AE_OK); 27369746Smsmith} 27469746Smsmith 27569746Smsmith 27669746Smsmith/******************************************************************************* 27769746Smsmith * 27869746Smsmith * FUNCTION: AcpiDsResultStackPop 27969746Smsmith * 28069746Smsmith * PARAMETERS: WalkState - Current Walk state 28169746Smsmith * 28269746Smsmith * RETURN: Status 28369746Smsmith * 284167802Sjkim * DESCRIPTION: Pop an object off of the WalkState result stack 28569746Smsmith * 28669746Smsmith ******************************************************************************/ 28769746Smsmith 288167802Sjkimstatic ACPI_STATUS 28969746SmsmithAcpiDsResultStackPop ( 29069746Smsmith ACPI_WALK_STATE *WalkState) 29169746Smsmith{ 29269746Smsmith ACPI_GENERIC_STATE *State; 29369746Smsmith 29469746Smsmith 295167802Sjkim ACPI_FUNCTION_NAME (DsResultStackPop); 29682367Smsmith 297167802Sjkim 29869746Smsmith /* Check for stack underflow */ 29969746Smsmith 30069746Smsmith if (WalkState->Results == NULL) 30169746Smsmith { 302298714Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 303298714Sjkim "Result stack underflow - State=%p\n", WalkState)); 30469746Smsmith return (AE_AML_NO_OPERAND); 30569746Smsmith } 30669746Smsmith 307167802Sjkim if (WalkState->ResultSize < ACPI_RESULTS_FRAME_OBJ_NUM) 308167802Sjkim { 309167802Sjkim ACPI_ERROR ((AE_INFO, "Insufficient result stack size")); 310167802Sjkim return (AE_AML_INTERNAL); 311167802Sjkim } 312167802Sjkim 31377424Smsmith State = AcpiUtPopGenericState (&WalkState->Results); 314167802Sjkim AcpiUtDeleteGenericState (State); 31569746Smsmith 316167802Sjkim /* Decrease the length of result stack by the length of frame */ 317167802Sjkim 318167802Sjkim WalkState->ResultSize -= ACPI_RESULTS_FRAME_OBJ_NUM; 319167802Sjkim 32082367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 32182367Smsmith "Result=%p RemainingResults=%X State=%p\n", 322167802Sjkim State, WalkState->ResultCount, WalkState)); 32369746Smsmith 32469746Smsmith return (AE_OK); 32569746Smsmith} 32669746Smsmith 32769746Smsmith 32869746Smsmith/******************************************************************************* 32969746Smsmith * 33067754Smsmith * FUNCTION: AcpiDsObjStackPush 33167754Smsmith * 33267754Smsmith * PARAMETERS: Object - Object to push 33367754Smsmith * WalkState - Current Walk state 33467754Smsmith * 33567754Smsmith * RETURN: Status 33667754Smsmith * 33767754Smsmith * DESCRIPTION: Push an object onto this walk's object/operand stack 33867754Smsmith * 33967754Smsmith ******************************************************************************/ 34067754Smsmith 34167754SmsmithACPI_STATUS 34267754SmsmithAcpiDsObjStackPush ( 34367754Smsmith void *Object, 34467754Smsmith ACPI_WALK_STATE *WalkState) 34567754Smsmith{ 346167802Sjkim ACPI_FUNCTION_NAME (DsObjStackPush); 34767754Smsmith 34867754Smsmith 34967754Smsmith /* Check for stack overflow */ 35067754Smsmith 351114237Snjl if (WalkState->NumOperands >= ACPI_OBJ_NUM_OPERANDS) 35267754Smsmith { 353167802Sjkim ACPI_ERROR ((AE_INFO, 354204773Sjkim "Object stack overflow! Obj=%p State=%p #Ops=%u", 35567754Smsmith Object, WalkState, WalkState->NumOperands)); 35667754Smsmith return (AE_STACK_OVERFLOW); 35767754Smsmith } 35867754Smsmith 35967754Smsmith /* Put the object onto the stack */ 36067754Smsmith 361167802Sjkim WalkState->Operands [WalkState->OperandIndex] = Object; 36267754Smsmith WalkState->NumOperands++; 36367754Smsmith 364167802Sjkim /* For the usual order of filling the operand stack */ 365167802Sjkim 366167802Sjkim WalkState->OperandIndex++; 367167802Sjkim 36882367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", 369167802Sjkim Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object), 370167802Sjkim WalkState, WalkState->NumOperands)); 37167754Smsmith 37267754Smsmith return (AE_OK); 37367754Smsmith} 37467754Smsmith 37567754Smsmith 37667754Smsmith/******************************************************************************* 37767754Smsmith * 37867754Smsmith * FUNCTION: AcpiDsObjStackPop 37967754Smsmith * 38067754Smsmith * PARAMETERS: PopCount - Number of objects/entries to pop 38167754Smsmith * WalkState - Current Walk state 38267754Smsmith * 38367754Smsmith * RETURN: Status 38467754Smsmith * 385241973Sjkim * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT 38667754Smsmith * deleted by this routine. 38767754Smsmith * 38867754Smsmith ******************************************************************************/ 38967754Smsmith 39067754SmsmithACPI_STATUS 39167754SmsmithAcpiDsObjStackPop ( 39267754Smsmith UINT32 PopCount, 39367754Smsmith ACPI_WALK_STATE *WalkState) 39467754Smsmith{ 39567754Smsmith UINT32 i; 39667754Smsmith 39767754Smsmith 398167802Sjkim ACPI_FUNCTION_NAME (DsObjStackPop); 39982367Smsmith 400167802Sjkim 40167754Smsmith for (i = 0; i < PopCount; i++) 40267754Smsmith { 40367754Smsmith /* Check for stack underflow */ 40467754Smsmith 40567754Smsmith if (WalkState->NumOperands == 0) 40667754Smsmith { 407167802Sjkim ACPI_ERROR ((AE_INFO, 408204773Sjkim "Object stack underflow! Count=%X State=%p #Ops=%u", 40967754Smsmith PopCount, WalkState, WalkState->NumOperands)); 41067754Smsmith return (AE_STACK_UNDERFLOW); 41167754Smsmith } 41267754Smsmith 41367754Smsmith /* Just set the stack entry to null */ 41467754Smsmith 41567754Smsmith WalkState->NumOperands--; 41667754Smsmith WalkState->Operands [WalkState->NumOperands] = NULL; 41767754Smsmith } 41867754Smsmith 419204773Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n", 420167802Sjkim PopCount, WalkState, WalkState->NumOperands)); 42167754Smsmith 42267754Smsmith return (AE_OK); 42367754Smsmith} 42467754Smsmith 42567754Smsmith 42667754Smsmith/******************************************************************************* 42767754Smsmith * 42867754Smsmith * FUNCTION: AcpiDsObjStackPopAndDelete 42967754Smsmith * 43067754Smsmith * PARAMETERS: PopCount - Number of objects/entries to pop 43167754Smsmith * WalkState - Current Walk state 43267754Smsmith * 43367754Smsmith * RETURN: Status 43467754Smsmith * 43567754Smsmith * DESCRIPTION: Pop this walk's object stack and delete each object that is 43667754Smsmith * popped off. 43767754Smsmith * 43867754Smsmith ******************************************************************************/ 43967754Smsmith 440167802Sjkimvoid 44167754SmsmithAcpiDsObjStackPopAndDelete ( 44267754Smsmith UINT32 PopCount, 44367754Smsmith ACPI_WALK_STATE *WalkState) 44467754Smsmith{ 445193267Sjkim INT32 i; 44667754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 44767754Smsmith 448123315Snjl 449167802Sjkim ACPI_FUNCTION_NAME (DsObjStackPopAndDelete); 45067754Smsmith 45182367Smsmith 452167802Sjkim if (PopCount == 0) 45367754Smsmith { 454167802Sjkim return; 455167802Sjkim } 45667754Smsmith 457193267Sjkim for (i = (INT32) PopCount - 1; i >= 0; i--) 458167802Sjkim { 45967754Smsmith if (WalkState->NumOperands == 0) 46067754Smsmith { 461167802Sjkim return; 46267754Smsmith } 46367754Smsmith 46467754Smsmith /* Pop the stack and delete an object if present in this stack entry */ 46567754Smsmith 46667754Smsmith WalkState->NumOperands--; 467167802Sjkim ObjDesc = WalkState->Operands [i]; 46867754Smsmith if (ObjDesc) 46967754Smsmith { 470167802Sjkim AcpiUtRemoveReference (WalkState->Operands [i]); 471167802Sjkim WalkState->Operands [i] = NULL; 47267754Smsmith } 47367754Smsmith } 47467754Smsmith 47582367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n", 476167802Sjkim PopCount, WalkState, WalkState->NumOperands)); 47767754Smsmith} 47867754Smsmith 47967754Smsmith 48067754Smsmith/******************************************************************************* 48167754Smsmith * 48267754Smsmith * FUNCTION: AcpiDsGetCurrentWalkState 48367754Smsmith * 48487031Smsmith * PARAMETERS: Thread - Get current active state for this Thread 48567754Smsmith * 48667754Smsmith * RETURN: Pointer to the current walk state 48767754Smsmith * 48867754Smsmith * DESCRIPTION: Get the walk state that is at the head of the list (the "current" 48987031Smsmith * walk state.) 49067754Smsmith * 49167754Smsmith ******************************************************************************/ 49267754Smsmith 49367754SmsmithACPI_WALK_STATE * 49467754SmsmithAcpiDsGetCurrentWalkState ( 49587031Smsmith ACPI_THREAD_STATE *Thread) 49667754Smsmith{ 497167802Sjkim ACPI_FUNCTION_NAME (DsGetCurrentWalkState); 49867754Smsmith 49982367Smsmith 50087031Smsmith if (!Thread) 50167754Smsmith { 50267754Smsmith return (NULL); 50367754Smsmith } 50467754Smsmith 505114237Snjl ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current WalkState %p\n", 50687031Smsmith Thread->WalkStateList)); 50787031Smsmith 50887031Smsmith return (Thread->WalkStateList); 50967754Smsmith} 51067754Smsmith 51167754Smsmith 51267754Smsmith/******************************************************************************* 51367754Smsmith * 51467754Smsmith * FUNCTION: AcpiDsPushWalkState 51567754Smsmith * 51667754Smsmith * PARAMETERS: WalkState - State to push 517151937Sjkim * Thread - Thread state object 51867754Smsmith * 51967754Smsmith * RETURN: None 52067754Smsmith * 521167802Sjkim * DESCRIPTION: Place the Thread state at the head of the state list 52267754Smsmith * 52367754Smsmith ******************************************************************************/ 52467754Smsmith 52584491Smsmithvoid 52667754SmsmithAcpiDsPushWalkState ( 52767754Smsmith ACPI_WALK_STATE *WalkState, 52887031Smsmith ACPI_THREAD_STATE *Thread) 52967754Smsmith{ 530167802Sjkim ACPI_FUNCTION_TRACE (DsPushWalkState); 53167754Smsmith 53267754Smsmith 533167802Sjkim WalkState->Next = Thread->WalkStateList; 53487031Smsmith Thread->WalkStateList = WalkState; 53567754Smsmith 53667754Smsmith return_VOID; 53767754Smsmith} 53867754Smsmith 53967754Smsmith 54067754Smsmith/******************************************************************************* 54167754Smsmith * 54267754Smsmith * FUNCTION: AcpiDsPopWalkState 54367754Smsmith * 544151937Sjkim * PARAMETERS: Thread - Current thread state 54567754Smsmith * 546151937Sjkim * RETURN: A WalkState object popped from the thread's stack 54767754Smsmith * 54867754Smsmith * DESCRIPTION: Remove and return the walkstate object that is at the head of 549241973Sjkim * the walk stack for the given walk list. NULL indicates that 55067754Smsmith * the list is empty. 55167754Smsmith * 55267754Smsmith ******************************************************************************/ 55367754Smsmith 55467754SmsmithACPI_WALK_STATE * 55567754SmsmithAcpiDsPopWalkState ( 55687031Smsmith ACPI_THREAD_STATE *Thread) 55767754Smsmith{ 55867754Smsmith ACPI_WALK_STATE *WalkState; 55967754Smsmith 56067754Smsmith 561167802Sjkim ACPI_FUNCTION_TRACE (DsPopWalkState); 56267754Smsmith 56367754Smsmith 56487031Smsmith WalkState = Thread->WalkStateList; 56567754Smsmith 56667754Smsmith if (WalkState) 56767754Smsmith { 56867754Smsmith /* Next walk state becomes the current walk state */ 56967754Smsmith 57087031Smsmith Thread->WalkStateList = WalkState->Next; 57167754Smsmith 57267754Smsmith /* 57367754Smsmith * Don't clear the NEXT field, this serves as an indicator 57467754Smsmith * that there is a parent WALK STATE 575151937Sjkim * Do Not: WalkState->Next = NULL; 57667754Smsmith */ 57767754Smsmith } 57867754Smsmith 57967754Smsmith return_PTR (WalkState); 58067754Smsmith} 58167754Smsmith 58267754Smsmith 58367754Smsmith/******************************************************************************* 58467754Smsmith * 58567754Smsmith * FUNCTION: AcpiDsCreateWalkState 58667754Smsmith * 587151937Sjkim * PARAMETERS: OwnerId - ID for object creation 588151937Sjkim * Origin - Starting point for this walk 589167802Sjkim * MethodDesc - Method object 59087031Smsmith * Thread - Current thread state 59167754Smsmith * 59267754Smsmith * RETURN: Pointer to the new walk state. 59367754Smsmith * 594241973Sjkim * DESCRIPTION: Allocate and initialize a new walk state. The current walk 59587031Smsmith * state is set to this new state. 59667754Smsmith * 59767754Smsmith ******************************************************************************/ 59867754Smsmith 59967754SmsmithACPI_WALK_STATE * 60067754SmsmithAcpiDsCreateWalkState ( 60167754Smsmith ACPI_OWNER_ID OwnerId, 60267754Smsmith ACPI_PARSE_OBJECT *Origin, 603167802Sjkim ACPI_OPERAND_OBJECT *MethodDesc, 60487031Smsmith ACPI_THREAD_STATE *Thread) 60567754Smsmith{ 60667754Smsmith ACPI_WALK_STATE *WalkState; 60767754Smsmith 60867754Smsmith 609167802Sjkim ACPI_FUNCTION_TRACE (DsCreateWalkState); 61067754Smsmith 61167754Smsmith 612167802Sjkim WalkState = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_WALK_STATE)); 61382367Smsmith if (!WalkState) 61467754Smsmith { 61582367Smsmith return_PTR (NULL); 61671867Smsmith } 61767754Smsmith 618167802Sjkim WalkState->DescriptorType = ACPI_DESC_TYPE_WALK; 619167802Sjkim WalkState->MethodDesc = MethodDesc; 620167802Sjkim WalkState->OwnerId = OwnerId; 621167802Sjkim WalkState->Origin = Origin; 622167802Sjkim WalkState->Thread = Thread; 62367754Smsmith 624102550Siwasaki WalkState->ParserState.StartOp = Origin; 625102550Siwasaki 62667754Smsmith /* Init the method args/local */ 62767754Smsmith 628100966Siwasaki#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) 62967754Smsmith AcpiDsMethodDataInit (WalkState); 63069450Smsmith#endif 63167754Smsmith 63267754Smsmith /* Put the new state at the head of the walk list */ 63367754Smsmith 63487031Smsmith if (Thread) 63584491Smsmith { 63687031Smsmith AcpiDsPushWalkState (WalkState, Thread); 63784491Smsmith } 63867754Smsmith 63967754Smsmith return_PTR (WalkState); 64067754Smsmith} 64167754Smsmith 64267754Smsmith 64367754Smsmith/******************************************************************************* 64467754Smsmith * 64584491Smsmith * FUNCTION: AcpiDsInitAmlWalk 64684491Smsmith * 64784491Smsmith * PARAMETERS: WalkState - New state to be initialized 648123315Snjl * Op - Current parse op 649123315Snjl * MethodNode - Control method NS node, if any 650123315Snjl * AmlStart - Start of AML 651123315Snjl * AmlLength - Length of AML 652151937Sjkim * Info - Method info block (params, etc.) 653123315Snjl * PassNumber - 1, 2, or 3 65484491Smsmith * 655123315Snjl * RETURN: Status 65684491Smsmith * 65784491Smsmith * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk 65884491Smsmith * 65984491Smsmith ******************************************************************************/ 66084491Smsmith 66184491SmsmithACPI_STATUS 66284491SmsmithAcpiDsInitAmlWalk ( 66384491Smsmith ACPI_WALK_STATE *WalkState, 66484491Smsmith ACPI_PARSE_OBJECT *Op, 66584491Smsmith ACPI_NAMESPACE_NODE *MethodNode, 66684491Smsmith UINT8 *AmlStart, 66784491Smsmith UINT32 AmlLength, 668167802Sjkim ACPI_EVALUATE_INFO *Info, 669151937Sjkim UINT8 PassNumber) 67084491Smsmith{ 67184491Smsmith ACPI_STATUS Status; 67284491Smsmith ACPI_PARSE_STATE *ParserState = &WalkState->ParserState; 673102550Siwasaki ACPI_PARSE_OBJECT *ExtraOp; 67484491Smsmith 67584491Smsmith 676167802Sjkim ACPI_FUNCTION_TRACE (DsInitAmlWalk); 67784491Smsmith 67884491Smsmith 679167802Sjkim WalkState->ParserState.Aml = 68084491Smsmith WalkState->ParserState.AmlStart = AmlStart; 681167802Sjkim WalkState->ParserState.AmlEnd = 682167802Sjkim WalkState->ParserState.PkgEnd = AmlStart + AmlLength; 68384491Smsmith 68484491Smsmith /* The NextOp of the NextWalk will be the beginning of the method */ 68584491Smsmith 686151937Sjkim WalkState->NextOp = NULL; 687151937Sjkim WalkState->PassNumber = PassNumber; 68884491Smsmith 689129684Snjl if (Info) 690129684Snjl { 691193267Sjkim WalkState->Params = Info->Parameters; 692193267Sjkim WalkState->CallerReturnDesc = &Info->ReturnObject; 693129684Snjl } 694129684Snjl 69584491Smsmith Status = AcpiPsInitScope (&WalkState->ParserState, Op); 69684491Smsmith if (ACPI_FAILURE (Status)) 69784491Smsmith { 69884491Smsmith return_ACPI_STATUS (Status); 69984491Smsmith } 70084491Smsmith 70184491Smsmith if (MethodNode) 70284491Smsmith { 703123315Snjl WalkState->ParserState.StartNode = MethodNode; 704167802Sjkim WalkState->WalkType = ACPI_WALK_METHOD; 705167802Sjkim WalkState->MethodNode = MethodNode; 706167802Sjkim WalkState->MethodDesc = AcpiNsGetAttachedObject (MethodNode); 70784491Smsmith 70884491Smsmith /* Push start scope on scope stack and make it current */ 70984491Smsmith 710298714Sjkim Status = AcpiDsScopeStackPush ( 711298714Sjkim MethodNode, ACPI_TYPE_METHOD, WalkState); 71284491Smsmith if (ACPI_FAILURE (Status)) 71384491Smsmith { 71484491Smsmith return_ACPI_STATUS (Status); 71584491Smsmith } 71684491Smsmith 71784491Smsmith /* Init the method arguments */ 71884491Smsmith 719151937Sjkim Status = AcpiDsMethodDataInitArgs (WalkState->Params, 720151937Sjkim ACPI_METHOD_NUM_ARGS, WalkState); 72199679Siwasaki if (ACPI_FAILURE (Status)) 72299679Siwasaki { 72399679Siwasaki return_ACPI_STATUS (Status); 72499679Siwasaki } 72584491Smsmith } 72684491Smsmith else 72784491Smsmith { 728114237Snjl /* 729102550Siwasaki * Setup the current scope. 730102550Siwasaki * Find a Named Op that has a namespace node associated with it. 731241973Sjkim * search upwards from this Op. Current scope is the first 732102550Siwasaki * Op with a namespace node. 733102550Siwasaki */ 734102550Siwasaki ExtraOp = ParserState->StartOp; 735102550Siwasaki while (ExtraOp && !ExtraOp->Common.Node) 736102550Siwasaki { 737102550Siwasaki ExtraOp = ExtraOp->Common.Parent; 738102550Siwasaki } 739123315Snjl 740102550Siwasaki if (!ExtraOp) 741102550Siwasaki { 742102550Siwasaki ParserState->StartNode = NULL; 743102550Siwasaki } 744102550Siwasaki else 745102550Siwasaki { 746102550Siwasaki ParserState->StartNode = ExtraOp->Common.Node; 747102550Siwasaki } 748114237Snjl 74984491Smsmith if (ParserState->StartNode) 75084491Smsmith { 75184491Smsmith /* Push start scope on scope stack and make it current */ 75284491Smsmith 75384491Smsmith Status = AcpiDsScopeStackPush (ParserState->StartNode, 754298714Sjkim ParserState->StartNode->Type, WalkState); 75584491Smsmith if (ACPI_FAILURE (Status)) 75684491Smsmith { 75784491Smsmith return_ACPI_STATUS (Status); 75884491Smsmith } 75984491Smsmith } 76084491Smsmith } 76184491Smsmith 76299679Siwasaki Status = AcpiDsInitCallbacks (WalkState, PassNumber); 76399679Siwasaki return_ACPI_STATUS (Status); 76484491Smsmith} 76584491Smsmith 76684491Smsmith 76784491Smsmith/******************************************************************************* 76884491Smsmith * 76967754Smsmith * FUNCTION: AcpiDsDeleteWalkState 77067754Smsmith * 77167754Smsmith * PARAMETERS: WalkState - State to delete 77267754Smsmith * 77367754Smsmith * RETURN: Status 77467754Smsmith * 77567754Smsmith * DESCRIPTION: Delete a walk state including all internal data structures 77667754Smsmith * 77767754Smsmith ******************************************************************************/ 77867754Smsmith 77967754Smsmithvoid 78067754SmsmithAcpiDsDeleteWalkState ( 78167754Smsmith ACPI_WALK_STATE *WalkState) 78267754Smsmith{ 78367754Smsmith ACPI_GENERIC_STATE *State; 78467754Smsmith 78567754Smsmith 786167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsDeleteWalkState, WalkState); 78767754Smsmith 78867754Smsmith 78967754Smsmith if (!WalkState) 79067754Smsmith { 791241973Sjkim return_VOID; 79267754Smsmith } 79367754Smsmith 794167802Sjkim if (WalkState->DescriptorType != ACPI_DESC_TYPE_WALK) 79567754Smsmith { 796167802Sjkim ACPI_ERROR ((AE_INFO, "%p is not a valid walk state", 797151937Sjkim WalkState)); 798241973Sjkim return_VOID; 79967754Smsmith } 80067754Smsmith 801167802Sjkim /* There should not be any open scopes */ 802167802Sjkim 80384491Smsmith if (WalkState->ParserState.Scope) 80484491Smsmith { 805167802Sjkim ACPI_ERROR ((AE_INFO, "%p walk still has a scope list", 806151937Sjkim WalkState)); 807167802Sjkim AcpiPsCleanupScope (&WalkState->ParserState); 80884491Smsmith } 80967754Smsmith 810123315Snjl /* Always must free any linked control states */ 81184491Smsmith 81267754Smsmith while (WalkState->ControlState) 81367754Smsmith { 81467754Smsmith State = WalkState->ControlState; 81567754Smsmith WalkState->ControlState = State->Common.Next; 81667754Smsmith 81777424Smsmith AcpiUtDeleteGenericState (State); 81867754Smsmith } 81967754Smsmith 82067754Smsmith /* Always must free any linked parse states */ 82167754Smsmith 82267754Smsmith while (WalkState->ScopeInfo) 82367754Smsmith { 82467754Smsmith State = WalkState->ScopeInfo; 82567754Smsmith WalkState->ScopeInfo = State->Common.Next; 82667754Smsmith 82777424Smsmith AcpiUtDeleteGenericState (State); 82867754Smsmith } 82967754Smsmith 83069746Smsmith /* Always must free any stacked result states */ 83169746Smsmith 83269746Smsmith while (WalkState->Results) 83369746Smsmith { 83469746Smsmith State = WalkState->Results; 83569746Smsmith WalkState->Results = State->Common.Next; 83669746Smsmith 83777424Smsmith AcpiUtDeleteGenericState (State); 83869746Smsmith } 83969746Smsmith 840167802Sjkim ACPI_FREE (WalkState); 84167754Smsmith return_VOID; 84267754Smsmith} 843