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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [acpi/] [executer/] [exresolv.c] - Blame information for rev 67

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
 
2
/******************************************************************************
3
 *
4
 * Module Name: exresolv - AML Interpreter object resolution
5
 *
6
 *****************************************************************************/
7
 
8
/*
9
 * Copyright (C) 2000 - 2007, R. Byron Moore
10
 * All rights reserved.
11
 *
12
 * Redistribution and use in source and binary forms, with or without
13
 * modification, are permitted provided that the following conditions
14
 * are met:
15
 * 1. Redistributions of source code must retain the above copyright
16
 *    notice, this list of conditions, and the following disclaimer,
17
 *    without modification.
18
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19
 *    substantially similar to the "NO WARRANTY" disclaimer below
20
 *    ("Disclaimer") and any redistribution must be conditioned upon
21
 *    including a substantially similar Disclaimer requirement for further
22
 *    binary redistribution.
23
 * 3. Neither the names of the above-listed copyright holders nor the names
24
 *    of any contributors may be used to endorse or promote products derived
25
 *    from this software without specific prior written permission.
26
 *
27
 * Alternatively, this software may be distributed under the terms of the
28
 * GNU General Public License ("GPL") version 2 as published by the Free
29
 * Software Foundation.
30
 *
31
 * NO WARRANTY
32
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42
 * POSSIBILITY OF SUCH DAMAGES.
43
 */
44
 
45
#include <acpi/acpi.h>
46
#include <acpi/amlcode.h>
47
#include <acpi/acdispat.h>
48
#include <acpi/acinterp.h>
49
#include <acpi/acnamesp.h>
50
#include <acpi/acparser.h>
51
 
52
#define _COMPONENT          ACPI_EXECUTER
53
ACPI_MODULE_NAME("exresolv")
54
 
55
/* Local prototypes */
56
static acpi_status
57
acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
58
                                struct acpi_walk_state *walk_state);
59
 
60
/*******************************************************************************
61
 *
62
 * FUNCTION:    acpi_ex_resolve_to_value
63
 *
64
 * PARAMETERS:  **stack_ptr         - Points to entry on obj_stack, which can
65
 *                                    be either an (union acpi_operand_object *)
66
 *                                    or an acpi_handle.
67
 *              walk_state          - Current method state
68
 *
69
 * RETURN:      Status
70
 *
71
 * DESCRIPTION: Convert Reference objects to values
72
 *
73
 ******************************************************************************/
74
 
75
acpi_status
76
acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr,
77
                         struct acpi_walk_state *walk_state)
78
{
79
        acpi_status status;
80
 
81
        ACPI_FUNCTION_TRACE_PTR(ex_resolve_to_value, stack_ptr);
82
 
83
        if (!stack_ptr || !*stack_ptr) {
84
                ACPI_ERROR((AE_INFO, "Internal - null pointer"));
85
                return_ACPI_STATUS(AE_AML_NO_OPERAND);
86
        }
87
 
88
        /*
89
         * The entity pointed to by the stack_ptr can be either
90
         * 1) A valid union acpi_operand_object, or
91
         * 2) A struct acpi_namespace_node (named_obj)
92
         */
93
        if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_OPERAND) {
94
                status = acpi_ex_resolve_object_to_value(stack_ptr, walk_state);
95
                if (ACPI_FAILURE(status)) {
96
                        return_ACPI_STATUS(status);
97
                }
98
 
99
                if (!*stack_ptr) {
100
                        ACPI_ERROR((AE_INFO, "Internal - null pointer"));
101
                        return_ACPI_STATUS(AE_AML_NO_OPERAND);
102
                }
103
        }
104
 
105
        /*
106
         * Object on the stack may have changed if acpi_ex_resolve_object_to_value()
107
         * was called (i.e., we can't use an _else_ here.)
108
         */
109
        if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_NAMED) {
110
                status =
111
                    acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
112
                                                  (struct acpi_namespace_node,
113
                                                   stack_ptr), walk_state);
114
                if (ACPI_FAILURE(status)) {
115
                        return_ACPI_STATUS(status);
116
                }
117
        }
118
 
119
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Resolved object %p\n", *stack_ptr));
120
        return_ACPI_STATUS(AE_OK);
121
}
122
 
123
/*******************************************************************************
124
 *
125
 * FUNCTION:    acpi_ex_resolve_object_to_value
126
 *
127
 * PARAMETERS:  stack_ptr       - Pointer to an internal object
128
 *              walk_state      - Current method state
129
 *
130
 * RETURN:      Status
131
 *
132
 * DESCRIPTION: Retrieve the value from an internal object. The Reference type
133
 *              uses the associated AML opcode to determine the value.
134
 *
135
 ******************************************************************************/
136
 
137
static acpi_status
138
acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
139
                                struct acpi_walk_state *walk_state)
