1 /*******************************************************************************
3 * Module Name: dbmethod - Debug commands for control methods
5 ******************************************************************************/
8 * Copyright (C) 2000 - 2013, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
57 #define _COMPONENT ACPI_CA_DEBUGGER
58 ACPI_MODULE_NAME ("dbmethod")
61 /* Local prototypes */
64 AcpiDbWalkForExecute (
65 ACPI_HANDLE ObjHandle
,
71 /*******************************************************************************
73 * FUNCTION: AcpiDbSetMethodBreakpoint
75 * PARAMETERS: Location - AML offset of breakpoint
76 * WalkState - Current walk info
77 * Op - Current Op (from parse walk)
81 * DESCRIPTION: Set a breakpoint in a control method at the specified
84 ******************************************************************************/
87 AcpiDbSetMethodBreakpoint (
89 ACPI_WALK_STATE
*WalkState
,
90 ACPI_PARSE_OBJECT
*Op
)
97 AcpiOsPrintf ("There is no method currently executing\n");
101 /* Get and verify the breakpoint address */
103 Address
= ACPI_STRTOUL (Location
, NULL
, 16);
104 if (Address
<= Op
->Common
.AmlOffset
)
106 AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n",
107 Address
, Op
->Common
.AmlOffset
);
110 /* Save breakpoint in current walk */
112 WalkState
->UserBreakpoint
= Address
;
113 AcpiOsPrintf ("Breakpoint set at AML offset %X\n", Address
);
117 /*******************************************************************************
119 * FUNCTION: AcpiDbSetMethodCallBreakpoint
121 * PARAMETERS: Op - Current Op (from parse walk)
125 * DESCRIPTION: Set a breakpoint in a control method at the specified
128 ******************************************************************************/
131 AcpiDbSetMethodCallBreakpoint (
132 ACPI_PARSE_OBJECT
*Op
)
138 AcpiOsPrintf ("There is no method currently executing\n");
142 AcpiGbl_StepToNextCall
= TRUE
;
146 /*******************************************************************************
148 * FUNCTION: AcpiDbSetMethodData
150 * PARAMETERS: TypeArg - L for local, A for argument
151 * IndexArg - which one
152 * ValueArg - Value to set.
156 * DESCRIPTION: Set a local or argument for the running control method.
157 * NOTE: only object supported is Number.
159 ******************************************************************************/
162 AcpiDbSetMethodData (
170 ACPI_WALK_STATE
*WalkState
;
171 ACPI_OPERAND_OBJECT
*ObjDesc
;
173 ACPI_NAMESPACE_NODE
*Node
;
176 /* Validate TypeArg */
178 AcpiUtStrupr (TypeArg
);
184 AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg
);
188 Value
= ACPI_STRTOUL (ValueArg
, NULL
, 16);
192 Node
= AcpiDbConvertToNode (IndexArg
);
193 if (Node
->Type
!= ACPI_TYPE_INTEGER
)
195 AcpiOsPrintf ("Can only set Integer nodes\n");
198 ObjDesc
= Node
->Object
;
199 ObjDesc
->Integer
.Value
= Value
;
203 /* Get the index and value */
205 Index
= ACPI_STRTOUL (IndexArg
, NULL
, 16);
207 WalkState
= AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList
);
210 AcpiOsPrintf ("There is no method currently executing\n");
214 /* Create and initialize the new object */
216 ObjDesc
= AcpiUtCreateIntegerObject ((UINT64
) Value
);
219 AcpiOsPrintf ("Could not create an internal object\n");
223 /* Store the new object into the target */
229 /* Set a method argument */
231 if (Index
> ACPI_METHOD_MAX_ARG
)
233 AcpiOsPrintf ("Arg%u - Invalid argument name\n", Index
);
237 Status
= AcpiDsStoreObjectToLocal (ACPI_REFCLASS_ARG
, Index
, ObjDesc
,
239 if (ACPI_FAILURE (Status
))
244 ObjDesc
= WalkState
->Arguments
[Index
].Object
;
246 AcpiOsPrintf ("Arg%u: ", Index
);
247 AcpiDmDisplayInternalObject (ObjDesc
, WalkState
);
252 /* Set a method local */
254 if (Index
> ACPI_METHOD_MAX_LOCAL
)
256 AcpiOsPrintf ("Local%u - Invalid local variable name\n", Index
);
260 Status
= AcpiDsStoreObjectToLocal (ACPI_REFCLASS_LOCAL
, Index
, ObjDesc
,
262 if (ACPI_FAILURE (Status
))
267 ObjDesc
= WalkState
->LocalVariables
[Index
].Object
;
269 AcpiOsPrintf ("Local%u: ", Index
);
270 AcpiDmDisplayInternalObject (ObjDesc
, WalkState
);
279 AcpiUtRemoveReference (ObjDesc
);
283 /*******************************************************************************
285 * FUNCTION: AcpiDbDisassembleAml
287 * PARAMETERS: Statements - Number of statements to disassemble
288 * Op - Current Op (from parse walk)
292 * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
293 * of statements specified.
295 ******************************************************************************/
298 AcpiDbDisassembleAml (
300 ACPI_PARSE_OBJECT
*Op
)
302 UINT32 NumStatements
= 8;
307 AcpiOsPrintf ("There is no method currently executing\n");
313 NumStatements
= ACPI_STRTOUL (Statements
, NULL
, 0);
316 AcpiDmDisassemble (NULL
, Op
, NumStatements
);
320 /*******************************************************************************
322 * FUNCTION: AcpiDbDisassembleMethod
324 * PARAMETERS: Name - Name of control method
328 * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
329 * of statements specified.
331 ******************************************************************************/
334 AcpiDbDisassembleMethod (
338 ACPI_PARSE_OBJECT
*Op
;
339 ACPI_WALK_STATE
*WalkState
;
340 ACPI_OPERAND_OBJECT
*ObjDesc
;
341 ACPI_NAMESPACE_NODE
*Method
;
344 Method
= AcpiDbConvertToNode (Name
);
347 return (AE_BAD_PARAMETER
);
350 if (Method
->Type
!= ACPI_TYPE_METHOD
)
352 ACPI_ERROR ((AE_INFO
, "%s (%s): Object must be a control method",
353 Name
, AcpiUtGetTypeName (Method
->Type
)));
354 return (AE_BAD_PARAMETER
);
357 ObjDesc
= Method
->Object
;
359 Op
= AcpiPsCreateScopeOp ();
362 return (AE_NO_MEMORY
);
365 /* Create and initialize a new walk state */
367 WalkState
= AcpiDsCreateWalkState (0, Op
, NULL
, NULL
);
370 return (AE_NO_MEMORY
);
373 Status
= AcpiDsInitAmlWalk (WalkState
, Op
, NULL
,
374 ObjDesc
->Method
.AmlStart
,
375 ObjDesc
->Method
.AmlLength
, NULL
, ACPI_IMODE_LOAD_PASS1
);
376 if (ACPI_FAILURE (Status
))
381 Status
= AcpiUtAllocateOwnerId (&ObjDesc
->Method
.OwnerId
);
382 WalkState
->OwnerId
= ObjDesc
->Method
.OwnerId
;
384 /* Push start scope on scope stack and make it current */
386 Status
= AcpiDsScopeStackPush (Method
,
387 Method
->Type
, WalkState
);
388 if (ACPI_FAILURE (Status
))
393 /* Parse the entire method AML including deferred operators */
395 WalkState
->ParseFlags
&= ~ACPI_PARSE_DELETE_TREE
;
396 WalkState
->ParseFlags
|= ACPI_PARSE_DISASSEMBLE
;
398 Status
= AcpiPsParseAml (WalkState
);
399 (void) AcpiDmParseDeferredOps (Op
);
401 /* Now we can disassemble the method */
403 AcpiGbl_DbOpt_verbose
= FALSE
;
404 AcpiDmDisassemble (NULL
, Op
, 0);
405 AcpiGbl_DbOpt_verbose
= TRUE
;
407 AcpiPsDeleteParseTree (Op
);
411 AcpiNsDeleteNamespaceSubtree (Method
);
412 AcpiNsDeleteNamespaceByOwner (ObjDesc
->Method
.OwnerId
);
413 AcpiUtReleaseOwnerId (&ObjDesc
->Method
.OwnerId
);
418 /*******************************************************************************
420 * FUNCTION: AcpiDbWalkForExecute
422 * PARAMETERS: Callback from WalkNamespace
426 * DESCRIPTION: Batch execution module. Currently only executes predefined
429 ******************************************************************************/
432 AcpiDbWalkForExecute (
433 ACPI_HANDLE ObjHandle
,
438 ACPI_NAMESPACE_NODE
*Node
= (ACPI_NAMESPACE_NODE
*) ObjHandle
;
439 ACPI_DB_EXECUTE_WALK
*Info
= (ACPI_DB_EXECUTE_WALK
*) Context
;
441 const ACPI_PREDEFINED_INFO
*Predefined
;
442 ACPI_DEVICE_INFO
*ObjInfo
;
443 ACPI_OBJECT_LIST ParamObjects
;
444 ACPI_OBJECT Params
[ACPI_METHOD_NUM_ARGS
];
445 ACPI_OBJECT
*ThisParam
;
446 ACPI_BUFFER ReturnObj
;
454 /* The name must be a predefined ACPI name */
456 Predefined
= AcpiUtMatchPredefinedMethod (Node
->Name
.Ascii
);
462 if (Node
->Type
== ACPI_TYPE_LOCAL_SCOPE
)
467 Pathname
= AcpiNsGetExternalPathname (Node
);
473 /* Get the object info for number of method parameters */
475 Status
= AcpiGetObjectInfo (ObjHandle
, &ObjInfo
);
476 if (ACPI_FAILURE (Status
))
481 ParamObjects
.Count
= 0;
482 ParamObjects
.Pointer
= NULL
;
484 if (ObjInfo
->Type
== ACPI_TYPE_METHOD
)
486 /* Setup default parameters (with proper types) */
488 ArgTypeList
= Predefined
->Info
.ArgumentList
;
489 ArgCount
= METHOD_GET_ARG_COUNT (ArgTypeList
);
492 * Setup the ACPI-required number of arguments, regardless of what
493 * the actual method defines. If there is a difference, then the
494 * method is wrong and a warning will be issued during execution.
497 for (i
= 0; i
< ArgCount
; i
++)
499 ArgType
= METHOD_GET_NEXT_TYPE (ArgTypeList
);
500 ThisParam
->Type
= ArgType
;
504 case ACPI_TYPE_INTEGER
:
506 ThisParam
->Integer
.Value
= 1;
509 case ACPI_TYPE_STRING
:
511 ThisParam
->String
.Pointer
= "This is the default argument string";
512 ThisParam
->String
.Length
= ACPI_STRLEN (ThisParam
->String
.Pointer
);
515 case ACPI_TYPE_BUFFER
:
517 ThisParam
->Buffer
.Pointer
= (UINT8
*) Params
; /* just a garbage buffer */
518 ThisParam
->Buffer
.Length
= 48;
521 case ACPI_TYPE_PACKAGE
:
523 ThisParam
->Package
.Elements
= NULL
;
524 ThisParam
->Package
.Count
= 0;
529 AcpiOsPrintf ("%s: Unsupported argument type: %u\n",
537 ParamObjects
.Count
= ArgCount
;
538 ParamObjects
.Pointer
= Params
;
542 ReturnObj
.Pointer
= NULL
;
543 ReturnObj
.Length
= ACPI_ALLOCATE_BUFFER
;
545 /* Do the actual method execution */
547 AcpiGbl_MethodExecuting
= TRUE
;
549 Status
= AcpiEvaluateObject (Node
, NULL
, &ParamObjects
, &ReturnObj
);
551 AcpiOsPrintf ("%-32s returned %s\n", Pathname
, AcpiFormatException (Status
));
552 AcpiGbl_MethodExecuting
= FALSE
;
553 ACPI_FREE (Pathname
);
555 /* Ignore status from method execution */
559 /* Update count, check if we have executed enough methods */
562 if (Info
->Count
>= Info
->MaxCount
)
564 Status
= AE_CTRL_TERMINATE
;
571 /*******************************************************************************
573 * FUNCTION: AcpiDbBatchExecute
575 * PARAMETERS: CountArg - Max number of methods to execute
579 * DESCRIPTION: Namespace batch execution. Execute predefined names in the
580 * namespace, up to the max count, if specified.
582 ******************************************************************************/
588 ACPI_DB_EXECUTE_WALK Info
;
592 Info
.MaxCount
= ACPI_UINT32_MAX
;
596 Info
.MaxCount
= ACPI_STRTOUL (CountArg
, NULL
, 0);
600 /* Search all nodes in namespace */
602 (void) AcpiWalkNamespace (ACPI_TYPE_ANY
, ACPI_ROOT_OBJECT
, ACPI_UINT32_MAX
,
603 AcpiDbWalkForExecute
, NULL
, (void *) &Info
, NULL
);
605 AcpiOsPrintf ("Evaluated %u predefined names in the namespace\n", Info
.Count
);
608 #endif /* ACPI_DEBUGGER */