1db2bae30SDana Myers /****************************************************************************** 2db2bae30SDana Myers * 3db2bae30SDana Myers * Module Name: dswstate - Dispatcher parse tree walk management routines 4db2bae30SDana Myers * 5db2bae30SDana Myers *****************************************************************************/ 6db2bae30SDana Myers 726f3cdf0SGordon Ross /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 9db2bae30SDana Myers * All rights reserved. 10db2bae30SDana Myers * 1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1326f3cdf0SGordon Ross * are met: 1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1626f3cdf0SGordon Ross * without modification. 1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2126f3cdf0SGordon Ross * binary redistribution. 2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2426f3cdf0SGordon Ross * from this software without specific prior written permission. 25db2bae30SDana Myers * 2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2826f3cdf0SGordon Ross * Software Foundation. 29db2bae30SDana Myers * 3026f3cdf0SGordon Ross * NO WARRANTY 3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4226f3cdf0SGordon Ross */ 43db2bae30SDana Myers 44db2bae30SDana Myers #include "acpi.h" 45aa2aa9a6SDana Myers #include "accommon.h" 46db2bae30SDana Myers #include "acparser.h" 47db2bae30SDana Myers #include "acdispat.h" 48db2bae30SDana Myers #include "acnamesp.h" 49db2bae30SDana Myers 50db2bae30SDana Myers #define _COMPONENT ACPI_DISPATCHER 51db2bae30SDana Myers ACPI_MODULE_NAME ("dswstate") 52db2bae30SDana Myers 53db2bae30SDana Myers /* Local prototypes */ 54db2bae30SDana Myers 55db2bae30SDana Myers static ACPI_STATUS 56db2bae30SDana Myers AcpiDsResultStackPush ( 57db2bae30SDana Myers ACPI_WALK_STATE *WalkState); 58db2bae30SDana Myers 59db2bae30SDana Myers static ACPI_STATUS 60db2bae30SDana Myers AcpiDsResultStackPop ( 61db2bae30SDana Myers ACPI_WALK_STATE *WalkState); 62db2bae30SDana Myers 63db2bae30SDana Myers 64db2bae30SDana Myers /******************************************************************************* 65db2bae30SDana Myers * 66db2bae30SDana Myers * FUNCTION: AcpiDsResultPop 67db2bae30SDana Myers * 68db2bae30SDana Myers * PARAMETERS: Object - Where to return the popped object 69db2bae30SDana Myers * WalkState - Current Walk state 70db2bae30SDana Myers * 71db2bae30SDana Myers * RETURN: Status 72db2bae30SDana Myers * 73db2bae30SDana Myers * DESCRIPTION: Pop an object off the top of this walk's result stack 74db2bae30SDana Myers * 75db2bae30SDana Myers ******************************************************************************/ 76db2bae30SDana Myers 77db2bae30SDana Myers ACPI_STATUS 78db2bae30SDana Myers AcpiDsResultPop ( 79db2bae30SDana Myers ACPI_OPERAND_OBJECT **Object, 80db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 81db2bae30SDana Myers { 82db2bae30SDana Myers UINT32 Index; 83db2bae30SDana Myers ACPI_GENERIC_STATE *State; 84db2bae30SDana Myers ACPI_STATUS Status; 85db2bae30SDana Myers 86db2bae30SDana Myers 87db2bae30SDana Myers ACPI_FUNCTION_NAME (DsResultPop); 88db2bae30SDana Myers 89db2bae30SDana Myers 90db2bae30SDana Myers State = WalkState->Results; 91db2bae30SDana Myers 92db2bae30SDana Myers /* Incorrect state of result stack */ 93db2bae30SDana Myers 94db2bae30SDana Myers if (State && !WalkState->ResultCount) 95db2bae30SDana Myers { 96db2bae30SDana Myers ACPI_ERROR ((AE_INFO, "No results on result stack")); 97db2bae30SDana Myers return (AE_AML_INTERNAL); 98db2bae30SDana Myers } 99db2bae30SDana Myers 100db2bae30SDana Myers if (!State && WalkState->ResultCount) 101db2bae30SDana Myers { 102db2bae30SDana Myers ACPI_ERROR ((AE_INFO, "No result state for result stack")); 103db2bae30SDana Myers return (AE_AML_INTERNAL); 104db2bae30SDana Myers } 105db2bae30SDana Myers 106db2bae30SDana Myers /* Empty result stack */ 107db2bae30SDana Myers 108db2bae30SDana Myers if (!State) 109db2bae30SDana Myers { 110db2bae30SDana Myers ACPI_ERROR ((AE_INFO, "Result stack is empty! State=%p", WalkState)); 111db2bae30SDana Myers return (AE_AML_NO_RETURN_VALUE); 112db2bae30SDana Myers } 113db2bae30SDana Myers 114db2bae30SDana Myers /* Return object of the top element and clean that top element result stack */ 115db2bae30SDana Myers 116db2bae30SDana Myers WalkState->ResultCount--; 117aa2aa9a6SDana Myers Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM; 118db2bae30SDana Myers 119db2bae30SDana Myers *Object = State->Results.ObjDesc [Index]; 120db2bae30SDana Myers if (!*Object) 121db2bae30SDana Myers { 122db2bae30SDana Myers ACPI_ERROR ((AE_INFO, "No result objects on result stack, State=%p", 123db2bae30SDana Myers WalkState)); 124db2bae30SDana Myers return (AE_AML_NO_RETURN_VALUE); 125db2bae30SDana Myers } 126db2bae30SDana Myers 127db2bae30SDana Myers State->Results.ObjDesc [Index] = NULL; 128db2bae30SDana Myers if (Index == 0) 129db2bae30SDana Myers { 130db2bae30SDana Myers Status = AcpiDsResultStackPop (WalkState); 131db2bae30SDana Myers if (ACPI_FAILURE (Status)) 132db2bae30SDana Myers { 133db2bae30SDana Myers return (Status); 134db2bae30SDana Myers } 135db2bae30SDana Myers } 136db2bae30SDana Myers 137db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 138db2bae30SDana Myers "Obj=%p [%s] Index=%X State=%p Num=%X\n", *Object, 139db2bae30SDana Myers AcpiUtGetObjectTypeName (*Object), 140db2bae30SDana Myers Index, WalkState, WalkState->ResultCount)); 141db2bae30SDana Myers 142db2bae30SDana Myers return (AE_OK); 143db2bae30SDana Myers } 144db2bae30SDana Myers 145db2bae30SDana Myers 146db2bae30SDana Myers /******************************************************************************* 147db2bae30SDana Myers * 148db2bae30SDana Myers * FUNCTION: AcpiDsResultPush 149db2bae30SDana Myers * 150db2bae30SDana Myers * PARAMETERS: Object - Where to return the popped object 151db2bae30SDana Myers * WalkState - Current Walk state 152db2bae30SDana Myers * 153db2bae30SDana Myers * RETURN: Status 154db2bae30SDana Myers * 155db2bae30SDana Myers * DESCRIPTION: Push an object onto the current result stack 156db2bae30SDana Myers * 157db2bae30SDana Myers ******************************************************************************/ 158db2bae30SDana Myers 159db2bae30SDana Myers ACPI_STATUS 160db2bae30SDana Myers AcpiDsResultPush ( 161db2bae30SDana Myers ACPI_OPERAND_OBJECT *Object, 162db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 163db2bae30SDana Myers { 164db2bae30SDana Myers ACPI_GENERIC_STATE *State; 165db2bae30SDana Myers ACPI_STATUS Status; 166db2bae30SDana Myers UINT32 Index; 167db2bae30SDana Myers 168db2bae30SDana Myers 169db2bae30SDana Myers ACPI_FUNCTION_NAME (DsResultPush); 170db2bae30SDana Myers 171db2bae30SDana Myers 172db2bae30SDana Myers if (WalkState->ResultCount > WalkState->ResultSize) 173db2bae30SDana Myers { 174db2bae30SDana Myers ACPI_ERROR ((AE_INFO, "Result stack is full")); 175db2bae30SDana Myers return (AE_AML_INTERNAL); 176db2bae30SDana Myers } 177db2bae30SDana Myers else if (WalkState->ResultCount == WalkState->ResultSize) 178db2bae30SDana Myers { 179db2bae30SDana Myers /* Extend the result stack */ 180db2bae30SDana Myers 181db2bae30SDana Myers Status = AcpiDsResultStackPush (WalkState); 182db2bae30SDana Myers if (ACPI_FAILURE (Status)) 183db2bae30SDana Myers { 184db2bae30SDana Myers ACPI_ERROR ((AE_INFO, "Failed to extend the result stack")); 185db2bae30SDana Myers return (Status); 186db2bae30SDana Myers } 187db2bae30SDana Myers } 188db2bae30SDana Myers 189db2bae30SDana Myers if (!(WalkState->ResultCount < WalkState->ResultSize)) 190db2bae30SDana Myers { 191db2bae30SDana Myers ACPI_ERROR ((AE_INFO, "No free elements in result stack")); 192db2bae30SDana Myers return (AE_AML_INTERNAL); 193db2bae30SDana Myers } 194db2bae30SDana Myers 195db2bae30SDana Myers State = WalkState->Results; 196db2bae30SDana Myers if (!State) 197db2bae30SDana Myers { 198db2bae30SDana Myers ACPI_ERROR ((AE_INFO, "No result stack frame during push")); 199db2bae30SDana Myers return (AE_AML_INTERNAL); 200db2bae30SDana Myers } 201db2bae30SDana Myers 202db2bae30SDana Myers if (!Object) 203db2bae30SDana Myers { 204db2bae30SDana Myers ACPI_ERROR ((AE_INFO, 20526f3cdf0SGordon Ross "Null Object! Obj=%p State=%p Num=%u", 206db2bae30SDana Myers Object, WalkState, WalkState->ResultCount)); 207db2bae30SDana Myers return (AE_BAD_PARAMETER); 208db2bae30SDana Myers } 209db2bae30SDana Myers 210db2bae30SDana Myers /* Assign the address of object to the top free element of result stack */ 211db2bae30SDana Myers 212aa2aa9a6SDana Myers Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM; 213db2bae30SDana Myers State->Results.ObjDesc [Index] = Object; 214db2bae30SDana Myers WalkState->ResultCount++; 215db2bae30SDana Myers 216db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n", 217db2bae30SDana Myers Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object), 218db2bae30SDana Myers WalkState, WalkState->ResultCount, WalkState->CurrentResult)); 219db2bae30SDana Myers 220db2bae30SDana Myers return (AE_OK); 221db2bae30SDana Myers } 222db2bae30SDana Myers 223db2bae30SDana Myers 224db2bae30SDana Myers /******************************************************************************* 225db2bae30SDana Myers * 226db2bae30SDana Myers * FUNCTION: AcpiDsResultStackPush 227db2bae30SDana Myers * 228db2bae30SDana Myers * PARAMETERS: WalkState - Current Walk state 229db2bae30SDana Myers * 230db2bae30SDana Myers * RETURN: Status 231db2bae30SDana Myers * 232db2bae30SDana Myers * DESCRIPTION: Push an object onto the WalkState result stack 233db2bae30SDana Myers * 234db2bae30SDana Myers ******************************************************************************/ 235db2bae30SDana Myers 236db2bae30SDana Myers static ACPI_STATUS 237db2bae30SDana Myers AcpiDsResultStackPush ( 238db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 239db2bae30SDana Myers { 240db2bae30SDana Myers ACPI_GENERIC_STATE *State; 241db2bae30SDana Myers 242db2bae30SDana Myers 243db2bae30SDana Myers ACPI_FUNCTION_NAME (DsResultStackPush); 244db2bae30SDana Myers 245db2bae30SDana Myers 246db2bae30SDana Myers /* Check for stack overflow */ 247db2bae30SDana Myers 248db2bae30SDana Myers if (((UINT32) WalkState->ResultSize + ACPI_RESULTS_FRAME_OBJ_NUM) > 249db2bae30SDana Myers ACPI_RESULTS_OBJ_NUM_MAX) 250db2bae30SDana Myers { 25126f3cdf0SGordon Ross ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%u", 252db2bae30SDana Myers WalkState, WalkState->ResultSize)); 253db2bae30SDana Myers return (AE_STACK_OVERFLOW); 254db2bae30SDana Myers } 255db2bae30SDana Myers 256db2bae30SDana Myers State = AcpiUtCreateGenericState (); 257db2bae30SDana Myers if (!State) 258db2bae30SDana Myers { 259db2bae30SDana Myers return (AE_NO_MEMORY); 260db2bae30SDana Myers } 261db2bae30SDana Myers 262db2bae30SDana Myers State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_RESULT; 263db2bae30SDana Myers AcpiUtPushGenericState (&WalkState->Results, State); 264db2bae30SDana Myers 265db2bae30SDana Myers /* Increase the length of the result stack by the length of frame */ 266db2bae30SDana Myers 267db2bae30SDana Myers WalkState->ResultSize += ACPI_RESULTS_FRAME_OBJ_NUM; 268db2bae30SDana Myers 269db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n", 270db2bae30SDana Myers State, WalkState)); 271db2bae30SDana Myers 272db2bae30SDana Myers return (AE_OK); 273db2bae30SDana Myers } 274db2bae30SDana Myers 275db2bae30SDana Myers 276db2bae30SDana Myers /******************************************************************************* 277db2bae30SDana Myers * 278db2bae30SDana Myers * FUNCTION: AcpiDsResultStackPop 279db2bae30SDana Myers * 280db2bae30SDana Myers * PARAMETERS: WalkState - Current Walk state 281db2bae30SDana Myers * 282db2bae30SDana Myers * RETURN: Status 283db2bae30SDana Myers * 284db2bae30SDana Myers * DESCRIPTION: Pop an object off of the WalkState result stack 285db2bae30SDana Myers * 286db2bae30SDana Myers ******************************************************************************/ 287db2bae30SDana Myers 288db2bae30SDana Myers static ACPI_STATUS 289db2bae30SDana Myers AcpiDsResultStackPop ( 290db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 291db2bae30SDana Myers { 292db2bae30SDana Myers ACPI_GENERIC_STATE *State; 293db2bae30SDana Myers 294db2bae30SDana Myers 295db2bae30SDana Myers ACPI_FUNCTION_NAME (DsResultStackPop); 296db2bae30SDana Myers 297db2bae30SDana Myers 298db2bae30SDana Myers /* Check for stack underflow */ 299db2bae30SDana Myers 300db2bae30SDana Myers if (WalkState->Results == NULL) 301db2bae30SDana Myers { 302*385cc6b4SJerry Jelinek ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 303*385cc6b4SJerry Jelinek "Result stack underflow - State=%p\n", WalkState)); 304db2bae30SDana Myers return (AE_AML_NO_OPERAND); 305db2bae30SDana Myers } 306db2bae30SDana Myers 307db2bae30SDana Myers if (WalkState->ResultSize < ACPI_RESULTS_FRAME_OBJ_NUM) 308db2bae30SDana Myers { 309db2bae30SDana Myers ACPI_ERROR ((AE_INFO, "Insufficient result stack size")); 310db2bae30SDana Myers return (AE_AML_INTERNAL); 311db2bae30SDana Myers } 312db2bae30SDana Myers 313db2bae30SDana Myers State = AcpiUtPopGenericState (&WalkState->Results); 314db2bae30SDana Myers AcpiUtDeleteGenericState (State); 315db2bae30SDana Myers 316db2bae30SDana Myers /* Decrease the length of result stack by the length of frame */ 317db2bae30SDana Myers 318db2bae30SDana Myers WalkState->ResultSize -= ACPI_RESULTS_FRAME_OBJ_NUM; 319db2bae30SDana Myers 320db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 321db2bae30SDana Myers "Result=%p RemainingResults=%X State=%p\n", 322db2bae30SDana Myers State, WalkState->ResultCount, WalkState)); 323db2bae30SDana Myers 324db2bae30SDana Myers return (AE_OK); 325db2bae30SDana Myers } 326db2bae30SDana Myers 327db2bae30SDana Myers 328db2bae30SDana Myers /******************************************************************************* 329db2bae30SDana Myers * 330db2bae30SDana Myers * FUNCTION: AcpiDsObjStackPush 331db2bae30SDana Myers * 332db2bae30SDana Myers * PARAMETERS: Object - Object to push 333db2bae30SDana Myers * WalkState - Current Walk state 334db2bae30SDana Myers * 335db2bae30SDana Myers * RETURN: Status 336db2bae30SDana Myers * 337db2bae30SDana Myers * DESCRIPTION: Push an object onto this walk's object/operand stack 338db2bae30SDana Myers * 339db2bae30SDana Myers ******************************************************************************/ 340db2bae30SDana Myers 341db2bae30SDana Myers ACPI_STATUS 342db2bae30SDana Myers AcpiDsObjStackPush ( 343db2bae30SDana Myers void *Object, 344db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 345db2bae30SDana Myers { 346db2bae30SDana Myers ACPI_FUNCTION_NAME (DsObjStackPush); 347db2bae30SDana Myers 348db2bae30SDana Myers 349db2bae30SDana Myers /* Check for stack overflow */ 350db2bae30SDana Myers 351db2bae30SDana Myers if (WalkState->NumOperands >= ACPI_OBJ_NUM_OPERANDS) 352db2bae30SDana Myers { 353db2bae30SDana Myers ACPI_ERROR ((AE_INFO, 35426f3cdf0SGordon Ross "Object stack overflow! Obj=%p State=%p #Ops=%u", 355db2bae30SDana Myers Object, WalkState, WalkState->NumOperands)); 356db2bae30SDana Myers return (AE_STACK_OVERFLOW); 357db2bae30SDana Myers } 358db2bae30SDana Myers 359db2bae30SDana Myers /* Put the object onto the stack */ 360db2bae30SDana Myers 361db2bae30SDana Myers WalkState->Operands [WalkState->OperandIndex] = Object; 362db2bae30SDana Myers WalkState->NumOperands++; 363db2bae30SDana Myers 364db2bae30SDana Myers /* For the usual order of filling the operand stack */ 365db2bae30SDana Myers 366db2bae30SDana Myers WalkState->OperandIndex++; 367db2bae30SDana Myers 368db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", 369db2bae30SDana Myers Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object), 370db2bae30SDana Myers WalkState, WalkState->NumOperands)); 371db2bae30SDana Myers 372db2bae30SDana Myers return (AE_OK); 373db2bae30SDana Myers } 374db2bae30SDana Myers 375db2bae30SDana Myers 376db2bae30SDana Myers /******************************************************************************* 377db2bae30SDana Myers * 378db2bae30SDana Myers * FUNCTION: AcpiDsObjStackPop 379db2bae30SDana Myers * 380db2bae30SDana Myers * PARAMETERS: PopCount - Number of objects/entries to pop 381db2bae30SDana Myers * WalkState - Current Walk state 382db2bae30SDana Myers * 383db2bae30SDana Myers * RETURN: Status 384db2bae30SDana Myers * 385db2bae30SDana Myers * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT 386db2bae30SDana Myers * deleted by this routine. 387db2bae30SDana Myers * 388db2bae30SDana Myers ******************************************************************************/ 389db2bae30SDana Myers 390db2bae30SDana Myers ACPI_STATUS 391db2bae30SDana Myers AcpiDsObjStackPop ( 392db2bae30SDana Myers UINT32 PopCount, 393db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 394db2bae30SDana Myers { 395db2bae30SDana Myers UINT32 i; 396db2bae30SDana Myers 397db2bae30SDana Myers 398db2bae30SDana Myers ACPI_FUNCTION_NAME (DsObjStackPop); 399db2bae30SDana Myers 400db2bae30SDana Myers 401db2bae30SDana Myers for (i = 0; i < PopCount; i++) 402db2bae30SDana Myers { 403db2bae30SDana Myers /* Check for stack underflow */ 404db2bae30SDana Myers 405db2bae30SDana Myers if (WalkState->NumOperands == 0) 406db2bae30SDana Myers { 407db2bae30SDana Myers ACPI_ERROR ((AE_INFO, 40826f3cdf0SGordon Ross "Object stack underflow! Count=%X State=%p #Ops=%u", 409db2bae30SDana Myers PopCount, WalkState, WalkState->NumOperands)); 410db2bae30SDana Myers return (AE_STACK_UNDERFLOW); 411db2bae30SDana Myers } 412db2bae30SDana Myers 413db2bae30SDana Myers /* Just set the stack entry to null */ 414db2bae30SDana Myers 415db2bae30SDana Myers WalkState->NumOperands--; 416db2bae30SDana Myers WalkState->Operands [WalkState->NumOperands] = NULL; 417db2bae30SDana Myers } 418db2bae30SDana Myers 41926f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n", 420db2bae30SDana Myers PopCount, WalkState, WalkState->NumOperands)); 421db2bae30SDana Myers 422db2bae30SDana Myers return (AE_OK); 423db2bae30SDana Myers } 424db2bae30SDana Myers 425db2bae30SDana Myers 426db2bae30SDana Myers /******************************************************************************* 427db2bae30SDana Myers * 428db2bae30SDana Myers * FUNCTION: AcpiDsObjStackPopAndDelete 429db2bae30SDana Myers * 430db2bae30SDana Myers * PARAMETERS: PopCount - Number of objects/entries to pop 431db2bae30SDana Myers * WalkState - Current Walk state 432db2bae30SDana Myers * 433db2bae30SDana Myers * RETURN: Status 434db2bae30SDana Myers * 435db2bae30SDana Myers * DESCRIPTION: Pop this walk's object stack and delete each object that is 436db2bae30SDana Myers * popped off. 437db2bae30SDana Myers * 438db2bae30SDana Myers ******************************************************************************/ 439db2bae30SDana Myers 440db2bae30SDana Myers void 441db2bae30SDana Myers AcpiDsObjStackPopAndDelete ( 442db2bae30SDana Myers UINT32 PopCount, 443db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 444db2bae30SDana Myers { 445db2bae30SDana Myers INT32 i; 446db2bae30SDana Myers ACPI_OPERAND_OBJECT *ObjDesc; 447db2bae30SDana Myers 448db2bae30SDana Myers 449db2bae30SDana Myers ACPI_FUNCTION_NAME (DsObjStackPopAndDelete); 450db2bae30SDana Myers 451db2bae30SDana Myers 452db2bae30SDana Myers if (PopCount == 0) 453db2bae30SDana Myers { 454db2bae30SDana Myers return; 455db2bae30SDana Myers } 456db2bae30SDana Myers 457db2bae30SDana Myers for (i = (INT32) PopCount - 1; i >= 0; i--) 458db2bae30SDana Myers { 459db2bae30SDana Myers if (WalkState->NumOperands == 0) 460db2bae30SDana Myers { 461db2bae30SDana Myers return; 462db2bae30SDana Myers } 463db2bae30SDana Myers 464db2bae30SDana Myers /* Pop the stack and delete an object if present in this stack entry */ 465db2bae30SDana Myers 466db2bae30SDana Myers WalkState->NumOperands--; 467db2bae30SDana Myers ObjDesc = WalkState->Operands [i]; 468db2bae30SDana Myers if (ObjDesc) 469db2bae30SDana Myers { 470db2bae30SDana Myers AcpiUtRemoveReference (WalkState->Operands [i]); 471db2bae30SDana Myers WalkState->Operands [i] = NULL; 472db2bae30SDana Myers } 473db2bae30SDana Myers } 474db2bae30SDana Myers 475db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n", 476db2bae30SDana Myers PopCount, WalkState, WalkState->NumOperands)); 477db2bae30SDana Myers } 478db2bae30SDana Myers 479db2bae30SDana Myers 480db2bae30SDana Myers /******************************************************************************* 481db2bae30SDana Myers * 482db2bae30SDana Myers * FUNCTION: AcpiDsGetCurrentWalkState 483db2bae30SDana Myers * 484db2bae30SDana Myers * PARAMETERS: Thread - Get current active state for this Thread 485db2bae30SDana Myers * 486db2bae30SDana Myers * RETURN: Pointer to the current walk state 487db2bae30SDana Myers * 488db2bae30SDana Myers * DESCRIPTION: Get the walk state that is at the head of the list (the "current" 489db2bae30SDana Myers * walk state.) 490db2bae30SDana Myers * 491db2bae30SDana Myers ******************************************************************************/ 492db2bae30SDana Myers 493db2bae30SDana Myers ACPI_WALK_STATE * 494db2bae30SDana Myers AcpiDsGetCurrentWalkState ( 495db2bae30SDana Myers ACPI_THREAD_STATE *Thread) 496db2bae30SDana Myers { 497db2bae30SDana Myers ACPI_FUNCTION_NAME (DsGetCurrentWalkState); 498db2bae30SDana Myers 499db2bae30SDana Myers 500db2bae30SDana Myers if (!Thread) 501db2bae30SDana Myers { 502db2bae30SDana Myers return (NULL); 503db2bae30SDana Myers } 504db2bae30SDana Myers 505db2bae30SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current WalkState %p\n", 506db2bae30SDana Myers Thread->WalkStateList)); 507db2bae30SDana Myers 508db2bae30SDana Myers return (Thread->WalkStateList); 509db2bae30SDana Myers } 510db2bae30SDana Myers 511db2bae30SDana Myers 512db2bae30SDana Myers /******************************************************************************* 513db2bae30SDana Myers * 514db2bae30SDana Myers * FUNCTION: AcpiDsPushWalkState 515db2bae30SDana Myers * 516db2bae30SDana Myers * PARAMETERS: WalkState - State to push 517db2bae30SDana Myers * Thread - Thread state object 518db2bae30SDana Myers * 519db2bae30SDana Myers * RETURN: None 520db2bae30SDana Myers * 521db2bae30SDana Myers * DESCRIPTION: Place the Thread state at the head of the state list 522db2bae30SDana Myers * 523db2bae30SDana Myers ******************************************************************************/ 524db2bae30SDana Myers 525db2bae30SDana Myers void 526db2bae30SDana Myers AcpiDsPushWalkState ( 527db2bae30SDana Myers ACPI_WALK_STATE *WalkState, 528db2bae30SDana Myers ACPI_THREAD_STATE *Thread) 529db2bae30SDana Myers { 530db2bae30SDana Myers ACPI_FUNCTION_TRACE (DsPushWalkState); 531db2bae30SDana Myers 532db2bae30SDana Myers 533db2bae30SDana Myers WalkState->Next = Thread->WalkStateList; 534db2bae30SDana Myers Thread->WalkStateList = WalkState; 535db2bae30SDana Myers 536db2bae30SDana Myers return_VOID; 537db2bae30SDana Myers } 538db2bae30SDana Myers 539db2bae30SDana Myers 540db2bae30SDana Myers /******************************************************************************* 541db2bae30SDana Myers * 542db2bae30SDana Myers * FUNCTION: AcpiDsPopWalkState 543db2bae30SDana Myers * 544db2bae30SDana Myers * PARAMETERS: Thread - Current thread state 545db2bae30SDana Myers * 546db2bae30SDana Myers * RETURN: A WalkState object popped from the thread's stack 547db2bae30SDana Myers * 548db2bae30SDana Myers * DESCRIPTION: Remove and return the walkstate object that is at the head of 549db2bae30SDana Myers * the walk stack for the given walk list. NULL indicates that 550db2bae30SDana Myers * the list is empty. 551db2bae30SDana Myers * 552db2bae30SDana Myers ******************************************************************************/ 553db2bae30SDana Myers 554db2bae30SDana Myers ACPI_WALK_STATE * 555db2bae30SDana Myers AcpiDsPopWalkState ( 556db2bae30SDana Myers ACPI_THREAD_STATE *Thread) 557db2bae30SDana Myers { 558db2bae30SDana Myers ACPI_WALK_STATE *WalkState; 559db2bae30SDana Myers 560db2bae30SDana Myers 561db2bae30SDana Myers ACPI_FUNCTION_TRACE (DsPopWalkState); 562db2bae30SDana Myers 563db2bae30SDana Myers 564db2bae30SDana Myers WalkState = Thread->WalkStateList; 565db2bae30SDana Myers 566db2bae30SDana Myers if (WalkState) 567db2bae30SDana Myers { 568db2bae30SDana Myers /* Next walk state becomes the current walk state */ 569db2bae30SDana Myers 570db2bae30SDana Myers Thread->WalkStateList = WalkState->Next; 571db2bae30SDana Myers 572db2bae30SDana Myers /* 573db2bae30SDana Myers * Don't clear the NEXT field, this serves as an indicator 574db2bae30SDana Myers * that there is a parent WALK STATE 575db2bae30SDana Myers * Do Not: WalkState->Next = NULL; 576db2bae30SDana Myers */ 577db2bae30SDana Myers } 578db2bae30SDana Myers 579db2bae30SDana Myers return_PTR (WalkState); 580db2bae30SDana Myers } 581db2bae30SDana Myers 582db2bae30SDana Myers 583db2bae30SDana Myers /******************************************************************************* 584db2bae30SDana Myers * 585db2bae30SDana Myers * FUNCTION: AcpiDsCreateWalkState 586db2bae30SDana Myers * 587db2bae30SDana Myers * PARAMETERS: OwnerId - ID for object creation 588db2bae30SDana Myers * Origin - Starting point for this walk 589db2bae30SDana Myers * MethodDesc - Method object 590db2bae30SDana Myers * Thread - Current thread state 591db2bae30SDana Myers * 592db2bae30SDana Myers * RETURN: Pointer to the new walk state. 593db2bae30SDana Myers * 594db2bae30SDana Myers * DESCRIPTION: Allocate and initialize a new walk state. The current walk 595db2bae30SDana Myers * state is set to this new state. 596db2bae30SDana Myers * 597db2bae30SDana Myers ******************************************************************************/ 598db2bae30SDana Myers 599db2bae30SDana Myers ACPI_WALK_STATE * 600db2bae30SDana Myers AcpiDsCreateWalkState ( 601db2bae30SDana Myers ACPI_OWNER_ID OwnerId, 602db2bae30SDana Myers ACPI_PARSE_OBJECT *Origin, 603db2bae30SDana Myers ACPI_OPERAND_OBJECT *MethodDesc, 604db2bae30SDana Myers ACPI_THREAD_STATE *Thread) 605db2bae30SDana Myers { 606db2bae30SDana Myers ACPI_WALK_STATE *WalkState; 607db2bae30SDana Myers 608db2bae30SDana Myers 609db2bae30SDana Myers ACPI_FUNCTION_TRACE (DsCreateWalkState); 610db2bae30SDana Myers 611db2bae30SDana Myers 612db2bae30SDana Myers WalkState = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_WALK_STATE)); 613db2bae30SDana Myers if (!WalkState) 614db2bae30SDana Myers { 615db2bae30SDana Myers return_PTR (NULL); 616db2bae30SDana Myers } 617db2bae30SDana Myers 618db2bae30SDana Myers WalkState->DescriptorType = ACPI_DESC_TYPE_WALK; 619db2bae30SDana Myers WalkState->MethodDesc = MethodDesc; 620db2bae30SDana Myers WalkState->OwnerId = OwnerId; 621db2bae30SDana Myers WalkState->Origin = Origin; 622db2bae30SDana Myers WalkState->Thread = Thread; 623db2bae30SDana Myers 624db2bae30SDana Myers WalkState->ParserState.StartOp = Origin; 625db2bae30SDana Myers 626db2bae30SDana Myers /* Init the method args/local */ 627db2bae30SDana Myers 628db2bae30SDana Myers #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) 629db2bae30SDana Myers AcpiDsMethodDataInit (WalkState); 630db2bae30SDana Myers #endif 631db2bae30SDana Myers 632db2bae30SDana Myers /* Put the new state at the head of the walk list */ 633db2bae30SDana Myers 634db2bae30SDana Myers if (Thread) 635db2bae30SDana Myers { 636db2bae30SDana Myers AcpiDsPushWalkState (WalkState, Thread); 637db2bae30SDana Myers } 638db2bae30SDana Myers 639db2bae30SDana Myers return_PTR (WalkState); 640db2bae30SDana Myers } 641db2bae30SDana Myers 642db2bae30SDana Myers 643db2bae30SDana Myers /******************************************************************************* 644db2bae30SDana Myers * 645db2bae30SDana Myers * FUNCTION: AcpiDsInitAmlWalk 646db2bae30SDana Myers * 647db2bae30SDana Myers * PARAMETERS: WalkState - New state to be initialized 648db2bae30SDana Myers * Op - Current parse op 649db2bae30SDana Myers * MethodNode - Control method NS node, if any 650db2bae30SDana Myers * AmlStart - Start of AML 651db2bae30SDana Myers * AmlLength - Length of AML 652db2bae30SDana Myers * Info - Method info block (params, etc.) 653db2bae30SDana Myers * PassNumber - 1, 2, or 3 654db2bae30SDana Myers * 655db2bae30SDana Myers * RETURN: Status 656db2bae30SDana Myers * 657db2bae30SDana Myers * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk 658db2bae30SDana Myers * 659db2bae30SDana Myers ******************************************************************************/ 660db2bae30SDana Myers 661db2bae30SDana Myers ACPI_STATUS 662db2bae30SDana Myers AcpiDsInitAmlWalk ( 663db2bae30SDana Myers ACPI_WALK_STATE *WalkState, 664db2bae30SDana Myers ACPI_PARSE_OBJECT *Op, 665db2bae30SDana Myers ACPI_NAMESPACE_NODE *MethodNode, 666db2bae30SDana Myers UINT8 *AmlStart, 667db2bae30SDana Myers UINT32 AmlLength, 668db2bae30SDana Myers ACPI_EVALUATE_INFO *Info, 669db2bae30SDana Myers UINT8 PassNumber) 670db2bae30SDana Myers { 671db2bae30SDana Myers ACPI_STATUS Status; 672db2bae30SDana Myers ACPI_PARSE_STATE *ParserState = &WalkState->ParserState; 673db2bae30SDana Myers ACPI_PARSE_OBJECT *ExtraOp; 674db2bae30SDana Myers 675db2bae30SDana Myers 676db2bae30SDana Myers ACPI_FUNCTION_TRACE (DsInitAmlWalk); 677db2bae30SDana Myers 678db2bae30SDana Myers 679db2bae30SDana Myers WalkState->ParserState.Aml = 680db2bae30SDana Myers WalkState->ParserState.AmlStart = AmlStart; 681db2bae30SDana Myers WalkState->ParserState.AmlEnd = 682db2bae30SDana Myers WalkState->ParserState.PkgEnd = AmlStart + AmlLength; 683db2bae30SDana Myers 684db2bae30SDana Myers /* The NextOp of the NextWalk will be the beginning of the method */ 685db2bae30SDana Myers 686db2bae30SDana Myers WalkState->NextOp = NULL; 687db2bae30SDana Myers WalkState->PassNumber = PassNumber; 688db2bae30SDana Myers 689db2bae30SDana Myers if (Info) 690db2bae30SDana Myers { 691db2bae30SDana Myers WalkState->Params = Info->Parameters; 692db2bae30SDana Myers WalkState->CallerReturnDesc = &Info->ReturnObject; 693db2bae30SDana Myers } 694db2bae30SDana Myers 695db2bae30SDana Myers Status = AcpiPsInitScope (&WalkState->ParserState, Op); 696db2bae30SDana Myers if (ACPI_FAILURE (Status)) 697db2bae30SDana Myers { 698db2bae30SDana Myers return_ACPI_STATUS (Status); 699db2bae30SDana Myers } 700db2bae30SDana Myers 701db2bae30SDana Myers if (MethodNode) 702db2bae30SDana Myers { 703db2bae30SDana Myers WalkState->ParserState.StartNode = MethodNode; 704db2bae30SDana Myers WalkState->WalkType = ACPI_WALK_METHOD; 705db2bae30SDana Myers WalkState->MethodNode = MethodNode; 706db2bae30SDana Myers WalkState->MethodDesc = AcpiNsGetAttachedObject (MethodNode); 707db2bae30SDana Myers 708db2bae30SDana Myers /* Push start scope on scope stack and make it current */ 709db2bae30SDana Myers 710*385cc6b4SJerry Jelinek Status = AcpiDsScopeStackPush ( 711*385cc6b4SJerry Jelinek MethodNode, ACPI_TYPE_METHOD, WalkState); 712db2bae30SDana Myers if (ACPI_FAILURE (Status)) 713db2bae30SDana Myers { 714db2bae30SDana Myers return_ACPI_STATUS (Status); 715db2bae30SDana Myers } 716db2bae30SDana Myers 717db2bae30SDana Myers /* Init the method arguments */ 718db2bae30SDana Myers 719db2bae30SDana Myers Status = AcpiDsMethodDataInitArgs (WalkState->Params, 720db2bae30SDana Myers ACPI_METHOD_NUM_ARGS, WalkState); 721db2bae30SDana Myers if (ACPI_FAILURE (Status)) 722db2bae30SDana Myers { 723db2bae30SDana Myers return_ACPI_STATUS (Status); 724db2bae30SDana Myers } 725db2bae30SDana Myers } 726db2bae30SDana Myers else 727db2bae30SDana Myers { 728db2bae30SDana Myers /* 729db2bae30SDana Myers * Setup the current scope. 730db2bae30SDana Myers * Find a Named Op that has a namespace node associated with it. 731db2bae30SDana Myers * search upwards from this Op. Current scope is the first 732db2bae30SDana Myers * Op with a namespace node. 733db2bae30SDana Myers */ 734db2bae30SDana Myers ExtraOp = ParserState->StartOp; 735db2bae30SDana Myers while (ExtraOp && !ExtraOp->Common.Node) 736db2bae30SDana Myers { 737db2bae30SDana Myers ExtraOp = ExtraOp->Common.Parent; 738db2bae30SDana Myers } 739db2bae30SDana Myers 740db2bae30SDana Myers if (!ExtraOp) 741db2bae30SDana Myers { 742db2bae30SDana Myers ParserState->StartNode = NULL; 743db2bae30SDana Myers } 744db2bae30SDana Myers else 745db2bae30SDana Myers { 746db2bae30SDana Myers ParserState->StartNode = ExtraOp->Common.Node; 747db2bae30SDana Myers } 748db2bae30SDana Myers 749db2bae30SDana Myers if (ParserState->StartNode) 750db2bae30SDana Myers { 751db2bae30SDana Myers /* Push start scope on scope stack and make it current */ 752db2bae30SDana Myers 753db2bae30SDana Myers Status = AcpiDsScopeStackPush (ParserState->StartNode, 754db2bae30SDana Myers ParserState->StartNode->Type, WalkState); 755db2bae30SDana Myers if (ACPI_FAILURE (Status)) 756db2bae30SDana Myers { 757db2bae30SDana Myers return_ACPI_STATUS (Status); 758db2bae30SDana Myers } 759db2bae30SDana Myers } 760db2bae30SDana Myers } 761db2bae30SDana Myers 762db2bae30SDana Myers Status = AcpiDsInitCallbacks (WalkState, PassNumber); 763db2bae30SDana Myers return_ACPI_STATUS (Status); 764db2bae30SDana Myers } 765db2bae30SDana Myers 766db2bae30SDana Myers 767db2bae30SDana Myers /******************************************************************************* 768db2bae30SDana Myers * 769db2bae30SDana Myers * FUNCTION: AcpiDsDeleteWalkState 770db2bae30SDana Myers * 771db2bae30SDana Myers * PARAMETERS: WalkState - State to delete 772db2bae30SDana Myers * 773db2bae30SDana Myers * RETURN: Status 774db2bae30SDana Myers * 775db2bae30SDana Myers * DESCRIPTION: Delete a walk state including all internal data structures 776db2bae30SDana Myers * 777db2bae30SDana Myers ******************************************************************************/ 778db2bae30SDana Myers 779db2bae30SDana Myers void 780db2bae30SDana Myers AcpiDsDeleteWalkState ( 781db2bae30SDana Myers ACPI_WALK_STATE *WalkState) 782db2bae30SDana Myers { 783db2bae30SDana Myers ACPI_GENERIC_STATE *State; 784db2bae30SDana Myers 785db2bae30SDana Myers 786db2bae30SDana Myers ACPI_FUNCTION_TRACE_PTR (DsDeleteWalkState, WalkState); 787db2bae30SDana Myers 788db2bae30SDana Myers 789db2bae30SDana Myers if (!WalkState) 790db2bae30SDana Myers { 791*385cc6b4SJerry Jelinek return_VOID; 792db2bae30SDana Myers } 793db2bae30SDana Myers 794db2bae30SDana Myers if (WalkState->DescriptorType != ACPI_DESC_TYPE_WALK) 795db2bae30SDana Myers { 796db2bae30SDana Myers ACPI_ERROR ((AE_INFO, "%p is not a valid walk state", 797db2bae30SDana Myers WalkState)); 798*385cc6b4SJerry Jelinek return_VOID; 799db2bae30SDana Myers } 800db2bae30SDana Myers 801db2bae30SDana Myers /* There should not be any open scopes */ 802db2bae30SDana Myers 803db2bae30SDana Myers if (WalkState->ParserState.Scope) 804db2bae30SDana Myers { 805db2bae30SDana Myers ACPI_ERROR ((AE_INFO, "%p walk still has a scope list", 806db2bae30SDana Myers WalkState)); 807db2bae30SDana Myers AcpiPsCleanupScope (&WalkState->ParserState); 808db2bae30SDana Myers } 809db2bae30SDana Myers 810db2bae30SDana Myers /* Always must free any linked control states */ 811db2bae30SDana Myers 812db2bae30SDana Myers while (WalkState->ControlState) 813db2bae30SDana Myers { 814db2bae30SDana Myers State = WalkState->ControlState; 815db2bae30SDana Myers WalkState->ControlState = State->Common.Next; 816db2bae30SDana Myers 817db2bae30SDana Myers AcpiUtDeleteGenericState (State); 818db2bae30SDana Myers } 819db2bae30SDana Myers 820db2bae30SDana Myers /* Always must free any linked parse states */ 821db2bae30SDana Myers 822db2bae30SDana Myers while (WalkState->ScopeInfo) 823db2bae30SDana Myers { 824db2bae30SDana Myers State = WalkState->ScopeInfo; 825db2bae30SDana Myers WalkState->ScopeInfo = State->Common.Next; 826db2bae30SDana Myers 827db2bae30SDana Myers AcpiUtDeleteGenericState (State); 828db2bae30SDana Myers } 829db2bae30SDana Myers 830db2bae30SDana Myers /* Always must free any stacked result states */ 831db2bae30SDana Myers 832db2bae30SDana Myers while (WalkState->Results) 833db2bae30SDana Myers { 834db2bae30SDana Myers State = WalkState->Results; 835db2bae30SDana Myers WalkState->Results = State->Common.Next; 836db2bae30SDana Myers 837db2bae30SDana Myers AcpiUtDeleteGenericState (State); 838db2bae30SDana Myers } 839db2bae30SDana Myers 840db2bae30SDana Myers ACPI_FREE (WalkState); 841db2bae30SDana Myers return_VOID; 842db2bae30SDana Myers } 843