140
{
141
        acpi_status status = AE_OK;
142
        union acpi_operand_object *stack_desc;
143
        void *temp_node;
144
        union acpi_operand_object *obj_desc = NULL;
145
        u16 opcode;
146
 
147
        ACPI_FUNCTION_TRACE(ex_resolve_object_to_value);
148
 
149
        stack_desc = *stack_ptr;
150
 
151
        /* This is an union acpi_operand_object    */
152
 
153
        switch (ACPI_GET_OBJECT_TYPE(stack_desc)) {
154
        case ACPI_TYPE_LOCAL_REFERENCE:
155
 
156
                opcode = stack_desc->reference.opcode;
157
 
158
                switch (opcode) {
159
                case AML_NAME_OP:
160
 
161
                        /*
162
                         * Convert name reference to a namespace node
163
                         * Then, acpi_ex_resolve_node_to_value can be used to get the value
164
                         */
165
                        temp_node = stack_desc->reference.object;
166
 
167
                        /* Delete the Reference Object */
168
 
169
                        acpi_ut_remove_reference(stack_desc);
170
 
171
                        /* Return the namespace node */
172
 
173
                        (*stack_ptr) = temp_node;
174
                        break;
175
 
176
                case AML_LOCAL_OP:
177
                case AML_ARG_OP:
178
 
179
                        /*
180
                         * Get the local from the method's state info
181
                         * Note: this increments the local's object reference count
182
                         */
183
                        status = acpi_ds_method_data_get_value(opcode,
184
                                                               stack_desc->
185
                                                               reference.offset,
186
                                                               walk_state,
187
                                                               &obj_desc);
188
                        if (ACPI_FAILURE(status)) {
189
                                return_ACPI_STATUS(status);
190
                        }
191
 
192
                        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
193
                                          "[Arg/Local %X] ValueObj is %p\n",
194
                                          stack_desc->reference.offset,
195
                                          obj_desc));
196
 
197
                        /*
198
                         * Now we can delete the original Reference Object and
199
                         * replace it with the resolved value
200
                         */
201
                        acpi_ut_remove_reference(stack_desc);
202
                        *stack_ptr = obj_desc;
203
                        break;
204
 
205
                case AML_INDEX_OP:
206
 
207
                        switch (stack_desc->reference.target_type) {
208
                        case ACPI_TYPE_BUFFER_FIELD:
209
 
210
                                /* Just return - leave the Reference on the stack */
211
                                break;
212
 
213
                        case ACPI_TYPE_PACKAGE:
214
 
215
                                obj_desc = *stack_desc->reference.where;
216
                                if (obj_desc) {
217
                                        /*
218
                                         * Valid obj descriptor, copy pointer to return value
219
                                         * (i.e., dereference the package index)
220
                                         * Delete the ref object, increment the returned object
221
                                         */
222
                                        acpi_ut_remove_reference(stack_desc);
223
                                        acpi_ut_add_reference(obj_desc);
224
                                        *stack_ptr = obj_desc;
225
                                } else {
226
                                        /*
227
                                         * A NULL object descriptor means an unitialized element of
228
                                         * the package, can't dereference it
229
                                         */
230
                                        ACPI_ERROR((AE_INFO,
231
                                                    "Attempt to deref an Index to NULL pkg element Idx=%p",
232
                                                    stack_desc));
233
                                        status = AE_AML_UNINITIALIZED_ELEMENT;
234
                                }
235
                                break;
236
 
237
                        default:
238
 
239
                                /* Invalid reference object */
240
 
241
                                ACPI_ERROR((AE_INFO,
242
                                            "Unknown TargetType %X in Index/Reference obj %p",
243
                                            stack_desc->reference.target_type,
244
                                            stack_desc));
245
                                status = AE_AML_INTERNAL;
246
                                break;
247
                        }
248
                        break;
249
 
250
                case AML_REF_OF_OP:
251
                case AML_DEBUG_OP:
252
                case AML_LOAD_OP:
253
 
254
                        /* Just leave the object as-is */
255
 
256
                        break;
257
 
258
                case AML_INT_NAMEPATH_OP:       /* Reference to a named object */
259
 
260
                        /* Dereference the name */
261
 
262
                        if ((stack_desc->reference.node->type ==
263
                             ACPI_TYPE_DEVICE)
264
                            || (stack_desc->reference.node->type ==
265
                                ACPI_TYPE_THERMAL)) {
266
 
267
                                /* These node types do not have 'real' subobjects */
268
 
269
                                *stack_ptr = (void *)stack_desc->reference.node;
270
                        } else {
271
                                /* Get the object pointed to by the namespace node */
272
 
273
                                *stack_ptr =
274
                                    (stack_desc->reference.node)->object;
275
                                acpi_ut_add_reference(*stack_ptr);
276
                        }
277
 
278
                        acpi_ut_remove_reference(stack_desc);
279
                        break;
280
 
281
                default:
282
 
283
                        ACPI_ERROR((AE_INFO,
284
                                    "Unknown Reference opcode %X (%s) in %p",
285
                                    opcode, acpi_ps_get_opcode_name(opcode),
286
                                    stack_desc));
287
                        status = AE_AML_INTERNAL;
288
                        break;
289
                }
