ReactOS  0.4.14-dev-114-gc8cbd56
dsmethod.c File Reference
#include "acpi.h"
#include "accommon.h"
#include "acdispat.h"
#include "acinterp.h"
#include "acnamesp.h"
#include "acparser.h"
#include "amlcode.h"
#include "acdebug.h"
Include dependency graph for dsmethod.c:

Go to the source code of this file.

Macros

#define _COMPONENT   ACPI_DISPATCHER
 

Functions

static ACPI_STATUS AcpiDsDetectNamedOpcodes (ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT **OutOp)
 
static ACPI_STATUS AcpiDsCreateMethodMutex (ACPI_OPERAND_OBJECT *MethodDesc)
 
ACPI_STATUS AcpiDsAutoSerializeMethod (ACPI_NAMESPACE_NODE *Node, ACPI_OPERAND_OBJECT *ObjDesc)
 
ACPI_STATUS AcpiDsMethodError (ACPI_STATUS Status, ACPI_WALK_STATE *WalkState)
 
ACPI_STATUS AcpiDsBeginMethodExecution (ACPI_NAMESPACE_NODE *MethodNode, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_WALK_STATE *WalkState)
 
ACPI_STATUS AcpiDsCallControlMethod (ACPI_THREAD_STATE *Thread, ACPI_WALK_STATE *ThisWalkState, ACPI_PARSE_OBJECT *Op)
 
ACPI_STATUS AcpiDsRestartControlMethod (ACPI_WALK_STATE *WalkState, ACPI_OPERAND_OBJECT *ReturnDesc)
 
void AcpiDsTerminateControlMethod (ACPI_OPERAND_OBJECT *MethodDesc, ACPI_WALK_STATE *WalkState)
 

Macro Definition Documentation

◆ _COMPONENT

#define _COMPONENT   ACPI_DISPATCHER

Definition at line 54 of file dsmethod.c.

Function Documentation

◆ AcpiDsAutoSerializeMethod()

ACPI_STATUS AcpiDsAutoSerializeMethod ( ACPI_NAMESPACE_NODE Node,
ACPI_OPERAND_OBJECT ObjDesc 
)

Definition at line 94 of file dsmethod.c.

97 {
99  ACPI_PARSE_OBJECT *Op = NULL;
100  ACPI_WALK_STATE *WalkState;
101 
102 
103  ACPI_FUNCTION_TRACE_PTR (DsAutoSerializeMethod, Node);
104 
105 
107  "Method auto-serialization parse [%4.4s] %p\n",
109 
110  /* Create/Init a root op for the method parse tree */
111 
112  Op = AcpiPsAllocOp (AML_METHOD_OP, ObjDesc->Method.AmlStart);
113  if (!Op)
114  {
116  }
117 
118  AcpiPsSetName (Op, Node->Name.Integer);
119  Op->Common.Node = Node;
120 
121  /* Create and initialize a new walk state */
122 
123  WalkState = AcpiDsCreateWalkState (Node->OwnerId, NULL, NULL, NULL);
124  if (!WalkState)
125  {
126  AcpiPsFreeOp (Op);
128  }
129 
130  Status = AcpiDsInitAmlWalk (WalkState, Op, Node,
131  ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength, NULL, 0);
132  if (ACPI_FAILURE (Status))
133  {
134  AcpiDsDeleteWalkState (WalkState);
135  AcpiPsFreeOp (Op);
137  }
138 
140 
141  /* Parse the method, scan for creation of named objects */
142 
143  Status = AcpiPsParseAml (WalkState);
144 
147 }
UINT8 * AmlStart
Definition: acobject.h:220
void AcpiPsDeleteParseTree(ACPI_PARSE_OBJECT *root)
Definition: pswalk.c:67
ACPI_PARSE_OBJ_COMMON Common
Definition: aclocal.h:1078
ACPI_STATUS AcpiDsInitAmlWalk(ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op, ACPI_NAMESPACE_NODE *MethodNode, UINT8 *AmlStart, UINT32 AmlLength, ACPI_EVALUATE_INFO *Info, UINT8 PassNumber)
Definition: dswstate.c:662
void AcpiDsDeleteWalkState(ACPI_WALK_STATE *WalkState)
Definition: dswstate.c:780
ACPI_WALK_STATE * AcpiDsCreateWalkState(ACPI_OWNER_ID OwnerId, ACPI_PARSE_OBJECT *Origin, ACPI_OPERAND_OBJECT *MethodDesc, ACPI_THREAD_STATE *Thread)
Definition: dswstate.c:600
#define AE_NO_MEMORY
Definition: acexcep.h:112
ACPI_PARSE_OBJECT * AcpiPsAllocOp(UINT16 Opcode, UINT8 *Aml)
Definition: psutils.c:130
#define ACPI_DB_PARSE
Definition: acoutput.h:162
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
union node Node
Definition: types.h:1255
smooth NULL
Definition: ftsmooth.c:416
#define ACPI_FUNCTION_TRACE_PTR(a, b)
Definition: acoutput.h:481
static ACPI_STATUS AcpiDsDetectNamedOpcodes(ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT **OutOp)
Definition: dsmethod.c:166
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
void AcpiPsSetName(ACPI_PARSE_OBJECT *op, UINT32 name)
Definition: psutils.c:281
#define AML_METHOD_OP
Definition: amlcode.h:64
Status
Definition: gdiplustypes.h:24
ACPI_OBJECT_METHOD Method
Definition: acobject.h:522
ACPI_PARSE_DOWNWARDS DescendingCallback
Definition: acstruct.h:128
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
ACPI_STATUS AcpiPsParseAml(ACPI_WALK_STATE *WalkState)
Definition: psparse.c:453
void AcpiPsFreeOp(ACPI_PARSE_OBJECT *Op)
Definition: psutils.c:212
const char * AcpiUtGetNodeName(void *Object)
Definition: utdecode.c:305
Definition: dlist.c:348

