OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [acpi/] [dispatcher/] [dsutils.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*******************************************************************************
2
 *
3
 * Module Name: dsutils - Dispatcher utilities
4
 *
5
 ******************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2007, R. Byron Moore
9
 * All rights reserved.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
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.
25
 *
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.
29
 *
30
 * NO WARRANTY
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.
42
 */
43
 
44
#include <acpi/acpi.h>
45
#include <acpi/acparser.h>
46
#include <acpi/amlcode.h>
47
#include <acpi/acdispat.h>
48
#include <acpi/acinterp.h>
49
#include <acpi/acnamesp.h>
50
#include <acpi/acdebug.h>
51
 
52
#define _COMPONENT          ACPI_DISPATCHER
53
ACPI_MODULE_NAME("dsutils")
54
 
55
/*******************************************************************************
56
 *
57
 * FUNCTION:    acpi_ds_clear_implicit_return
58
 *
59
 * PARAMETERS:  walk_state          - Current State
60
 *
61
 * RETURN:      None.
62
 *
63
 * DESCRIPTION: Clear and remove a reference on an implicit return value.  Used
64
 *              to delete "stale" return values (if enabled, the return value
65
 *              from every operator is saved at least momentarily, in case the
66
 *              parent method exits.)
67
 *
68
 ******************************************************************************/
69
void acpi_ds_clear_implicit_return(struct acpi_walk_state *walk_state)
70
{
71
        ACPI_FUNCTION_NAME(ds_clear_implicit_return);
72
 
73
        /*
74
         * Slack must be enabled for this feature
75
         */
76
        if (!acpi_gbl_enable_interpreter_slack) {
77
                return;
78
        }
79
 
80
        if (walk_state->implicit_return_obj) {
81
                /*
82
                 * Delete any "stale" implicit return. However, in
83
                 * complex statements, the implicit return value can be
84
                 * bubbled up several levels.
85
                 */
86
                ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
87
                                  "Removing reference on stale implicit return obj %p\n",
88
                                  walk_state->implicit_return_obj));
89
 
90
                acpi_ut_remove_reference(walk_state->implicit_return_obj);
91
                walk_state->implicit_return_obj = NULL;
92
        }
93
}
94
 
95
#ifndef ACPI_NO_METHOD_EXECUTION
96
/*******************************************************************************
97
 *
98
 * FUNCTION:    acpi_ds_do_implicit_return
99
 *
100
 * PARAMETERS:  return_desc         - The return value
101
 *              walk_state          - Current State
102
 *              add_reference       - True if a reference should be added to the
103
 *                                    return object
104
 *
105
 * RETURN:      TRUE if implicit return enabled, FALSE otherwise
106
 *
107
 * DESCRIPTION: Implements the optional "implicit return".  We save the result
108
 *              of every ASL operator and control method invocation in case the
109
 *              parent method exit.  Before storing a new return value, we
110
 *              delete the previous return value.
111
 *
112
 ******************************************************************************/
113
 
114
u8
115
acpi_ds_do_implicit_return(union acpi_operand_object *return_desc,
116
                           struct acpi_walk_state *walk_state, u8 add_reference)
117
{
118
        ACPI_FUNCTION_NAME(ds_do_implicit_return);
119
 
120
        /*
121
         * Slack must be enabled for this feature, and we must
122
         * have a valid return object
123
         */
124
        if ((!acpi_gbl_enable_interpreter_slack) || (!return_desc)) {
125
                return (FALSE);
126
        }
127
 
128
        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
129
                          "Result %p will be implicitly returned; Prev=%p\n",
130
                          return_desc, walk_state->implicit_return_obj));
131
 
132
        /*
133
         * Delete any "stale" implicit return value first. However, in
134
         * complex statements, the implicit return value can be
135
         * bubbled up several levels, so we don't clear the value if it
136
         * is the same as the return_desc.
137
         */
138
        if (walk_state->implicit_return_obj) {
139
                if (walk_state->implicit_return_obj == return_desc) {
140
                        return (TRUE);
141
                }
142
                acpi_ds_clear_implicit_return(walk_state);
143
        }
144
 
145
        /* Save the implicit return value, add a reference if requested */
146
 
147
        walk_state->implicit_return_obj = return_desc;