290
                break;
291
 
292
        case ACPI_TYPE_BUFFER:
293
 
294
                status = acpi_ds_get_buffer_arguments(stack_desc);
295
                break;
296
 
297
        case ACPI_TYPE_PACKAGE:
298
 
299
                status = acpi_ds_get_package_arguments(stack_desc);
300
                break;
301
 
302
        case ACPI_TYPE_BUFFER_FIELD:
303
        case ACPI_TYPE_LOCAL_REGION_FIELD:
304
        case ACPI_TYPE_LOCAL_BANK_FIELD:
305
        case ACPI_TYPE_LOCAL_INDEX_FIELD:
306
 
307
                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
308
                                  "FieldRead SourceDesc=%p Type=%X\n",
309
                                  stack_desc,
310
                                  ACPI_GET_OBJECT_TYPE(stack_desc)));
311
 
312
                status =
313
                    acpi_ex_read_data_from_field(walk_state, stack_desc,
314
                                                 &obj_desc);
315
 
316
                /* Remove a reference to the original operand, then override */
317
 
318
                acpi_ut_remove_reference(*stack_ptr);
319
                *stack_ptr = (void *)obj_desc;
320
                break;
321
 
322
        default:
323
                break;
324
        }
325
 
326
        return_ACPI_STATUS(status);
327
}
328
 
329
/*******************************************************************************
330
 *
331
 * FUNCTION:    acpi_ex_resolve_multiple
332
 *
333
 * PARAMETERS:  walk_state          - Current state (contains AML opcode)
334
 *              Operand             - Starting point for resolution
335
 *              return_type         - Where the object type is returned
336
 *              return_desc         - Where the resolved object is returned
337
 *
338
 * RETURN:      Status
339
 *
340
 * DESCRIPTION: Return the base object and type.  Traverse a reference list if
341
 *              necessary to get to the base object.
342
 *
343
 ******************************************************************************/
344
 
345
acpi_status
346
acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
347
                         union acpi_operand_object *operand,
348
                         acpi_object_type * return_type,
349
                         union acpi_operand_object **return_desc)
350
{
351
        union acpi_operand_object *obj_desc = (void *)operand;
352
        struct acpi_namespace_node *node;
353
        acpi_object_type type;
354
        acpi_status status;
355
 
356
        ACPI_FUNCTION_TRACE(acpi_ex_resolve_multiple);
357
 
358
        /* Operand can be either a namespace node or an operand descriptor */
359
 
360
        switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
361
        case ACPI_DESC_TYPE_OPERAND:
362
                type = obj_desc->common.type;
363
                break;
364
 
365
        case ACPI_DESC_TYPE_NAMED:
366
                type = ((struct acpi_namespace_node *)obj_desc)->type;
367
                obj_desc =
368
                    acpi_ns_get_attached_object((struct acpi_namespace_node *)
369
                                                obj_desc);
370
 
371
                /* If we had an Alias node, use the attached object for type info */
372
 
373
                if (type == ACPI_TYPE_LOCAL_ALIAS) {
374
                        type = ((struct acpi_namespace_node *)obj_desc)->type;
375
                        obj_desc =
376
                            acpi_ns_get_attached_object((struct
377
                                                         acpi_namespace_node *)
378
                                                        obj_desc);
379
                }
380
                break;
381
 
382
        default:
383
                return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
384
        }
385
 
386
        /* If type is anything other than a reference, we are done */
387
 
388
        if (type != ACPI_TYPE_LOCAL_REFERENCE) {
389
                goto exit;
390
        }
391
 
392
        /*
393
         * For reference objects created via the ref_of or Index operators,
394
         * we need to get to the base object (as per the ACPI specification
395
         * of the object_type and size_of operators). This means traversing
396
         * the list of possibly many nested references.
397
         */
398
        while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