Referenced by AcpiDsInitOneObject().

◆ AcpiDsBeginMethodExecution()

ACPI_STATUS AcpiDsBeginMethodExecution ( ACPI_NAMESPACE_NODE MethodNode,
ACPI_OPERAND_OBJECT ObjDesc,
ACPI_WALK_STATE WalkState 
)

Definition at line 352 of file dsmethod.c.

356 {
358 
359 
360  ACPI_FUNCTION_TRACE_PTR (DsBeginMethodExecution, MethodNode);
361 
362 
363  if (!MethodNode)
364  {
366  }
367 
368  AcpiExStartTraceMethod (MethodNode, ObjDesc, WalkState);
369 
370  /* Prevent wraparound of thread count */
371 
372  if (ObjDesc->Method.ThreadCount == ACPI_UINT8_MAX)
373  {
375  "Method reached maximum reentrancy limit (255)"));
377  }
378 
379  /*
380  * If this method is serialized, we need to acquire the method mutex.
381  */
382  if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED)
383  {
384  /*
385  * Create a mutex for the method if it is defined to be Serialized
386  * and a mutex has not already been created. We defer the mutex creation
387  * until a method is actually executed, to minimize the object count
388  */
389  if (!ObjDesc->Method.Mutex)
390  {
391  Status = AcpiDsCreateMethodMutex (ObjDesc);
392  if (ACPI_FAILURE (Status))
393  {
395  }
396  }
397 
398  /*
399  * The CurrentSyncLevel (per-thread) must be less than or equal to
400  * the sync level of the method. This mechanism provides some
401  * deadlock prevention.
402  *
403  * If the method was auto-serialized, we just ignore the sync level
404  * mechanism, because auto-serialization of methods can interfere
405  * with ASL code that actually uses sync levels.
406  *
407  * Top-level method invocation has no walk state at this point
408  */
409  if (WalkState &&
411  (WalkState->Thread->CurrentSyncLevel >
412  ObjDesc->Method.Mutex->Mutex.SyncLevel))
413  {
415  "Cannot acquire Mutex for method [%4.4s]"
416  ", current SyncLevel is too large (%u)",
417  AcpiUtGetNodeName (MethodNode),
418  WalkState->Thread->CurrentSyncLevel));
419 
421  }
422 
423  /*
424  * Obtain the method mutex if necessary. Do not acquire mutex for a
425  * recursive call.
426  */
427  if (!WalkState ||
428  !ObjDesc->Method.Mutex->Mutex.ThreadId ||
429  (WalkState->Thread->ThreadId !=
430  ObjDesc->Method.Mutex->Mutex.ThreadId))
431  {
432  /*
433  * Acquire the method mutex. This releases the interpreter if we
434  * block (and reacquires it before it returns)
435  */
438  if (ACPI_FAILURE (Status))
439  {
441  }
442 
443  /* Update the mutex and walk info and save the original SyncLevel */
444 
445  if (WalkState)
446  {
447  ObjDesc->Method.Mutex->Mutex.OriginalSyncLevel =
448  WalkState->Thread->CurrentSyncLevel;
449 
450  ObjDesc->Method.Mutex->Mutex.ThreadId =
451  WalkState->Thread->ThreadId;
452 
453  /*
454  * Update the current SyncLevel only if this is not an auto-
455  * serialized method. In the auto case, we have to ignore
456  * the sync level for the method mutex (created for the
457  * auto-serialization) because we have no idea of what the
458  * sync level should be. Therefore, just ignore it.
459  */
460  if (!(ObjDesc->Method.InfoFlags &
462  {
463  WalkState->Thread->CurrentSyncLevel =
464  ObjDesc->Method.SyncLevel;
465  }
466  }
467  else
468  {
469  ObjDesc->Method.Mutex->Mutex.OriginalSyncLevel =
470  ObjDesc->Method.Mutex->Mutex.SyncLevel;
471 
472  ObjDesc->Method.Mutex->Mutex.ThreadId =
474  }
475  }
476 
477  /* Always increase acquisition depth */
478 
479  ObjDesc->Method.Mutex->Mutex.AcquisitionDepth++;
480  }
481 
482  /*
483  * Allocate an Owner ID for this method, only if this is the first thread
484  * to begin concurrent execution. We only need one OwnerId, even if the
485  * method is invoked recursively.
486  */
487  if (!ObjDesc->Method.OwnerId)
488  {
490  if (ACPI_FAILURE (Status))
491  {
492  goto Cleanup;
493  }
494  }
495 
496  /*
497  * Increment the method parse tree thread count since it has been
498  * reentered one more time (even if it is the same thread)
499  */
500  ObjDesc->Method.ThreadCount++;
501  AcpiMethodCount++;
503 
504 
505 Cleanup:
506  /* On error, must release the method mutex (if present) */
507 
508  if (ObjDesc->Method.Mutex)
509  {
511  }
513 }
ACPI_THREAD_STATE * Thread
Definition: acstruct.h:127
#define ACPI_METHOD_IGNORE_SYNC_LEVEL
Definition: acobject.h:239
ACPI_THREAD_ID AcpiOsGetThreadId(void)
Definition: osl.c:217
ACPI_MUTEX OsMutex
Definition: acobject.h:188
#define ACPI_METHOD_SERIALIZED
Definition: acobject.h:237
ACPI_OBJECT_COMMON_HEADER UINT8 InfoFlags
Definition: acobject.h:215
ACPI_OBJECT_MUTEX Mutex
Definition: acobject.h:523
#define AE_AML_METHOD_LIMIT
Definition: acexcep.h:198
UINT32 ACPI_STATUS
Definition: actypes.h:460
ACPI_OBJECT_COMMON_HEADER UINT8 SyncLevel
Definition: acobject.h:186
UINT8 OriginalSyncLevel
Definition: acobject.h:194
UINT16 AcquisitionDepth
Definition: acobject.h:187
#define AE_AML_MUTEX_ORDER
Definition: acexcep.h:200
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
ACPI_STATUS AcpiExSystemWaitMutex(ACPI_MUTEX Mutex, UINT16 Timeout)
Definition: exsystem.c:120
#define ACPI_UINT8_MAX
Definition: actypes.h:64
#define AE_INFO
Definition: acoutput.h:230
void AcpiExStartTraceMethod(ACPI_NAMESPACE_NODE *MethodNode, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_WALK_STATE *WalkState)
Definition: extrace.c:224
#define ACPI_FUNCTION_TRACE_PTR(a, b)
Definition: acoutput.h:481
ACPI_STATE_COMMON UINT8 CurrentSyncLevel
Definition: aclocal.h:764
#define ACPI_WAIT_FOREVER
Definition: actypes.h:501
static ACPI_STATUS AcpiDsCreateMethodMutex(ACPI_OPERAND_OBJECT *MethodDesc)
Definition: dsmethod.c:301
ACPI_THREAD_ID ThreadId
Definition: acobject.h:189
union acpi_operand_object * Mutex
Definition: acobject.h:218
static const WCHAR Cleanup[]
Definition: register.c:80
Status
Definition: gdiplustypes.h:24
ACPI_OBJECT_METHOD Method
Definition: acobject.h:522
ACPI_STATUS AcpiUtAllocateOwnerId(ACPI_OWNER_ID *OwnerId)
Definition: utownerid.c:68
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define AE_NULL_ENTRY
Definition: acexcep.h:118
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
const char * AcpiUtGetNodeName(void *Object)
Definition: utdecode.c:305
void AcpiOsReleaseMutex(ACPI_MUTEX Handle)
Definition: osl.c:333
ACPI_THREAD_ID ThreadId
Definition: aclocal.h:767
ACPI_OWNER_ID OwnerId
Definition: acobject.h:228
#define AE_OK
Definition: acexcep.h:97

