Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
acpi
acpica
exresolv.c
Go to the documentation of this file.
1
2
/******************************************************************************
3
*
4
* Module Name: exresolv - AML Interpreter object resolution
5
*
6
*****************************************************************************/
7
8
/*
9
* Copyright (C) 2000 - 2012, Intel Corp.
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 "
accommon.h
"
47
#include "
amlcode.h
"
48
#include "
acdispat.h
"
49
#include "
acinterp.h
"
50
#include "
acnamesp.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
union
acpi_operand_object
*obj_desc =
NULL
;
144
u8
ref_type;
145
146
ACPI_FUNCTION_TRACE
(ex_resolve_object_to_value);
147
148
stack_desc = *stack_ptr;
149
150
/* This is an object of type union acpi_operand_object */
151
152
switch
(stack_desc->
common
.type) {
153
case
ACPI_TYPE_LOCAL_REFERENCE
:
154
155
ref_type = stack_desc->
reference
.class;
156
157
switch
(ref_type) {
158
case
ACPI_REFCLASS_LOCAL
:
159
case
ACPI_REFCLASS_ARG
:
160
161
/*
162
* Get the local from the method's state info
163
* Note: this increments the local's object reference count
164
*/
165
status =
acpi_ds_method_data_get_value
(ref_type,
166
stack_desc->
167
reference
.value,
168
walk_state,
169
&obj_desc);
170
if
(
ACPI_FAILURE
(status)) {
171
return_ACPI_STATUS
(status);
172
}
173
174
ACPI_DEBUG_PRINT
((
ACPI_DB_EXEC
,
175
"[Arg/Local %X] ValueObj is %p\n"
,
176
stack_desc->
reference
.value,
177
obj_desc));
178
179
/*
180
* Now we can delete the original Reference Object and
181
* replace it with the resolved value
182
*/
183
acpi_ut_remove_reference
(stack_desc);
184
*stack_ptr = obj_desc;
185
break
;
186
187
case
ACPI_REFCLASS_INDEX
:
188
189
switch
(stack_desc->
reference
.target_type) {
190
case
ACPI_TYPE_BUFFER_FIELD
:
191
192
/* Just return - do not dereference */
193
break
;
194
195
case
ACPI_TYPE_PACKAGE
:
196
197
/* If method call or copy_object - do not dereference */
198
199
if
((walk_state->
opcode
==
200
AML_INT_METHODCALL_OP
)
201
|| (walk_state->
opcode
==
AML_COPY_OP
)) {
202
break
;
203
}
204
205
/* Otherwise, dereference the package_index to a package element */
206
207
obj_desc = *stack_desc->
reference
.where;
208
if
(obj_desc) {
209
/*
210
* Valid object descriptor, copy pointer to return value
211
* (i.e., dereference the package index)
212
* Delete the ref object, increment the returned object
213
*/
214
acpi_ut_remove_reference
(stack_desc);
215
acpi_ut_add_reference
(obj_desc);
216
*stack_ptr = obj_desc;
217
}
else
{
218
/*
219
* A NULL object descriptor means an uninitialized element of
220
* the package, can't dereference it
221
*/
222
ACPI_ERROR
((
AE_INFO
,
223
"Attempt to dereference an Index to NULL package element Idx=%p"
,
224
stack_desc));
225
status =
AE_AML_UNINITIALIZED_ELEMENT
;
226
}
227
break
;
228
229
default
:
230
231
/* Invalid reference object */
232
233
ACPI_ERROR
((
AE_INFO
,
234
"Unknown TargetType 0x%X in Index/Reference object %p"
,
235
stack_desc->
reference
.target_type,
236
stack_desc));
237
status =
AE_AML_INTERNAL
;
238
break
;
239
}
240
break
;
241
242
case
ACPI_REFCLASS_REFOF
:
243
case
ACPI_REFCLASS_DEBUG
:
244
case
ACPI_REFCLASS_TABLE
:
245
246
/* Just leave the object as-is, do not dereference */
247
248
break
;
249
250
case
ACPI_REFCLASS_NAME
:
/* Reference to a named object */
251
252
/* Dereference the name */
253
254
if
((stack_desc->
reference
.node->type ==
255
ACPI_TYPE_DEVICE
)
256
|| (stack_desc->
reference
.node->type ==
257
ACPI_TYPE_THERMAL
)) {
258
259
/* These node types do not have 'real' subobjects */
260
261
*stack_ptr = (
void
*)stack_desc->
reference
.node;
262
}
else
{
263
/* Get the object pointed to by the namespace node */
264
265
*stack_ptr =
266
(stack_desc->
reference
.node)->
object
;
267
acpi_ut_add_reference
(*stack_ptr);
268
}
269
270
acpi_ut_remove_reference
(stack_desc);
271
break
;
272
273
default
:
274
275
ACPI_ERROR
((
AE_INFO
,
276
"Unknown Reference type 0x%X in %p"
,
277
ref_type, stack_desc));
278
status =
AE_AML_INTERNAL
;
279
break
;
280
}
281
break
;
282
283
case
ACPI_TYPE_BUFFER
:
284
285
status =
acpi_ds_get_buffer_arguments
(stack_desc);
286
break
;
287
288
case
ACPI_TYPE_PACKAGE
:
289
290
status =
acpi_ds_get_package_arguments
(stack_desc);
291
break
;
292
293
case
ACPI_TYPE_BUFFER_FIELD
:
294
case
ACPI_TYPE_LOCAL_REGION_FIELD
:
295
case
ACPI_TYPE_LOCAL_BANK_FIELD
:
296
case
ACPI_TYPE_LOCAL_INDEX_FIELD
:
297
298
ACPI_DEBUG_PRINT
((
ACPI_DB_EXEC
,
299
"FieldRead SourceDesc=%p Type=%X\n"
,
300
stack_desc, stack_desc->
common
.type));
301
302
status =
303
acpi_ex_read_data_from_field
(walk_state, stack_desc,
304
&obj_desc);
305
306
/* Remove a reference to the original operand, then override */
307
308
acpi_ut_remove_reference
(*stack_ptr);
309
*stack_ptr = (
void
*)obj_desc;
310
break
;
311
312
default
:
313
break
;
314
}
315
316
return_ACPI_STATUS
(status);
317
}
318
319
/*******************************************************************************
320
*
321
* FUNCTION: acpi_ex_resolve_multiple
322
*
323
* PARAMETERS: walk_state - Current state (contains AML opcode)
324
* operand - Starting point for resolution
325
* return_type - Where the object type is returned
326
* return_desc - Where the resolved object is returned
327
*
328
* RETURN: Status
329
*
330
* DESCRIPTION: Return the base object and type. Traverse a reference list if
331
* necessary to get to the base object.
332
*
333
******************************************************************************/
334
335
acpi_status
336
acpi_ex_resolve_multiple
(
struct
acpi_walk_state
*walk_state,
337
union
acpi_operand_object
*
operand
,
338
acpi_object_type
* return_type,
339
union
acpi_operand_object
**return_desc)
340
{
341
union
acpi_operand_object
*obj_desc = (
void
*)operand;
342
struct
acpi_namespace_node
*
node
;
343
acpi_object_type
type
;
344
acpi_status
status
;
345
346
ACPI_FUNCTION_TRACE
(
acpi_ex_resolve_multiple
);
347
348
/* Operand can be either a namespace node or an operand descriptor */
349
350
switch
(
ACPI_GET_DESCRIPTOR_TYPE
(obj_desc)) {
351
case
ACPI_DESC_TYPE_OPERAND
:
352
type = obj_desc->
common
.type;
353
break
;
354
355
case
ACPI_DESC_TYPE_NAMED
:
356
type = ((
struct
acpi_namespace_node
*)obj_desc)->type;
357
obj_desc =
358
acpi_ns_get_attached_object
((
struct
acpi_namespace_node
*)
359
obj_desc);
360
361
/* If we had an Alias node, use the attached object for type info */
362
363
if
(type ==
ACPI_TYPE_LOCAL_ALIAS
) {
364
type = ((
struct
acpi_namespace_node
*)obj_desc)->type;
365
obj_desc =
366
acpi_ns_get_attached_object
((
struct
367
acpi_namespace_node
*)
368
obj_desc);
369
}
370
break
;
371
372
default
:
373
return_ACPI_STATUS
(
AE_AML_OPERAND_TYPE
);
374
}
375
376
/* If type is anything other than a reference, we are done */
377
378
if
(type !=
ACPI_TYPE_LOCAL_REFERENCE
) {
379
goto
exit
;
380
}
381
382
/*
383
* For reference objects created via the ref_of, Index, or Load/load_table
384
* operators, we need to get to the base object (as per the ACPI
385
* specification of the object_type and size_of operators). This means
386
* traversing the list of possibly many nested references.
387
*/
388
while
(obj_desc->
common
.type ==
ACPI_TYPE_LOCAL_REFERENCE
) {
389
switch
(obj_desc->
reference
.class) {
390
case
ACPI_REFCLASS_REFOF
:
391
case
ACPI_REFCLASS_NAME
:
392
393
/* Dereference the reference pointer */
394
395
if
(obj_desc->
reference
.class ==
ACPI_REFCLASS_REFOF
) {
396
node = obj_desc->
reference
.object;
397
}
else
{
/* AML_INT_NAMEPATH_OP */
398
399
node = obj_desc->
reference
.node;
400
}
401
402
/* All "References" point to a NS node */
403
404
if
(
ACPI_GET_DESCRIPTOR_TYPE
(node) !=
405
ACPI_DESC_TYPE_NAMED
) {
406
ACPI_ERROR
((
AE_INFO
,
407
"Not a namespace node %p [%s]"
,
408
node,
409
acpi_ut_get_descriptor_name
(node)));
410
return_ACPI_STATUS
(
AE_AML_INTERNAL
);
411
}
412
413
/* Get the attached object */
414
415
obj_desc =
acpi_ns_get_attached_object
(node);
416
if
(!obj_desc) {
417
418
/* No object, use the NS node type */
419
420
type =
acpi_ns_get_type
(node);
421
goto
exit
;
422
}
423
424
/* Check for circular references */
425
426
if
(obj_desc == operand) {
427
return_ACPI_STATUS
(
AE_AML_CIRCULAR_REFERENCE
);
428
}
429
break
;
430
431
case
ACPI_REFCLASS_INDEX
:
432
433
/* Get the type of this reference (index into another object) */
434
435
type = obj_desc->
reference
.target_type;
436
if
(type !=
ACPI_TYPE_PACKAGE
) {
437
goto
exit
;
438
}
439
440
/*
441
* The main object is a package, we want to get the type
442
* of the individual package element that is referenced by
443
* the index.
444
*
445
* This could of course in turn be another reference object.
446
*/
447
obj_desc = *(obj_desc->
reference
.where);
448
if
(!obj_desc) {
449
450
/* NULL package elements are allowed */
451
452
type = 0;
/* Uninitialized */
453
goto
exit
;
454
}
455
break
;
456
457
case
ACPI_REFCLASS_TABLE
:
458
459
type =
ACPI_TYPE_DDB_HANDLE
;
460
goto
exit
;
461
462
case
ACPI_REFCLASS_LOCAL
:
463
case
ACPI_REFCLASS_ARG
:
464
465
if
(return_desc) {
466
status =
467
acpi_ds_method_data_get_value
(obj_desc->
468
reference
.
469
class
,
470
obj_desc->
471
reference
.
472
value
,
473
walk_state,
474
&obj_desc);
475
if
(
ACPI_FAILURE
(status)) {
476
return_ACPI_STATUS
(status);
477
}
478
acpi_ut_remove_reference
(obj_desc);
479
}
else
{
480
status =
481
acpi_ds_method_data_get_node
(obj_desc->
482
reference
.
483
class
,
484
obj_desc->
485
reference
.
486
value
,
487
walk_state,
488
&node);
489
if
(
ACPI_FAILURE
(status)) {
490
return_ACPI_STATUS
(status);
491
}
492
493
obj_desc =
acpi_ns_get_attached_object
(node);
494
if
(!obj_desc) {
495
type =
ACPI_TYPE_ANY
;
496
goto
exit
;
497
}
498
}
499
break
;
500
501
case
ACPI_REFCLASS_DEBUG
:
502
503
/* The Debug Object is of type "DebugObject" */
504
505
type =
ACPI_TYPE_DEBUG_OBJECT
;
506
goto
exit
;
507
508
default
:
509
510
ACPI_ERROR
((
AE_INFO
,
511
"Unknown Reference Class 0x%2.2X"
,
512
obj_desc->
reference
.class));
513
return_ACPI_STATUS
(
AE_AML_INTERNAL
);
514
}
515
}
516
517
/*
518
* Now we are guaranteed to have an object that has not been created
519
* via the ref_of or Index operators.
520
*/
521
type = obj_desc->
common
.type;
522
523
exit
:
524
/* Convert internal types to external types */
525
526
switch
(type) {
527
case
ACPI_TYPE_LOCAL_REGION_FIELD
:
528
case
ACPI_TYPE_LOCAL_BANK_FIELD
:
529
case
ACPI_TYPE_LOCAL_INDEX_FIELD
:
530
531
type =
ACPI_TYPE_FIELD_UNIT
;
532
break
;
533
534
case
ACPI_TYPE_LOCAL_SCOPE
:
535
536
/* Per ACPI Specification, Scope is untyped */
537
538
type =
ACPI_TYPE_ANY
;
539
break
;
540
541
default
:
542
/* No change to Type required */
543
break
;
544
}
545
546
*return_type =
type
;
547
if
(return_desc) {
548
*return_desc = obj_desc;
549
}
550
return_ACPI_STATUS
(
AE_OK
);
551
}
Generated on Thu Jan 10 2013 13:23:31 for Linux Kernel by
1.8.2