399
                switch (obj_desc->reference.opcode) {
400
                case AML_REF_OF_OP:
401
                case AML_INT_NAMEPATH_OP:
402
 
403
                        /* Dereference the reference pointer */
404
 
405
                        if (obj_desc->reference.opcode == AML_REF_OF_OP) {
406
                                node = obj_desc->reference.object;
407
                        } else {        /* AML_INT_NAMEPATH_OP */
408
 
409
                                node = obj_desc->reference.node;
410
                        }
411
 
412
                        /* All "References" point to a NS node */
413
 
414
                        if (ACPI_GET_DESCRIPTOR_TYPE(node) !=
415
                            ACPI_DESC_TYPE_NAMED) {
416
                                ACPI_ERROR((AE_INFO, "Not a NS node %p [%s]",
417
                                            node,
418
                                            acpi_ut_get_descriptor_name(node)));
419
                                return_ACPI_STATUS(AE_AML_INTERNAL);
420
                        }
421
 
422
                        /* Get the attached object */
423
 
424
                        obj_desc = acpi_ns_get_attached_object(node);
425
                        if (!obj_desc) {
426
 
427
                                /* No object, use the NS node type */
428
 
429
                                type = acpi_ns_get_type(node);
430
                                goto exit;
431
                        }
432
 
433
                        /* Check for circular references */
434
 
435
                        if (obj_desc == operand) {
436
                                return_ACPI_STATUS(AE_AML_CIRCULAR_REFERENCE);
437
                        }
438
                        break;
439
 
440
                case AML_INDEX_OP:
441
 
442
                        /* Get the type of this reference (index into another object) */
443
 
444
                        type = obj_desc->reference.target_type;
445
                        if (type != ACPI_TYPE_PACKAGE) {
446
                                goto exit;
447
                        }
448
 
449
                        /*
450
                         * The main object is a package, we want to get the type
451
                         * of the individual package element that is referenced by
452
                         * the index.
453
                         *
454
                         * This could of course in turn be another reference object.
455
                         */
456
                        obj_desc = *(obj_desc->reference.where);
457
                        if (!obj_desc) {
458
 
459
                                /* NULL package elements are allowed */
460
 
461
                                type = 0;        /* Uninitialized */
462
                                goto exit;
463
                        }
464
                        break;
465
 
466
                case AML_LOCAL_OP:
467
                case AML_ARG_OP:
468
 
469
                        if (return_desc) {
470
                                status =
471
                                    acpi_ds_method_data_get_value(obj_desc->
472
                                                                  reference.
473
                                                                  opcode,
474
                                                                  obj_desc->
475
                                                                  reference.
476
                                                                  offset,
477
                                                                  walk_state,
478
                                                                  &obj_desc);
479
                                if (ACPI_FAILURE(status)) {
480
                                        return_ACPI_STATUS(status);
481
                                }
482
                                acpi_ut_remove_reference(obj_desc);
483
                        } else {
484
                                status =
485
                                    acpi_ds_method_data_get_node(obj_desc->
486
                                                                 reference.
487
                                                                 opcode,
488
                                                                 obj_desc->
489
                                                                 reference.
490
                                                                 offset,
491
                                                                 walk_state,
492
                                                                 &node);
493
                                if (ACPI_FAILURE(status)) {
494
                                        return_ACPI_STATUS(status);
495
                                }
496
 
497
                                obj_desc = acpi_ns_get_attached_object(node);
498
                                if (!obj_desc) {
499
                                        type = ACPI_TYPE_ANY;
500
                                        goto exit;
501
                                }
502
                        }
503
                        break;
504
 
505
                case AML_DEBUG_OP:
506
 
507
                        /* The Debug Object is of type "DebugObject" */
508
 
509
                        type = ACPI_TYPE_DEBUG_OBJECT;
510
                        goto exit;
511
 
512
                default:
513
 
514
                        ACPI_ERROR((AE_INFO,
515
                                    "Unknown Reference subtype %X",
516
                                    obj_desc->reference.opcode));
517
                        return_ACPI_STATUS(AE_AML_INTERNAL);
518
                }
519
        }
520
 
521
        /*
522
         * Now we are guaranteed to have an object that has not been created
523
         * via the ref_of or Index operators.
524
         */
525
        type = ACPI_GET_OBJECT_TYPE(obj_desc);
526
 
527
      exit:
528
        /* Convert internal types to external types */
529
 
530
        switch (type) {
531
        case ACPI_TYPE_LOCAL_REGION_FIELD:
532
        case ACPI_TYPE_LOCAL_BANK_FIELD:
533
        case ACPI_TYPE_LOCAL_INDEX_FIELD:
534
 
535
                type = ACPI_TYPE_FIELD_UNIT;
536
                break;
537
 
538
        case ACPI_TYPE_LOCAL_SCOPE:
539
 
540
                /* Per ACPI Specification, Scope is untyped */
541
 
542
                type = ACPI_TYPE_ANY;
543
                break;
544
 
545
        default:
546
                /* No change to Type required */
547
                break;
548
        }
549
 
550
        *return_type = type;
551
        if (return_desc) {
552
                *return_desc = obj_desc;
553
        }
554
        return_ACPI_STATUS(AE_OK);
555
}

powered by: WebSVN 2.1.0

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