Referenced by AcpiDsCallControlMethod(), and AcpiPsExecuteMethod().

◆ AcpiDsCallControlMethod()

ACPI_STATUS AcpiDsCallControlMethod ( ACPI_THREAD_STATE Thread,
ACPI_WALK_STATE ThisWalkState,
ACPI_PARSE_OBJECT Op 
)

Definition at line 531 of file dsmethod.c.

535 {
537  ACPI_NAMESPACE_NODE *MethodNode;
538  ACPI_WALK_STATE *NextWalkState = NULL;
539  ACPI_OPERAND_OBJECT *ObjDesc;
541  UINT32 i;
542 
543 
544  ACPI_FUNCTION_TRACE_PTR (DsCallControlMethod, ThisWalkState);
545 
547  "Calling method %p, currentstate=%p\n",
548  ThisWalkState->PrevOp, ThisWalkState));
549 
550  /*
551  * Get the namespace entry for the control method we are about to call
552  */
553  MethodNode = ThisWalkState->MethodCallNode;
554  if (!MethodNode)
555  {
557  }
558 
559  ObjDesc = AcpiNsGetAttachedObject (MethodNode);
560  if (!ObjDesc)
561  {
563  }
564 
565  /* Init for new method, possibly wait on method mutex */
566 
568  MethodNode, ObjDesc, ThisWalkState);
569  if (ACPI_FAILURE (Status))
570  {
572  }
573 
574  /* Begin method parse/execution. Create a new walk state */
575 
576  NextWalkState = AcpiDsCreateWalkState (
577  ObjDesc->Method.OwnerId, NULL, ObjDesc, Thread);
578  if (!NextWalkState)
579  {
581  goto Cleanup;
582  }
583 
584  /*
585  * The resolved arguments were put on the previous walk state's operand
586  * stack. Operands on the previous walk state stack always
587  * start at index 0. Also, null terminate the list of arguments
588  */
589  ThisWalkState->Operands [ThisWalkState->NumOperands] = NULL;
590 
591  /*
592  * Allocate and initialize the evaluation information block
593  * TBD: this is somewhat inefficient, should change interface to
594  * DsInitAmlWalk. For now, keeps this struct off the CPU stack
595  */
597  if (!Info)
598  {
600  goto Cleanup;
601  }
602 
603  Info->Parameters = &ThisWalkState->Operands[0];
604 
605  Status = AcpiDsInitAmlWalk (NextWalkState, NULL, MethodNode,
606  ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength,
608 
609  ACPI_FREE (Info);
610  if (ACPI_FAILURE (Status))
611  {
612  goto Cleanup;
613  }
614 
615  NextWalkState->MethodNestingDepth = ThisWalkState->MethodNestingDepth + 1;
616 
617  /*
618  * Delete the operands on the previous walkstate operand stack
619  * (they were copied to new objects)
620  */
621  for (i = 0; i < ObjDesc->Method.ParamCount; i++)
622  {
623  AcpiUtRemoveReference (ThisWalkState->Operands [i]);
624  ThisWalkState->Operands [i] = NULL;
625  }
626 
627  /* Clear the operand stack */
628 
629  ThisWalkState->NumOperands = 0;
630 
632  "**** Begin nested execution of [%4.4s] **** WalkState=%p\n",
633  MethodNode->Name.Ascii, NextWalkState));
634 
635  ThisWalkState->MethodPathname = AcpiNsGetNormalizedPathname (MethodNode, TRUE);
636  ThisWalkState->MethodIsNested = TRUE;
637 
638  /* Optional object evaluation log */
639 
641  "%-26s: %*s%s\n", " Nested method call",
642  NextWalkState->MethodNestingDepth * 3, " ",
643  &ThisWalkState->MethodPathname[1]));
644 
645  /* Invoke an internal method if necessary */
646 
648  {
649  Status = ObjDesc->Method.Dispatch.Implementation (NextWalkState);
650  if (Status == AE_OK)
651  {
653  }
654  }
655 
657 
658 
659 Cleanup:
660 
661  /* On error, we must terminate the method properly */
662 
663  AcpiDsTerminateControlMethod (ObjDesc, NextWalkState);
664  AcpiDsDeleteWalkState (NextWalkState);
665 
667 }
#define ACPI_DEBUG_PRINT_RAW(pl)
Definition: acoutput.h:476
#define AE_NULL_OBJECT
Definition: acexcep.h:117
#define ACPI_FREE(a)
Definition: actypes.h:386
char * MethodPathname
Definition: acstruct.h:117
UINT8 * AmlStart
Definition: acobject.h:220
#define ACPI_ALLOCATE_ZEROED(a)
Definition: actypes.h:385
#define TRUE
Definition: types.h:120
ACPI_STATUS AcpiDsInitAmlWalk(ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op, ACPI_NAMESPACE_NODE *MethodNode, UINT8 *AmlStart, UINT32 AmlLength, ACPI_EVALUATE_INFO *Info, UINT8 PassNumber)
Definition: dswstate.c:662
void AcpiDsDeleteWalkState(ACPI_WALK_STATE *WalkState)
Definition: dswstate.c:780
ACPI_PARSE_OBJECT * PrevOp
Definition: acstruct.h:125
ACPI_WALK_STATE * AcpiDsCreateWalkState(ACPI_OWNER_ID OwnerId, ACPI_PARSE_OBJECT *Origin, ACPI_OPERAND_OBJECT *MethodDesc, ACPI_THREAD_STATE *Thread)
Definition: dswstate.c:600
#define AE_NO_MEMORY
Definition: acexcep.h:112
UINT8 NumOperands
Definition: acstruct.h:80
ACPI_OBJECT_COMMON_HEADER UINT8 InfoFlags
Definition: acobject.h:215
char Ascii[4]
Definition: actbl.h:394
UINT32 ACPI_STATUS
Definition: actypes.h:460
struct TraceInfo Info
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define AE_CTRL_TERMINATE
Definition: acexcep.h:226
unsigned int UINT32
smooth NULL
Definition: ftsmooth.c:416
struct acpi_namespace_node * MethodCallNode
Definition: acstruct.h:113
ACPI_NAME_UNION Name
Definition: aclocal.h:191
#define ACPI_FUNCTION_TRACE_PTR(a, b)
Definition: acoutput.h:481
#define ACPI_DB_DISPATCH
Definition: acoutput.h:163
#define ACPI_METHOD_INTERNAL_ONLY
Definition: acobject.h:236
union acpi_object_method::@585 Dispatch
ACPI_STATUS AcpiDsBeginMethodExecution(ACPI_NAMESPACE_NODE *MethodNode, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_WALK_STATE *WalkState)
Definition: dsmethod.c:352
UINT16 MethodNestingDepth
Definition: acstruct.h:100
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
ACPI_OPERAND_OBJECT * AcpiNsGetAttachedObject(ACPI_NAMESPACE_NODE *Node)
Definition: nsobject.c:308
ACPI_INTERNAL_METHOD Implementation
Definition: acobject.h:223
static const WCHAR Cleanup[]
Definition: register.c:80
Status
Definition: gdiplustypes.h:24
ACPI_OBJECT_METHOD Method
Definition: acobject.h:522
char * AcpiNsGetNormalizedPathname(ACPI_NAMESPACE_NODE *Node, BOOLEAN NoTrailing)
Definition: nsnames.c:373
union acpi_operand_object * Operands[ACPI_OBJ_NUM_OPERANDS+1]
Definition: acstruct.h:105
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
void AcpiUtRemoveReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:784
#define AE_NULL_ENTRY
Definition: acexcep.h:118
#define ACPI_DB_EVALUATION
Definition: acoutput.h:181
ACPI_OWNER_ID OwnerId
Definition: acobject.h:228
UINT8 MethodIsNested
Definition: acstruct.h:101
#define AE_OK
Definition: acexcep.h:97
void AcpiDsTerminateControlMethod(ACPI_OPERAND_OBJECT *MethodDesc, ACPI_WALK_STATE *WalkState)
Definition: dsmethod.c:779

