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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [acpi/] [executer/] [exresolv.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
 
2
/******************************************************************************
3
 *
4
 * Module Name: exresolv - AML Interpreter object resolution
5
 *
6
 *****************************************************************************/
7
 
8
/*
9
 * Copyright (C) 2000 - 2004, 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
 
46
#include <acpi/acpi.h>
47
#include <acpi/amlcode.h>
48
#include <acpi/acdispat.h>
49
#include <acpi/acinterp.h>
50
#include <acpi/acnamesp.h>
51
#include <acpi/acparser.h>
52
 
53
 
54
#define _COMPONENT          ACPI_EXECUTER
55
         ACPI_MODULE_NAME    ("exresolv")
56
 
57
 
58
/*******************************************************************************
59
 *
60
 * FUNCTION:    acpi_ex_resolve_to_value
61
 *
62
 * PARAMETERS:  **stack_ptr         - Points to entry on obj_stack, which can
63
 *                                    be either an (union acpi_operand_object *)
64
 *                                    or an acpi_handle.
65
 *              walk_state          - Current method state
66
 *
67
 * RETURN:      Status
68
 *
69
 * DESCRIPTION: Convert Reference objects to values
70
 *
71
 ******************************************************************************/
72
 
73
acpi_status
74
acpi_ex_resolve_to_value (
75
        union acpi_operand_object       **stack_ptr,
76
        struct acpi_walk_state          *walk_state)
77
{
78
        acpi_status                     status;
79
 
80
 
81
        ACPI_FUNCTION_TRACE_PTR ("ex_resolve_to_value", stack_ptr);
82
 
83
 
84
        if (!stack_ptr || !*stack_ptr) {
85
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null pointer\n"));
86
                return_ACPI_STATUS (AE_AML_NO_OPERAND);
87
        }
88
 
89
        /*
90
         * The entity pointed to by the stack_ptr can be either
91
         * 1) A valid union acpi_operand_object, or
92
         * 2) A struct acpi_namespace_node (named_obj)
93
         */
94
        if (ACPI_GET_DESCRIPTOR_TYPE (*stack_ptr) == ACPI_DESC_TYPE_OPERAND) {
95
                status = acpi_ex_resolve_object_to_value (stack_ptr, walk_state);
96
                if (ACPI_FAILURE (status)) {
97
                        return_ACPI_STATUS (status);
98
                }
99
        }
100
 
101
        /*
102
         * Object on the stack may have changed if acpi_ex_resolve_object_to_value()
103
         * was called (i.e., we can't use an _else_ here.)
104
         */
105
        if (ACPI_GET_DESCRIPTOR_TYPE (*stack_ptr) == ACPI_DESC_TYPE_NAMED) {
106
                status = acpi_ex_resolve_node_to_value (
107
                                  ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, stack_ptr),
108
                                  walk_state);
109
                if (ACPI_FAILURE (status)) {
110
                        return_ACPI_STATUS (status);
111
                }
112
        }
113
 
114
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Resolved object %p\n", *stack_ptr));
115
        return_ACPI_STATUS (AE_OK);
116
}
117
 
118
 
119
/*******************************************************************************
120
 *
121
 * FUNCTION:    acpi_ex_resolve_object_to_value
122
 *
123
 * PARAMETERS:  stack_ptr       - Pointer to a stack location that contains a
124
 *                                ptr to an internal object.
125
 *              walk_state      - Current method state
126
 *
127
 * RETURN:      Status
128
 *
129
 * DESCRIPTION: Retrieve the value from an internal object.  The Reference type
130
 *              uses the associated AML opcode to determine the value.
131
 *
132
 ******************************************************************************/
133
 
134
acpi_status
135
acpi_ex_resolve_object_to_value (
136
        union acpi_operand_object       **stack_ptr,
137
        struct acpi_walk_state          *walk_state)
138
{
139
        acpi_status                     status = AE_OK;
140
        union acpi_operand_object       *stack_desc;
141
        void                            *temp_node;
142
        union acpi_operand_object       *obj_desc;
143
        u16                             opcode;
144
 
145
 
146
        ACPI_FUNCTION_TRACE ("ex_resolve_object_to_value");
147
 
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 indirect name ptr to a direct name ptr.
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
                        /* Put direct name pointer onto stack and exit */
172
 
173
                        (*stack_ptr) = temp_node;
174
                        break;
175
 
176
 
177
                case AML_LOCAL_OP:
178
                case AML_ARG_OP:
179
 
180
                        /*
181
                         * Get the local from the method's state info
182
                         * Note: this increments the local's object reference count
183
                         */
184
                        status = acpi_ds_method_data_get_value (opcode,
185
                                          stack_desc->reference.offset, walk_state, &obj_desc);
186
                        if (ACPI_FAILURE (status)) {
187
                                return_ACPI_STATUS (status);
188
                        }
189
 
190
                        /*
191
                         * Now we can delete the original Reference Object and
192
                         * replace it with the resolve value
193
                         */
194
                        acpi_ut_remove_reference (stack_desc);
195
                        *stack_ptr = obj_desc;
196
 
197
                        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %d] value_obj is %p\n",