148
        if (add_reference) {
149
                acpi_ut_add_reference(return_desc);
150
        }
151
 
152
        return (TRUE);
153
}
154
 
155
/*******************************************************************************
156
 *
157
 * FUNCTION:    acpi_ds_is_result_used
158
 *
159
 * PARAMETERS:  Op                  - Current Op
160
 *              walk_state          - Current State
161
 *
162
 * RETURN:      TRUE if result is used, FALSE otherwise
163
 *
164
 * DESCRIPTION: Check if a result object will be used by the parent
165
 *
166
 ******************************************************************************/
167
 
168
u8
169
acpi_ds_is_result_used(union acpi_parse_object * op,
170
                       struct acpi_walk_state * walk_state)
171
{
172
        const struct acpi_opcode_info *parent_info;
173
 
174
        ACPI_FUNCTION_TRACE_PTR(ds_is_result_used, op);
175
 
176
        /* Must have both an Op and a Result Object */
177
 
178
        if (!op) {
179
                ACPI_ERROR((AE_INFO, "Null Op"));
180
                return_UINT8(TRUE);
181
        }
182
 
183
        /*
184
         * We know that this operator is not a
185
         * Return() operator (would not come here.) The following code is the
186
         * optional support for a so-called "implicit return". Some AML code
187
         * assumes that the last value of the method is "implicitly" returned
188
         * to the caller. Just save the last result as the return value.
189
         * NOTE: this is optional because the ASL language does not actually
190
         * support this behavior.
191
         */
192
        (void)acpi_ds_do_implicit_return(walk_state->result_obj, walk_state,
193
                                         TRUE);
194
 
195
        /*
196
         * Now determine if the parent will use the result
197
         *
198
         * If there is no parent, or the parent is a scope_op, we are executing
199
         * at the method level. An executing method typically has no parent,
200
         * since each method is parsed separately.  A method invoked externally
201
         * via execute_control_method has a scope_op as the parent.
202
         */
203
        if ((!op->common.parent) ||
204
            (op->common.parent->common.aml_opcode == AML_SCOPE_OP)) {
205
 
206
                /* No parent, the return value cannot possibly be used */
207
 
208
                ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
209
                                  "At Method level, result of [%s] not used\n",
210
                                  acpi_ps_get_opcode_name(op->common.
211
                                                          aml_opcode)));
212
                return_UINT8(FALSE);
213
        }
214
 
215
        /* Get info on the parent. The root_op is AML_SCOPE */
216
 
217
        parent_info =
218
            acpi_ps_get_opcode_info(op->common.parent->common.aml_opcode);
219
        if (parent_info->class == AML_CLASS_UNKNOWN) {
220
                ACPI_ERROR((AE_INFO, "Unknown parent opcode Op=%p", op));
221
                return_UINT8(FALSE);
222
        }
223
 
224
        /*
225
         * Decide what to do with the result based on the parent.  If
226
         * the parent opcode will not use the result, delete the object.
227
         * Otherwise leave it as is, it will be deleted when it is used
228
         * as an operand later.
229
         */