Referenced by AcpiPsParseAml().

◆ AcpiDsCreateMethodMutex()

static ACPI_STATUS AcpiDsCreateMethodMutex ( ACPI_OPERAND_OBJECT MethodDesc)
static

Definition at line 301 of file dsmethod.c.

303 {
304  ACPI_OPERAND_OBJECT *MutexDesc;
306 
307 
308  ACPI_FUNCTION_TRACE (DsCreateMethodMutex);
309 
310 
311  /* Create the new mutex object */
312 
314  if (!MutexDesc)
315  {
317  }
318 
319  /* Create the actual OS Mutex */
320 
321  Status = AcpiOsCreateMutex (&MutexDesc->Mutex.OsMutex);
322  if (ACPI_FAILURE (Status))
323  {
324  AcpiUtDeleteObjectDesc (MutexDesc);
326  }
327 
328  MutexDesc->Mutex.SyncLevel = MethodDesc->Method.SyncLevel;
329  MethodDesc->Method.Mutex = MutexDesc;
331 }
#define AE_NO_MEMORY
Definition: acexcep.h:112
ACPI_MUTEX OsMutex
Definition: acobject.h:188
ACPI_OBJECT_MUTEX Mutex
Definition: acobject.h:523
void AcpiUtDeleteObjectDesc(ACPI_OPERAND_OBJECT *Object)
Definition: utobject.c:473
UINT32 ACPI_STATUS
Definition: actypes.h:460
ACPI_OBJECT_COMMON_HEADER UINT8 SyncLevel
Definition: acobject.h:186
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
union acpi_operand_object * Mutex
Definition: acobject.h:218
Status
Definition: gdiplustypes.h:24
ACPI_OBJECT_METHOD Method
Definition: acobject.h:522
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_TYPE_MUTEX
Definition: actypes.h:687
ACPI_STATUS AcpiOsCreateMutex(ACPI_MUTEX *OutHandle)
Definition: osl.c:271
#define AcpiUtCreateInternalObject(t)
Definition: acutils.h:654
#define AE_OK
Definition: acexcep.h:97