198
                                stack_desc->reference.offset, obj_desc));
199
                        break;
200
 
201
 
202
                case AML_INDEX_OP:
203
 
204
                        switch (stack_desc->reference.target_type) {
205
                        case ACPI_TYPE_BUFFER_FIELD:
206
 
207
                                /* Just return - leave the Reference on the stack */
208
                                break;
209
 
210
 
211
                        case ACPI_TYPE_PACKAGE:
212
 
213
                                obj_desc = *stack_desc->reference.where;
214
                                if (obj_desc) {
215
                                        /*
216
                                         * Valid obj descriptor, copy pointer to return value
217
                                         * (i.e., dereference the package index)
218
                                         * Delete the ref object, increment the returned object
219
                                         */
220
                                        acpi_ut_remove_reference (stack_desc);
221
                                        acpi_ut_add_reference (obj_desc);
222
                                        *stack_ptr = obj_desc;
223
                                }
224
                                else {
225
                                        /*
226
                                         * A NULL object descriptor means an unitialized element of
227
                                         * the package, can't dereference it
228
                                         */
229
                                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
230
                                                "Attempt to deref an Index to NULL pkg element Idx=%p\n",
231
                                                stack_desc));
232
                                        status = AE_AML_UNINITIALIZED_ELEMENT;
233
                                }
234
                                break;
235
 
236
 
237
                        default:
238
 
239
                                /* Invalid reference object */
240
 
241
                                ACPI_REPORT_ERROR ((
242
                                        "During resolve, Unknown target_type %X in Index/Reference obj %p\n",
243
                                        stack_desc->reference.target_type, stack_desc));
244
                                status = AE_AML_INTERNAL;
245
                                break;
246
                        }
247
                        break;
248
 
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
 
259
                default:
260
 
261
                        ACPI_REPORT_ERROR (("During resolve, Unknown Reference opcode %X (%s) in %p\n",
262
                                opcode, acpi_ps_get_opcode_name (opcode), stack_desc));
263
                        status = AE_AML_INTERNAL;
264
                        break;
265
                }
266
                break;
267
 
268
 
269
        case ACPI_TYPE_BUFFER:
270
 
271
                status = acpi_ds_get_buffer_arguments (stack_desc);
272
                break;
273
 
274
 
275
        case ACPI_TYPE_PACKAGE:
276
 
277
                status = acpi_ds_get_package_arguments (stack_desc);
278
                break;
279
 
280
 
281
        /*
282
         * These cases may never happen here, but just in case..
283
         */
284
        case ACPI_TYPE_BUFFER_FIELD:
285
        case ACPI_TYPE_LOCAL_REGION_FIELD:
286
        case ACPI_TYPE_LOCAL_BANK_FIELD:
287
        case ACPI_TYPE_LOCAL_INDEX_FIELD:
288
 
289
                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "field_read source_desc=%p Type=%X\n",
290
                        stack_desc, ACPI_GET_OBJECT_TYPE (stack_desc)));
291
 
292
                status = acpi_ex_read_data_from_field (walk_state, stack_desc, &obj_desc);
293
                *stack_ptr = (void *) obj_desc;
294
                break;
295
 
296
        default:
297
                break;
298
        }
299
 
300
        return_ACPI_STATUS (status);
301
}
302
 
303
 
304
/*******************************************************************************
305
 *
306
 * FUNCTION:    acpi_ex_resolve_multiple
307
 *
308
 * PARAMETERS:  walk_state          - Current state (contains AML opcode)
309
 *              Operand             - Starting point for resolution
310
 *              return_type         - Where the object type is returned
311
 *              return_desc         - Where the resolved object is returned
312
 *
313
 * RETURN:      Status
314
 *
315
 * DESCRIPTION: Return the base object and type.  Traverse a reference list if
316
 *              necessary to get to the base object.
317
 *
318
 ******************************************************************************/
319
 
320
acpi_status
321
acpi_ex_resolve_multiple (
322
        struct acpi_walk_state          *walk_state,
323
        union acpi_operand_object       *operand,
324
        acpi_object_type                *return_type,
325
        union acpi_operand_object       **return_desc)