230
        switch (parent_info->class) {
231
        case AML_CLASS_CONTROL:
232
 
233
                switch (op->common.parent->common.aml_opcode) {
234
                case AML_RETURN_OP:
235
 
236
                        /* Never delete the return value associated with a return opcode */
237
 
238
                        goto result_used;
239
 
240
                case AML_IF_OP:
241
                case AML_WHILE_OP:
242
 
243
                        /*
244
                         * If we are executing the predicate AND this is the predicate op,
245
                         * we will use the return value
246
                         */
247
                        if ((walk_state->control_state->common.state ==
248
                             ACPI_CONTROL_PREDICATE_EXECUTING)
249
                            && (walk_state->control_state->control.
250
                                predicate_op == op)) {
251
                                goto result_used;
252
                        }
253
                        break;
254
 
255
                default:
256
                        /* Ignore other control opcodes */
257
                        break;
258
                }
259
 
260
                /* The general control opcode returns no result */
261
 
262
                goto result_not_used;
263
 
264
        case AML_CLASS_CREATE:
265
 
266
                /*
267
                 * These opcodes allow term_arg(s) as operands and therefore
268
                 * the operands can be method calls.  The result is used.
269
                 */
270
                goto result_used;
271
 
272
        case AML_CLASS_NAMED_OBJECT:
273
 
274
                if ((op->common.parent->common.aml_opcode == AML_REGION_OP) ||
275
                    (op->common.parent->common.aml_opcode == AML_DATA_REGION_OP)
276
                    || (op->common.parent->common.aml_opcode == AML_PACKAGE_OP)
277
                    || (op->common.parent->common.aml_opcode ==
278
                        AML_VAR_PACKAGE_OP)
279
                    || (op->common.parent->common.aml_opcode == AML_BUFFER_OP)
280
                    || (op->common.parent->common.aml_opcode ==
281
                        AML_INT_EVAL_SUBTREE_OP)) {
282
                        /*
283
                         * These opcodes allow term_arg(s) as operands and therefore
284
                         * the operands can be method calls.  The result is used.
285
                         */
286
                        goto result_used;
287
                }
288
 
289
                goto result_not_used;
290
 
291
        default:
292
 
293
                /*
294
                 * In all other cases. the parent will actually use the return
295
                 * object, so keep it.
296
                 */
297
                goto result_used;
298
        }
299
 
300
      result_used:
301
        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
302
                          "Result of [%s] used by Parent [%s] Op=%p\n",
303
                          acpi_ps_get_opcode_name(op->common.aml_opcode),
304
                          acpi_ps_get_opcode_name(op->common.parent->common.
305
                                                  aml_opcode), op));
306
 
307
        return_UINT8(TRUE);
308
 
309
      result_not_used:
310
        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
311
                          "Result of [%s] not used by Parent [%s] Op=%p\n",
312
                          acpi_ps_get_opcode_name(op->common.aml_opcode),
313
                          acpi_ps_get_opcode_name(op->common.parent->common.
314
                                                  aml_opcode), op));
315
 
316
        return_UINT8(FALSE);
317
}
318
 
319
/*******************************************************************************
320
 *
321
 * FUNCTION:    acpi_ds_delete_result_if_not_used
322
 *
323
 * PARAMETERS:  Op              - Current parse Op
324
 *              result_obj      - Result of the operation
325
 *              walk_state      - Current state
326
 *
327
 * RETURN:      Status
328
 *
329
 * DESCRIPTION: Used after interpretation of an opcode.  If there is an internal
330
 *              result descriptor, check if the parent opcode will actually use
331
 *              this result.  If not, delete the result now so that it will
332
 *              not become orphaned.
333
 *
334
 ******************************************************************************/
335
 
336
void
337
acpi_ds_delete_result_if_not_used(union acpi_parse_object *op,
338
                                  union acpi_operand_object *result_obj,
339
                                  struct acpi_walk_state *walk_state)
340
{
341
        union acpi_operand_object *obj_desc;
342
        acpi_status status;
343
 
344
        ACPI_FUNCTION_TRACE_PTR(ds_delete_result_if_not_used, result_obj);
345
 
346
        if (!op) {
347
                ACPI_ERROR((AE_INFO, "Null Op"));
348
                return_VOID;
349
        }
350
 
351
        if (!result_obj) {
352
                return_VOID;
353
        }
354
 
355
        if (!acpi_ds_is_result_used(op, walk_state)) {
356
 
357
                /* Must pop the result stack (obj_desc should be equal to result_obj) */
358
 
359
                status = acpi_ds_result_pop(&obj_desc, walk_state);
360
                if (ACPI_SUCCESS(status)) {
361
                        acpi_ut_remove_reference(result_obj);
362
                }
363
        }
364
 
365
        return_VOID;
366
}
367
 
368
/*******************************************************************************
369
 *
370
 * FUNCTION:    acpi_ds_resolve_operands
371
 *
372
 * PARAMETERS:  walk_state          - Current walk state with operands on stack
373
 *
374
 * RETURN:      Status
375
 *
376
 * DESCRIPTION: Resolve all operands to their values.  Used to prepare
377
 *              arguments to a control method invocation (a call from one
378
 *              method to another.)
379
 *
380
 ******************************************************************************/
381
 