Referenced by AcpiDsBeginMethodExecution().

◆ AcpiDsDetectNamedOpcodes()

static ACPI_STATUS AcpiDsDetectNamedOpcodes ( ACPI_WALK_STATE WalkState,
ACPI_PARSE_OBJECT **  OutOp 
)
static

Definition at line 166 of file dsmethod.c.

169 {
170 
172 
173 
174  /* We are only interested in opcodes that create a new name */
175 
176  if (!(WalkState->OpInfo->Flags & (AML_NAMED | AML_CREATE | AML_FIELD)))
177  {
178  return (AE_OK);
179  }
180 
181  /*
182  * At this point, we know we have a Named object opcode.
183  * Mark the method as serialized. Later code will create a mutex for
184  * this method to enforce serialization.
185  *
186  * Note, ACPI_METHOD_IGNORE_SYNC_LEVEL flag means that we will ignore the
187  * Sync Level mechanism for this method, even though it is now serialized.
188  * Otherwise, there can be conflicts with existing ASL code that actually
189  * uses sync levels.
190  */
191  WalkState->MethodDesc->Method.SyncLevel = 0;
192  WalkState->MethodDesc->Method.InfoFlags |=
194 
196  "Method serialized [%4.4s] %p - [%s] (%4.4X)\n",
197  WalkState->MethodNode->Name.Ascii, WalkState->MethodNode,
198  WalkState->OpInfo->Name, WalkState->Opcode));
199 
200  /* Abort the parse, no need to examine this method any further */
201 
202  return (AE_CTRL_TERMINATE);
203 }
#define AML_NAMED
Definition: amlcode.h:323
#define ACPI_METHOD_IGNORE_SYNC_LEVEL
Definition: acobject.h:239
#define ACPI_METHOD_SERIALIZED
Definition: acobject.h:237
ACPI_OBJECT_COMMON_HEADER UINT8 InfoFlags
Definition: acobject.h:215
#define AML_CREATE
Definition: amlcode.h:320
#define AE_CTRL_TERMINATE
Definition: acexcep.h:226
static ACPI_STATUS AcpiDsDetectNamedOpcodes(ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT **OutOp)
Definition: dsmethod.c:166
union acpi_operand_object * MethodDesc
Definition: acstruct.h:115
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
#define AML_FIELD
Definition: amlcode.h:321
const ACPI_OPCODE_INFO * OpInfo
Definition: acstruct.h:119
struct acpi_namespace_node * MethodNode
Definition: acstruct.h:116
ACPI_OBJECT_METHOD Method
Definition: acobject.h:522
#define ACPI_DB_INFO
Definition: acoutput.h:153
UINT16 Opcode
Definition: acstruct.h:78
#define ACPI_FUNCTION_NAME(a)
Definition: acoutput.h:479
#define AE_OK
Definition: acexcep.h:97
UINT16 Flags
Definition: aclocal.h:873