326
{
327
        union acpi_operand_object       *obj_desc = (void *) operand;
328
        struct acpi_namespace_node      *node;
329
        acpi_object_type                type;
330
 
331
 
332
        ACPI_FUNCTION_TRACE ("acpi_ex_resolve_multiple");
333
 
334
 
335
        /*
336
         * For reference objects created via the ref_of or Index operators,
337
         * we need to get to the base object (as per the ACPI specification
338
         * of the object_type and size_of operators). This means traversing
339
         * the list of possibly many nested references.
340
         */
341
        while (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
342
                switch (obj_desc->reference.opcode) {
343
                case AML_REF_OF_OP:
344
 
345
                        /* Dereference the reference pointer */
346
 
347
                        node = obj_desc->reference.object;
348
 
349
                        /* All "References" point to a NS node */
350
 
351
                        if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
352
                                ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
353
                                                node, acpi_ut_get_descriptor_name (node)));
354
                                return_ACPI_STATUS (AE_AML_INTERNAL);
355
                        }
356
 
357
                        /* Get the attached object */
358
 
359
                        obj_desc = acpi_ns_get_attached_object (node);
360
                        if (!obj_desc) {
361
                                /* No object, use the NS node type */
362
 
363
                                type = acpi_ns_get_type (node);
364
                                goto exit;
365
                        }
366
 
367
                        /* Check for circular references */
368
 
369
                        if (obj_desc == operand) {
370
                                return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE);
371
                        }
372
                        break;
373
 
374
 
375
                case AML_INDEX_OP:
376
 
377
                        /* Get the type of this reference (index into another object) */
378
 
379
                        type = obj_desc->reference.target_type;
380
                        if (type != ACPI_TYPE_PACKAGE) {
381
                                goto exit;
382
                        }
383
 
384
                        /*
385
                         * The main object is a package, we want to get the type
386
                         * of the individual package element that is referenced by
387
                         * the index.
388
                         *
389
                         * This could of course in turn be another reference object.
390
                         */
391
                        obj_desc = *(obj_desc->reference.where);
392
                        break;
393
 
394
 
395
                case AML_INT_NAMEPATH_OP:
396
 
397
                        /* Dereference the reference pointer */
398
 
399
                        node = obj_desc->reference.node;
400
 
401
                        /* All "References" point to a NS node */
402
 
403
                        if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
404
                                ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
405
                                                node, acpi_ut_get_descriptor_name (node)));
406
                           return_ACPI_STATUS (AE_AML_INTERNAL);
407
                        }
408
 
409
                        /* Get the attached object */
410
 
411
                        obj_desc = acpi_ns_get_attached_object (node);
412
                        if (!obj_desc) {
413
                                /* No object, use the NS node type */
414
 
415
                                type = acpi_ns_get_type (node);
416
                                goto exit;
417
                        }
418
 
419
                        /* Check for circular references */
420
 
421
                        if (obj_desc == operand) {
422
                                return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE);
423
                        }
424
                        break;
425
 
426
 
427
                case AML_DEBUG_OP:
428
 
429
                        /* The Debug Object is of type "debug_object" */
430
 
431
                        type = ACPI_TYPE_DEBUG_OBJECT;
432
                        goto exit;
433
 
434
 
435
                default:
436
 
437
                        ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Unknown Reference subtype %X\n",
438
                                obj_desc->reference.opcode));
439
                        return_ACPI_STATUS (AE_AML_INTERNAL);
440
                }
441
        }
442
 
443
        /*
444
         * Now we are guaranteed to have an object that has not been created
445
         * via the ref_of or Index operators.
446
         */
447
        type = ACPI_GET_OBJECT_TYPE (obj_desc);
448
 
449
 
450
exit:
451
        /* Convert internal types to external types */
452
 
453
        switch (type) {
454
        case ACPI_TYPE_LOCAL_REGION_FIELD:
455
        case ACPI_TYPE_LOCAL_BANK_FIELD:
456
        case ACPI_TYPE_LOCAL_INDEX_FIELD:
457
 
458
                type = ACPI_TYPE_FIELD_UNIT;
459
                break;
460
 
461
        case ACPI_TYPE_LOCAL_SCOPE:
462
 
463
                /* Per ACPI Specification, Scope is untyped */
464
 
465
                type = ACPI_TYPE_ANY;
466
                break;
467
 
468
        default:
469
                /* No change to Type required */
470
                break;
471
        }
472
 
473
        *return_type = type;
474
        if (return_desc) {
475
                *return_desc = obj_desc;
476
        }
477
        return_ACPI_STATUS (AE_OK);
478
}
479
 
480
 

powered by: WebSVN 2.1.0

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