382
acpi_status acpi_ds_resolve_operands(struct acpi_walk_state *walk_state)
383
{
384
        u32 i;
385
        acpi_status status = AE_OK;
386
 
387
        ACPI_FUNCTION_TRACE_PTR(ds_resolve_operands, walk_state);
388
 
389
        /*
390
         * Attempt to resolve each of the valid operands
391
         * Method arguments are passed by reference, not by value.  This means
392
         * that the actual objects are passed, not copies of the objects.
393
         */
394
        for (i = 0; i < walk_state->num_operands; i++) {
395
                status =
396
                    acpi_ex_resolve_to_value(&walk_state->operands[i],
397
                                             walk_state);
398
                if (ACPI_FAILURE(status)) {
399
                        break;
400
                }
401
        }
402
 
403
        return_ACPI_STATUS(status);
404
}
405
 
406
/*******************************************************************************
407
 *
408
 * FUNCTION:    acpi_ds_clear_operands
409
 *
410
 * PARAMETERS:  walk_state          - Current walk state with operands on stack
411
 *
412
 * RETURN:      None
413
 *
414
 * DESCRIPTION: Clear all operands on the current walk state operand stack.
415
 *
416
 ******************************************************************************/
417
 
418
void acpi_ds_clear_operands(struct acpi_walk_state *walk_state)
419
{
420
        u32 i;
421
 
422
        ACPI_FUNCTION_TRACE_PTR(ds_clear_operands, walk_state);
423
 
424
        /* Remove a reference on each operand on the stack */
425
 
426
        for (i = 0; i < walk_state->num_operands; i++) {
427
                /*
428
                 * Remove a reference to all operands, including both
429
                 * "Arguments" and "Targets".
430
                 */
431
                acpi_ut_remove_reference(walk_state->operands[i]);
432
                walk_state->operands[i] = NULL;
433
        }
434
 
435
        walk_state->num_operands = 0;
436
        return_VOID;
437
}
438
#endif
439
 
440
/*******************************************************************************
441
 *
442
 * FUNCTION:    acpi_ds_create_operand
443
 *
444
 * PARAMETERS:  walk_state      - Current walk state
445
 *              Arg             - Parse object for the argument
446
 *              arg_index       - Which argument (zero based)
447
 *
448
 * RETURN:      Status
449
 *
450
 * DESCRIPTION: Translate a parse tree object that is an argument to an AML
451
 *              opcode to the equivalent interpreter object.  This may include
452
 *              looking up a name or entering a new name into the internal
453
 *              namespace.
454
 *
455
 ******************************************************************************/
456
 
457
acpi_status
458
acpi_ds_create_operand(struct acpi_walk_state *walk_state,
459
                       union acpi_parse_object *arg, u32 arg_index)
460
{
461
        acpi_status status = AE_OK;
462
        char *name_string;
463
        u32 name_length;
464
        union acpi_operand_object *obj_desc;
465
        union acpi_parse_object *parent_op;
466
        u16 opcode;
467
        acpi_interpreter_mode interpreter_mode;
468
        const struct acpi_opcode_info *op_info;
469
 
470
        ACPI_FUNCTION_TRACE_PTR(ds_create_operand, arg);
471
 
472
        /* A valid name must be looked up in the namespace */
473
 
474
        if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
475
            (arg->common.value.string)) {
476
                ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n",
477
                                  arg));
478
 
479
                /* Get the entire name string from the AML stream */
480
 
481
                status =
482
                    acpi_ex_get_name_string(ACPI_TYPE_ANY,
483
                                            arg->common.value.buffer,
484
                                            &name_string, &name_length);
485
 
486
                if (ACPI_FAILURE(status)) {
487
                        return_ACPI_STATUS(status);
488
                }
489
 
490
                /* All prefixes have been handled, and the name is in name_string */
491
 
492
                /*
493
                 * Special handling for buffer_field declarations. This is a deferred
494
                 * opcode that unfortunately defines the field name as the last
495
                 * parameter instead of the first.  We get here when we are performing
496
                 * the deferred execution, so the actual name of the field is already
497
                 * in the namespace.  We don't want to attempt to look it up again
498
                 * because we may be executing in a different scope than where the
499
                 * actual opcode exists.
500
                 */