Referenced by AcpiDsAutoSerializeMethod().

◆ AcpiDsMethodError()

ACPI_STATUS AcpiDsMethodError ( ACPI_STATUS  Status,
ACPI_WALK_STATE WalkState 
)

Definition at line 223 of file dsmethod.c.

226 {
227  UINT32 AmlOffset;
228  ACPI_NAME Name = 0;
229 
230 
232 
233 
234  /* Ignore AE_OK and control exception codes */
235 
236  if (ACPI_SUCCESS (Status) ||
238  {
239  return (Status);
240  }
241 
242  /* Invoke the global exception handler */
243 
244  if (AcpiGbl_ExceptionHandler)
245  {
246  /* Exit the interpreter, allow handler to execute methods */
247 
249 
250  /*
251  * Handler can map the exception code to anything it wants, including
252  * AE_OK, in which case the executing method will not be aborted.
253  */
254  AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->Aml,
255  WalkState->ParserState.AmlStart);
256 
257  if (WalkState->MethodNode)
258  {
259  Name = WalkState->MethodNode->Name.Integer;
260  }
261  else if (WalkState->DeferredNode)
262  {
263  Name = WalkState->DeferredNode->Name.Integer;
264  }
265 
266  Status = AcpiGbl_ExceptionHandler (Status, Name,
267  WalkState->Opcode, AmlOffset, NULL);
269  }
270 
271  AcpiDsClearImplicitReturn (WalkState);
272 
273  if (ACPI_FAILURE (Status))
274  {
275  AcpiDsDumpMethodStack (Status, WalkState, WalkState->Op);
276 
277  /* Display method locals/args if debugger is present */
278 
279 #ifdef ACPI_DEBUGGER
280  AcpiDbDumpMethodInfo (Status, WalkState);
281 #endif
282  }
283 
284  return (Status);
285 }
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
#define ACPI_PTR_DIFF(a, b)
Definition: actypes.h:548
struct acpi_namespace_node * DeferredNode
Definition: acstruct.h:111
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
unsigned int UINT32
smooth NULL
Definition: ftsmooth.c:416
#define ACPI_FUNCTION_ENTRY()
Definition: acoutput.h:484
ACPI_PARSE_OBJECT * Op
Definition: acstruct.h:118
void AcpiDbDumpMethodInfo(ACPI_STATUS Status, ACPI_WALK_STATE *WalkState)
UINT8 * AmlStart
Definition: aclocal.h:1101
ACPI_PARSE_STATE ParserState
Definition: acstruct.h:97
UINT32 ACPI_NAME
Definition: actypes.h:461
struct acpi_namespace_node * MethodNode
Definition: acstruct.h:116
Status
Definition: gdiplustypes.h:24
void AcpiExExitInterpreter(void)
Definition: exutils.c:139
void AcpiExEnterInterpreter(void)
Definition: exutils.c:91
#define AE_CODE_CONTROL
Definition: acexcep.h:57
void AcpiDsDumpMethodStack(ACPI_STATUS Status, ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op)
Definition: dsdebug.c:249
UINT16 Opcode
Definition: acstruct.h:78
void AcpiDsClearImplicitReturn(ACPI_WALK_STATE *WalkState)
Definition: dsutils.c:73
UINT8 * Aml
Definition: acstruct.h:91

Referenced by AcpiDsExecBeginOp(), AcpiDsExecEndOp(), AcpiPsGetNextNamepath(), and AcpiPsParseAml().

◆ AcpiDsRestartControlMethod()

ACPI_STATUS AcpiDsRestartControlMethod ( ACPI_WALK_STATE WalkState,
ACPI_OPERAND_OBJECT ReturnDesc 
)

Definition at line 685 of file dsmethod.c.