501
                if ((walk_state->deferred_node) &&
502
                    (walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD)
503
                    && (arg_index ==
504
                        (u32) ((walk_state->opcode ==
505
                                AML_CREATE_FIELD_OP) ? 3 : 2))) {
506
                        obj_desc =
507
                            ACPI_CAST_PTR(union acpi_operand_object,
508
                                          walk_state->deferred_node);
509
                        status = AE_OK;
510
                } else {        /* All other opcodes */
511
 
512
                        /*
513
                         * Differentiate between a namespace "create" operation
514
                         * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
515
                         * IMODE_EXECUTE) in order to support the creation of
516
                         * namespace objects during the execution of control methods.
517
                         */
518
                        parent_op = arg->common.parent;
519
                        op_info =
520
                            acpi_ps_get_opcode_info(parent_op->common.
521
                                                    aml_opcode);
522
                        if ((op_info->flags & AML_NSNODE)
523
                            && (parent_op->common.aml_opcode !=
524
                                AML_INT_METHODCALL_OP)
525
                            && (parent_op->common.aml_opcode != AML_REGION_OP)
526
                            && (parent_op->common.aml_opcode !=
527
                                AML_INT_NAMEPATH_OP)) {
528
 
529
                                /* Enter name into namespace if not found */
530
 
531
                                interpreter_mode = ACPI_IMODE_LOAD_PASS2;
532
                        } else {
533
                                /* Return a failure if name not found */
534
 
535
                                interpreter_mode = ACPI_IMODE_EXECUTE;
536
                        }
537
 
538
                        status =
539
                            acpi_ns_lookup(walk_state->scope_info, name_string,
540
                                           ACPI_TYPE_ANY, interpreter_mode,
541
                                           ACPI_NS_SEARCH_PARENT |
542
                                           ACPI_NS_DONT_OPEN_SCOPE, walk_state,
543
                                           ACPI_CAST_INDIRECT_PTR(struct
544
                                                                  acpi_namespace_node,
545
                                                                  &obj_desc));
546
                        /*
547
                         * The only case where we pass through (ignore) a NOT_FOUND
548
                         * error is for the cond_ref_of opcode.
549
                         */
550
                        if (status == AE_NOT_FOUND) {
551
                                if (parent_op->common.aml_opcode ==
552
                                    AML_COND_REF_OF_OP) {
553
                                        /*
554
                                         * For the Conditional Reference op, it's OK if
555
                                         * the name is not found;  We just need a way to
556
                                         * indicate this to the interpreter, set the
557
                                         * object to the root
558
                                         */
559
                                        obj_desc = ACPI_CAST_PTR(union
560
                                                                 acpi_operand_object,
561
                                                                 acpi_gbl_root_node);
562
                                        status = AE_OK;
563
                                } else {
564
                                        /*
565
                                         * We just plain didn't find it -- which is a
566
                                         * very serious error at this point
567
                                         */
568
                                        status = AE_AML_NAME_NOT_FOUND;
569
                                }
570
                        }
571
 
572
                        if (ACPI_FAILURE(status)) {
573
                                ACPI_ERROR_NAMESPACE(name_string, status);
574
                        }
575
                }
576
 
577
                /* Free the namestring created above */
578
 
579
                ACPI_FREE(name_string);
580
 
581
                /* Check status from the lookup */
582
 
583
                if (ACPI_FAILURE(status)) {
584
                        return_ACPI_STATUS(status);
585
                }
586
 
587
                /* Put the resulting object onto the current object stack */
588
 
589
                status = acpi_ds_obj_stack_push(obj_desc, walk_state);
590
                if (ACPI_FAILURE(status)) {
591
                        return_ACPI_STATUS(status);
592
                }
593
                ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
594
                                   (obj_desc, walk_state));
595
        } else {
596
                /* Check for null name case */
597
 
598
                if (arg->common.aml_opcode == AML_INT_NAMEPATH_OP) {
599
                        /*
600
                         * If the name is null, this means that this is an
601
                         * optional result parameter that was not specified
602
                         * in the original ASL.  Create a Zero Constant for a
603
                         * placeholder.  (Store to a constant is a Noop.)
604
                         */
605
                        opcode = AML_ZERO_OP;   /* Has no arguments! */
606
 
607
                        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
608
                                          "Null namepath: Arg=%p\n", arg));
609
                } else {
610
                        opcode = arg->common.aml_opcode;
611
                }
612
 
613
                /* Get the object type of the argument */
614
 
615
                op_info = acpi_ps_get_opcode_info(opcode);
616
                if (op_info->object_type == ACPI_TYPE_INVALID) {
617
                        return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
618
                }
619
 
620
                if (op_info->flags & AML_HAS_RETVAL) {
621
                        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
622
                                          "Argument previously created, already stacked\n"));
623
 
624
                        ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
625
                                           (walk_state->
626
                                            operands[walk_state->num_operands -
627
                                                     1], walk_state));
628
 
629
                        /*
630
                         * Use value that was already previously returned
631
                         * by the evaluation of this argument
632
                         */
633
                        status =
634
                            acpi_ds_result_pop_from_bottom(&obj_desc,
635
                                                           walk_state);
636
                        if (ACPI_FAILURE(status)) {
637
                                /*
638
                                 * Only error is underflow, and this indicates
639
                                 * a missing or null operand!
640
                                 */
641
                                ACPI_EXCEPTION((AE_INFO, status,
642
                                                "Missing or null operand"));
643
                                return_ACPI_STATUS(status);
644
                        }
645
                } else {
646
                        /* Create an ACPI_INTERNAL_OBJECT for the argument */
647
 
648
                        obj_desc =
649
                            acpi_ut_create_internal_object(op_info->
650
                                                           object_type);
651
                        if (!obj_desc) {
652
                                return_ACPI_STATUS(AE_NO_MEMORY);
653
                        }
654
 
655
                        /* Initialize the new object */
656
 
657
                        status =
658
                            acpi_ds_init_object_from_op(walk_state, arg, opcode,
659
                                                        &obj_desc);
660
                        if (ACPI_FAILURE(status)) {
661
                                acpi_ut_delete_object_desc(obj_desc);
662
                                return_ACPI_STATUS(status);
663
                        }
664
                }
665
 
666
                /* Put the operand object on the object stack */
667
 
668
                status = acpi_ds_obj_stack_push(obj_desc, walk_state);
669
                if (ACPI_FAILURE(status)) {
670
                        return_ACPI_STATUS(status);
671
                }
672
 
673
                ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
674
                                   (obj_desc, walk_state));
675
        }
676
 
677
        return_ACPI_STATUS(AE_OK);
678
}
679
 
680
/*******************************************************************************
681
 *
682
 * FUNCTION:    acpi_ds_create_operands
683
 *
684
 * PARAMETERS:  walk_state          - Current state
685
 *              first_arg           - First argument of a parser argument tree
686
 *
687
 * RETURN:      Status
688
 *
689
 * DESCRIPTION: Convert an operator's arguments from a parse tree format to
690
 *              namespace objects and place those argument object on the object
691
 *              stack in preparation for evaluation by the interpreter.
692
 *
693
 ******************************************************************************/
694
 
695
acpi_status
696
acpi_ds_create_operands(struct acpi_walk_state *walk_state,
697
                        union acpi_parse_object *first_arg)
698
{
699
        acpi_status status = AE_OK;
700
        union acpi_parse_object *arg;
701
        u32 arg_count = 0;
702
 
703
        ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg);
704
 
705
        /* For all arguments in the list... */
706
 
707
        arg = first_arg;
708
        while (arg) {
709
                status = acpi_ds_create_operand(walk_state, arg, arg_count);
710
                if (ACPI_FAILURE(status)) {
711
                        goto cleanup;
712
                }
713
 
714
                ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
715
                                  "Arg #%d (%p) done, Arg1=%p\n", arg_count,
716
                                  arg, first_arg));
717
 
718
                /* Move on to next argument, if any */
719
 
720
                arg = arg->common.next;
721
                arg_count++;
722
        }
723
 
724
        return_ACPI_STATUS(status);
725
 
726
      cleanup:
727
        /*
728
         * We must undo everything done above; meaning that we must
729
         * pop everything off of the operand stack and delete those
730
         * objects
731
         */
732
        (void)acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state);
733
 
734
        ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d",
735
                        (arg_count + 1)));
736
        return_ACPI_STATUS(status);
737
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.