688 {
690  int SameAsImplicitReturn;
691 
692 
693  ACPI_FUNCTION_TRACE_PTR (DsRestartControlMethod, WalkState);
694 
695 
697  "****Restart [%4.4s] Op %p ReturnValueFromCallee %p\n",
698  AcpiUtGetNodeName (WalkState->MethodNode),
699  WalkState->MethodCallOp, ReturnDesc));
700 
702  " ReturnFromThisMethodUsed?=%X ResStack %p Walk %p\n",
703  WalkState->ReturnUsed,
704  WalkState->Results, WalkState));
705 
706  /* Did the called method return a value? */
707 
708  if (ReturnDesc)
709  {
710  /* Is the implicit return object the same as the return desc? */
711 
712  SameAsImplicitReturn = (WalkState->ImplicitReturnObj == ReturnDesc);
713 
714  /* Are we actually going to use the return value? */
715 
716  if (WalkState->ReturnUsed)
717  {
718  /* Save the return value from the previous method */
719 
720  Status = AcpiDsResultPush (ReturnDesc, WalkState);
721  if (ACPI_FAILURE (Status))
722  {
723  AcpiUtRemoveReference (ReturnDesc);
725  }
726 
727  /*
728  * Save as THIS method's return value in case it is returned
729  * immediately to yet another method
730  */
731  WalkState->ReturnDesc = ReturnDesc;
732  }
733 
734  /*
735  * The following code is the optional support for the so-called
736  * "implicit return". Some AML code assumes that the last value of the
737  * method is "implicitly" returned to the caller, in the absence of an
738  * explicit return value.
739  *
740  * Just save the last result of the method as the return value.
741  *
742  * NOTE: this is optional because the ASL language does not actually
743  * support this behavior.
744  */
745  else if (!AcpiDsDoImplicitReturn (ReturnDesc, WalkState, FALSE) ||
746  SameAsImplicitReturn)
747  {
748  /*
749  * Delete the return value if it will not be used by the
750  * calling method or remove one reference if the explicit return
751  * is the same as the implicit return value.
752  */
753  AcpiUtRemoveReference (ReturnDesc);
754  }
755  }
756 
758 }
union acpi_operand_object * ImplicitReturnObj
Definition: acstruct.h:112
ACPI_GENERIC_STATE * Results
Definition: acstruct.h:122
union acpi_operand_object * ReturnDesc
Definition: acstruct.h:123
UINT32 ACPI_STATUS
Definition: actypes.h:460
ACPI_STATUS AcpiDsResultPush(ACPI_OPERAND_OBJECT *Object, ACPI_WALK_STATE *WalkState)
Definition: dswstate.c:160
BOOLEAN AcpiDsDoImplicitReturn(ACPI_OPERAND_OBJECT *ReturnDesc, ACPI_WALK_STATE *WalkState, BOOLEAN AddReference)
Definition: dsutils.c:123
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define ACPI_FUNCTION_TRACE_PTR(a, b)
Definition: acoutput.h:481
#define ACPI_DB_DISPATCH
Definition: acoutput.h:163
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
ACPI_PARSE_OBJECT * MethodCallOp
Definition: acstruct.h:114
struct acpi_namespace_node * MethodNode
Definition: acstruct.h:116
Status
Definition: gdiplustypes.h:24
UINT8 ReturnUsed
Definition: acstruct.h:85
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
void AcpiUtRemoveReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:784
const char * AcpiUtGetNodeName(void *Object)
Definition: utdecode.c:305
#define AE_OK
Definition: acexcep.h:97

Referenced by AcpiPsParseAml().

◆ AcpiDsTerminateControlMethod()

void AcpiDsTerminateControlMethod ( ACPI_OPERAND_OBJECT MethodDesc,
ACPI_WALK_STATE WalkState 
)

Definition at line 779 of file dsmethod.c.

782 {
783 
784  ACPI_FUNCTION_TRACE_PTR (DsTerminateControlMethod, WalkState);
785 
786 
787  /* MethodDesc is required, WalkState is optional */
788 
789  if (!MethodDesc)
790  {
791  return_VOID;
792  }
793 
794  if (WalkState)
795  {
796  /* Delete all arguments and locals */
797 
798  AcpiDsMethodDataDeleteAll (WalkState);
799 
800  /*
801  * Delete any namespace objects created anywhere within the
802  * namespace by the execution of this method. Unless:
803  * 1) This method is a module-level executable code method, in which
804  * case we want make the objects permanent.
805  * 2) There are other threads executing the method, in which case we
806  * will wait until the last thread has completed.
807  */
808  if (!(MethodDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL) &&
809  (MethodDesc->Method.ThreadCount == 1))
810  {
811  /* Delete any direct children of (created by) this method */
812 
816 
817  /*
818  * Delete any objects that were created by this method
819  * elsewhere in the namespace (if any were created).
820  * Use of the ACPI_METHOD_MODIFIED_NAMESPACE optimizes the
821  * deletion such that we don't have to perform an entire
822  * namespace walk for every control method execution.
823  */
825  {
829  MethodDesc->Method.InfoFlags &=
831  }
832  }
833 
834  /*
835  * If method is serialized, release the mutex and restore the
836  * current sync level for this thread
837  */
838  if (MethodDesc->Method.Mutex)
839  {
840  /* Acquisition Depth handles recursive calls */
841 
842  MethodDesc->Method.Mutex->Mutex.AcquisitionDepth--;
843  if (!MethodDesc->Method.Mutex->Mutex.AcquisitionDepth)
844  {
845  WalkState->Thread->CurrentSyncLevel =
846  MethodDesc->Method.Mutex->Mutex.OriginalSyncLevel;
847 
849  MethodDesc->Method.Mutex->Mutex.OsMutex);
850  MethodDesc->Method.Mutex->Mutex.ThreadId = 0;
851  }
852  }
853  }
854 
855  /* Decrement the thread count on the method */
856 
857  if (MethodDesc->Method.ThreadCount)
858  {
859  MethodDesc->Method.ThreadCount--;
860  }
861  else
862  {
864  "Invalid zero thread count in method"));
865  }
866 
867  /* Are there any other threads currently executing this method? */
868 
869  if (MethodDesc->Method.ThreadCount)
870  {
871  /*
872  * Additional threads. Do not release the OwnerId in this case,
873  * we immediately reuse it for the next thread executing this method
874  */
876  "*** Completed execution of one thread, %u threads remaining\n",
877  MethodDesc->Method.ThreadCount));
878  }
879  else
880  {
881  /* This is the only executing thread for this method */
882 
883  /*
884  * Support to dynamically change a method from NotSerialized to
885  * Serialized if it appears that the method is incorrectly written and
886  * does not support multiple thread execution. The best example of this
887  * is if such a method creates namespace objects and blocks. A second
888  * thread will fail with an AE_ALREADY_EXISTS exception.
889  *
890  * This code is here because we must wait until the last thread exits
891  * before marking the method as serialized.
892  */
894  {
895  if (WalkState)
896  {
897  ACPI_INFO ((
898  "Marking method %4.4s as Serialized "
899  "because of AE_ALREADY_EXISTS error",
900  WalkState->MethodNode->Name.Ascii));
901  }
902 
903  /*
904  * Method tried to create an object twice and was marked as
905  * "pending serialized". The probable cause is that the method
906  * cannot handle reentrancy.
907  *
908  * The method was created as NotSerialized, but it tried to create
909  * a named object and then blocked, causing the second thread
910  * entrance to begin and then fail. Workaround this problem by
911  * marking the method permanently as Serialized when the last
912  * thread exits here.
913  */
914  MethodDesc->Method.InfoFlags &=
916 
917  MethodDesc->Method.InfoFlags |=
919  MethodDesc->Method.SyncLevel = 0;
920  }
921 
922  /* No more threads, we can free the OwnerId */
923 
924  if (!(MethodDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL))
925  {
926  AcpiUtReleaseOwnerId (&MethodDesc->Method.OwnerId);
927  }
928  }
929 
931  MethodDesc, WalkState);
932 
933  return_VOID;
934 }
ACPI_THREAD_STATE * Thread
Definition: acstruct.h:127
#define ACPI_METHOD_IGNORE_SYNC_LEVEL
Definition: acobject.h:239
void AcpiUtReleaseOwnerId(ACPI_OWNER_ID *OwnerId)
Definition: utownerid.c:190
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
ACPI_MUTEX OsMutex
Definition: acobject.h:188
#define ACPI_METHOD_SERIALIZED
Definition: acobject.h:237
ACPI_OBJECT_COMMON_HEADER UINT8 InfoFlags
Definition: acobject.h:215
ACPI_OBJECT_MUTEX Mutex
Definition: acobject.h:523
UINT8 OriginalSyncLevel
Definition: acobject.h:194
UINT16 AcquisitionDepth
Definition: acobject.h:187
#define ACPI_METHOD_MODIFIED_NAMESPACE
Definition: acobject.h:240
#define AE_INFO
Definition: acoutput.h:230
#define ACPI_METHOD_SERIALIZED_PENDING
Definition: acobject.h:238
#define ACPI_FUNCTION_TRACE_PTR(a, b)
Definition: acoutput.h:481
#define ACPI_DB_DISPATCH
Definition: acoutput.h:163
void AcpiDsMethodDataDeleteAll(ACPI_WALK_STATE *WalkState)
Definition: dsmthdat.c:153
ACPI_STATE_COMMON UINT8 CurrentSyncLevel
Definition: aclocal.h:764
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
#define return_VOID
Definition: acoutput.h:495
void AcpiNsDeleteNamespaceSubtree(ACPI_NAMESPACE_NODE *ParentHandle)
Definition: nsalloc.c:399
ACPI_THREAD_ID ThreadId
Definition: acobject.h:189
#define ACPI_METHOD_MODULE_LEVEL
Definition: acobject.h:235
union acpi_operand_object * Mutex
Definition: acobject.h:218
struct acpi_namespace_node * MethodNode
Definition: acstruct.h:116
#define ACPI_INFO(plist)
Definition: acoutput.h:237
ACPI_OBJECT_METHOD Method
Definition: acobject.h:522
void AcpiExExitInterpreter(void)
Definition: exutils.c:139
void AcpiExEnterInterpreter(void)
Definition: exutils.c:91
void AcpiExStopTraceMethod(ACPI_NAMESPACE_NODE *MethodNode, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_WALK_STATE *WalkState)
Definition: extrace.c:290
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
void AcpiOsReleaseMutex(ACPI_MUTEX Handle)
Definition: osl.c:333
ACPI_OWNER_ID OwnerId
Definition: acobject.h:228
void AcpiNsDeleteNamespaceByOwner(ACPI_OWNER_ID OwnerId)
Definition: nsalloc.c:497
union acpi_operand_object * Node
Definition: acobject.h:219

Referenced by AcpiDsCallControlMethod(), AcpiPsExecuteMethod(), and AcpiPsParseAml().