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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [acpi/] [executer/] [exoparg1.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: exoparg1 - AML execution - opcodes with 1 argument
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/acparser.h>
48
#include <acpi/acdispat.h>
49
#include <acpi/acinterp.h>
50
#include <acpi/amlcode.h>
51
#include <acpi/acnamesp.h>
52
 
53
 
54
#define _COMPONENT          ACPI_EXECUTER
55
         ACPI_MODULE_NAME    ("exoparg1")
56
 
57
 
58
/*!
59
 * Naming convention for AML interpreter execution routines.
60
 *
61
 * The routines that begin execution of AML opcodes are named with a common
62
 * convention based upon the number of arguments, the number of target operands,
63
 * and whether or not a value is returned:
64
 *
65
 *      AcpiExOpcode_xA_yT_zR
66
 *
67
 * Where:
68
 *
69
 * xA - ARGUMENTS:    The number of arguments (input operands) that are
70
 *                    required for this opcode type (1 through 6 args).
71
 * yT - TARGETS:      The number of targets (output operands) that are required
72
 *                    for this opcode type (0, 1, or 2 targets).
73
 * zR - RETURN VALUE: Indicates whether this opcode type returns a value
74
 *                    as the function return (0 or 1).
75
 *
76
 * The AcpiExOpcode* functions are called via the Dispatcher component with
77
 * fully resolved operands.
78
!*/
79
 
80
/*******************************************************************************
81
 *
82
 * FUNCTION:    acpi_ex_opcode_1A_0T_0R
83
 *
84
 * PARAMETERS:  walk_state          - Current state (contains AML opcode)
85
 *
86
 * RETURN:      Status
87
 *
88
 * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
89
 *              object stack
90
 *
91
 ******************************************************************************/
92
 
93
acpi_status
94
acpi_ex_opcode_1A_0T_0R (
95
        struct acpi_walk_state          *walk_state)
96
{
97
        union acpi_operand_object       **operand = &walk_state->operands[0];
98
        acpi_status                     status = AE_OK;
99
 
100
 
101
        ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
102
 
103
 
104
        /* Examine the AML opcode */
105
 
106
        switch (walk_state->opcode) {
107
        case AML_RELEASE_OP:    /*  Release (mutex_object) */
108
 
109
                status = acpi_ex_release_mutex (operand[0], walk_state);
110
                break;
111
 
112
 
113
        case AML_RESET_OP:      /*  Reset (event_object) */
114
 
115
                status = acpi_ex_system_reset_event (operand[0]);
116
                break;
117
 
118
 
119
        case AML_SIGNAL_OP:     /*  Signal (event_object) */
120
 
121
                status = acpi_ex_system_signal_event (operand[0]);
122
                break;
123
 
124
 
125
        case AML_SLEEP_OP:      /*  Sleep (msec_time) */
126
 
127
                status = acpi_ex_system_do_suspend ((u32) operand[0]->integer.value);
128
                break;
129
 
130
 
131
        case AML_STALL_OP:      /*  Stall (usec_time) */
132
 
133
                status = acpi_ex_system_do_stall ((u32) operand[0]->integer.value);
134
                break;
135
 
136
 
137
        case AML_UNLOAD_OP:     /*  Unload (Handle) */
138
 
139
                status = acpi_ex_unload_table (operand[0]);
140
                break;
141
 
142
 
143
        default:                /*  Unknown opcode  */
144
 
145
                ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_0T_0R: Unknown opcode %X\n",
146
                        walk_state->opcode));
147
                status = AE_AML_BAD_OPCODE;
148
                break;
149
        }
150
 
151
        return_ACPI_STATUS (status);
152
}
153
 
154
 
155
/*******************************************************************************
156
 *
157
 * FUNCTION:    acpi_ex_opcode_1A_1T_0R
158
 *
159
 * PARAMETERS:  walk_state          - Current state (contains AML opcode)
160
 *
161
 * RETURN:      Status
162
 *
163
 * DESCRIPTION: Execute opcode with one argument, one target, and no
164
 *              return value.
165
 *
166
 ******************************************************************************/
167
 
168
acpi_status
169
acpi_ex_opcode_1A_1T_0R (
170
        struct acpi_walk_state          *walk_state)
171
{
172
        acpi_status                     status = AE_OK;
173
        union acpi_operand_object       **operand = &walk_state->operands[0];
174
 
175
 
176
        ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
177
 
178
 
179
        /* Examine the AML opcode */
180
 
181
        switch (walk_state->opcode) {
182
        case AML_LOAD_OP:
183
 
184
                status = acpi_ex_load_op (operand[0], operand[1], walk_state);
185
                break;
186
 
187
        default:                        /* Unknown opcode */
188
 
189
                ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_1T_0R: Unknown opcode %X\n",
190
                        walk_state->opcode));
191
                status = AE_AML_BAD_OPCODE;
192
                goto cleanup;
193
        }
194
 
195
 
196
cleanup:
197
 
198
        return_ACPI_STATUS (status);
199
}
200
 
201
 
202
/*******************************************************************************
203
 *
204
 * FUNCTION:    acpi_ex_opcode_1A_1T_1R
205
 *
206
 * PARAMETERS:  walk_state          - Current state (contains AML opcode)
207
 *
208
 * RETURN:      Status
209
 *
210
 * DESCRIPTION: Execute opcode with one argument, one target, and a
211
 *              return value.
212
 *
213
 ******************************************************************************/
214
 
215
acpi_status
216
acpi_ex_opcode_1A_1T_1R (
217
        struct acpi_walk_state          *walk_state)
218
{
219
        acpi_status                     status = AE_OK;
220
        union acpi_operand_object       **operand = &walk_state->operands[0];
221
        union acpi_operand_object       *return_desc = NULL;
222
        union acpi_operand_object       *return_desc2 = NULL;
223
        u32                             temp32;
224
        u32                             i;
225
        u32                             power_of_ten;
226
        acpi_integer                    digit;
227
 
228
 
229
        ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
230
 
231
 
232
        /* Examine the AML opcode */
233
 
234
        switch (walk_state->opcode) {
235
        case AML_BIT_NOT_OP:
236
        case AML_FIND_SET_LEFT_BIT_OP:
237
        case AML_FIND_SET_RIGHT_BIT_OP:
238
        case AML_FROM_BCD_OP:
239
        case AML_TO_BCD_OP:
240
        case AML_COND_REF_OF_OP:
241
 
242
                /* Create a return object of type Integer for these opcodes */
243
 
244
                return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
245
                if (!return_desc) {
246
                        status = AE_NO_MEMORY;
247
                        goto cleanup;
248
                }
249
 
250
                switch (walk_state->opcode) {
251
                case AML_BIT_NOT_OP:            /* Not (Operand, Result)  */
252
 
253
                        return_desc->integer.value = ~operand[0]->integer.value;
254
                        break;
255
 
256
 
257
                case AML_FIND_SET_LEFT_BIT_OP:  /* find_set_left_bit (Operand, Result) */
258
 
259
                        return_desc->integer.value = operand[0]->integer.value;
260
 
261
                        /*
262
                         * Acpi specification describes Integer type as a little
263
                         * endian unsigned value, so this boundary condition is valid.
264
                         */
265
                        for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
266
                                return_desc->integer.value >>= 1;
267
                        }
268
 
269
                        return_desc->integer.value = temp32;
270
                        break;
271
 
272
 
273
                case AML_FIND_SET_RIGHT_BIT_OP: /* find_set_right_bit (Operand, Result) */
274
 
275
                        return_desc->integer.value = operand[0]->integer.value;
276
 
277
                        /*
278
                         * The Acpi specification describes Integer type as a little
279
                         * endian unsigned value, so this boundary condition is valid.
280
                         */
281
                        for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
282
                                return_desc->integer.value <<= 1;
283
                        }
284
 
285
                        /* Since the bit position is one-based, subtract from 33 (65) */
286
 
287
                        return_desc->integer.value = temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - temp32;
288
                        break;
289
 
290
 
291
                case AML_FROM_BCD_OP:           /* from_bcd (BCDValue, Result) */
292
 
293
                        /*
294
                         * The 64-bit ACPI integer can hold 16 4-bit BCD characters
295
                         * (if table is 32-bit, integer can hold 8 BCD characters)
296
                         * Convert each 4-bit BCD value
297
                         */
298
                        power_of_ten = 1;
299
                        return_desc->integer.value = 0;
300
                        digit = operand[0]->integer.value;
301
 
302
                        /* Convert each BCD digit (each is one nybble wide) */
303
 
304
                        for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) {
305
                                /* Get the least significant 4-bit BCD digit */
306
 
307
                                temp32 = ((u32) digit) & 0xF;
308
 
309
                                /* Check the range of the digit */
310
 
311
                                if (temp32 > 9) {
312
                                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
313
                                                "BCD digit too large (not decimal): 0x%X\n",
314
                                                temp32));
315
 
316
                                        status = AE_AML_NUMERIC_OVERFLOW;
317
                                        goto cleanup;
318
                                }
319
 
320
                                /* Sum the digit into the result with the current power of 10 */
321
 
322
                                return_desc->integer.value += (((acpi_integer) temp32) * power_of_ten);
323
 
324
                                /* Shift to next BCD digit */
325
 
326
                                digit >>= 4;
327
 
328
                                /* Next power of 10 */
329
 
330
                                power_of_ten *= 10;
331
                        }
332
                        break;
333
 
334
 
335
                case AML_TO_BCD_OP:             /* to_bcd (Operand, Result) */
336
 
337
                        return_desc->integer.value = 0;
338
                        digit = operand[0]->integer.value;
339
 
340
                        /* Each BCD digit is one nybble wide */
341
 
342
                        for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) {
343
                                (void) acpi_ut_short_divide (&digit, 10, &digit, &temp32);
344
 
345
                                /* Insert the BCD digit that resides in the remainder from above */
346
 
347
                                return_desc->integer.value |= (((acpi_integer) temp32) << (i * 4));
348
                        }
349
 
350
                        /* Overflow if there is any data left in Digit */
351
 
352
                        if (digit > 0) {
353
                                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Integer too large to convert to BCD: %8.8X%8.8X\n",
354
                                                ACPI_FORMAT_UINT64 (operand[0]->integer.value)));
355
                                status = AE_AML_NUMERIC_OVERFLOW;
356
                                goto cleanup;
357
                        }
358
                        break;
359
 
360
 
361
                case AML_COND_REF_OF_OP:        /* cond_ref_of (source_object, Result) */
362
 
363
                        /*
364
                         * This op is a little strange because the internal return value is
365
                         * different than the return value stored in the result descriptor
366
                         * (There are really two return values)
367
                         */
368
                        if ((struct acpi_namespace_node *) operand[0] == acpi_gbl_root_node) {
369
                                /*
370
                                 * This means that the object does not exist in the namespace,
371
                                 * return FALSE
372
                                 */
373
                                return_desc->integer.value = 0;
374
                                goto cleanup;
375
                        }
376
 
377
                        /* Get the object reference, store it, and remove our reference */
378
 
379
                        status = acpi_ex_get_object_reference (operand[0], &return_desc2, walk_state);
380
                        if (ACPI_FAILURE (status)) {
381
                                goto cleanup;
382
                        }
383
 
384
                        status = acpi_ex_store (return_desc2, operand[1], walk_state);
385
                        acpi_ut_remove_reference (return_desc2);
386
 
387
                        /* The object exists in the namespace, return TRUE */
388
 
389
                        return_desc->integer.value = ACPI_INTEGER_MAX;
390
                        goto cleanup;
391
 
392
 
393
                default:
394
                        /* No other opcodes get here */
395
                        break;
396
                }
397
                break;
398
 
399
 
400
        case AML_STORE_OP:              /* Store (Source, Target) */
401
 
402
                /*
403
                 * A store operand is typically a number, string, buffer or lvalue
404
                 * Be careful about deleting the source object,
405
                 * since the object itself may have been stored.
406
                 */
407
                status = acpi_ex_store (operand[0], operand[1], walk_state);
408
                if (ACPI_FAILURE (status)) {
409
                        return_ACPI_STATUS (status);
410
                }
411
 
412
                /* It is possible that the Store already produced a return object */
413
 
414
                if (!walk_state->result_obj) {
415
                        /*
416
                         * Normally, we would remove a reference on the Operand[0] parameter;
417
                         * But since it is being used as the internal return object
418
                         * (meaning we would normally increment it), the two cancel out,
419
                         * and we simply don't do anything.
420
                         */
421
                        walk_state->result_obj = operand[0];
422
                        walk_state->operands[0] = NULL; /* Prevent deletion */
423
                }
424
                return_ACPI_STATUS (status);
425
 
426
 
427
        /*
428
         * ACPI 2.0 Opcodes
429
         */
430
        case AML_COPY_OP:               /* Copy (Source, Target) */
431
 
432
                status = acpi_ut_copy_iobject_to_iobject (operand[0], &return_desc, walk_state);
433
                break;
434
 
435
 
436
        case AML_TO_DECSTRING_OP:       /* to_decimal_string (Data, Result) */
437
 
438
                status = acpi_ex_convert_to_string (operand[0], &return_desc, 10, ACPI_UINT32_MAX, walk_state);
439
                break;
440
 
441
 
442
        case AML_TO_HEXSTRING_OP:       /* to_hex_string (Data, Result) */
443
 
444
                status = acpi_ex_convert_to_string (operand[0], &return_desc, 16, ACPI_UINT32_MAX, walk_state);
445
                break;
446
 
447
 
448
        case AML_TO_BUFFER_OP:          /* to_buffer (Data, Result) */
449
 
450
                status = acpi_ex_convert_to_buffer (operand[0], &return_desc, walk_state);
451
                break;
452
 
453
 
454
        case AML_TO_INTEGER_OP:         /* to_integer (Data, Result) */
455
 
456
                status = acpi_ex_convert_to_integer (operand[0], &return_desc, walk_state);
457
                break;
458
 
459
 
460
        case AML_SHIFT_LEFT_BIT_OP:     /*  shift_left_bit (Source, bit_num) */
461
        case AML_SHIFT_RIGHT_BIT_OP:    /*  shift_right_bit (Source, bit_num) */
462
 
463
                /*
464
                 * These are two obsolete opcodes
465
                 */
466
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s is obsolete and not implemented\n",
467
                                  acpi_ps_get_opcode_name (walk_state->opcode)));
468
                status = AE_SUPPORT;
469
                goto cleanup;
470
 
471
 
472
        default:                        /* Unknown opcode */
473
 
474
                ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_1T_1R: Unknown opcode %X\n",
475
                        walk_state->opcode));
476
                status = AE_AML_BAD_OPCODE;
477
                goto cleanup;
478
        }
479
 
480
        /*
481
         * Store the return value computed above into the target object
482
         */
483
        status = acpi_ex_store (return_desc, operand[1], walk_state);
484
 
485
 
486
cleanup:
487
 
488
        if (!walk_state->result_obj) {
489
                walk_state->result_obj = return_desc;
490
        }
491
 
492
        /* Delete return object on error */
493
 
494
        if (ACPI_FAILURE (status)) {
495
                acpi_ut_remove_reference (return_desc);
496
        }
497
 
498
        return_ACPI_STATUS (status);
499
}
500
 
501
 
502
/*******************************************************************************
503
 *
504
 * FUNCTION:    acpi_ex_opcode_1A_0T_1R
505
 *
506
 * PARAMETERS:  walk_state          - Current state (contains AML opcode)
507
 *
508
 * RETURN:      Status
509
 *
510
 * DESCRIPTION: Execute opcode with one argument, no target, and a return value
511
 *
512
 ******************************************************************************/
513
 
514
acpi_status
515
acpi_ex_opcode_1A_0T_1R (
516
        struct acpi_walk_state          *walk_state)
517
{
518
        union acpi_operand_object       **operand = &walk_state->operands[0];
519
        union acpi_operand_object       *temp_desc;
520
        union acpi_operand_object       *return_desc = NULL;
521
        acpi_status                     status = AE_OK;
522
        u32                             type;
523
        acpi_integer                    value;
524
 
525
 
526
        ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
527
 
528
 
529
        /* Examine the AML opcode */
530
 
531
        switch (walk_state->opcode) {
532
        case AML_LNOT_OP:               /* LNot (Operand) */
533
 
534
                return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
535
                if (!return_desc) {
536
                        status = AE_NO_MEMORY;
537
                        goto cleanup;
538
                }
539
 
540
                return_desc->integer.value = !operand[0]->integer.value;
541
                break;
542
 
543
 
544
        case AML_DECREMENT_OP:          /* Decrement (Operand)  */
545
        case AML_INCREMENT_OP:          /* Increment (Operand)  */
546
 
547
                /*
548
                 * Since we are expecting a Reference operand, it
549
                 * can be either a NS Node or an internal object.
550
                 */
551
                return_desc = operand[0];
552
                if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) == ACPI_DESC_TYPE_OPERAND) {
553
                        /* Internal reference object - prevent deletion */
554
 
555
                        acpi_ut_add_reference (return_desc);
556
                }
557
 
558
                /*
559
                 * Convert the return_desc Reference to a Number
560
                 * (This removes a reference on the return_desc object)
561
                 */
562
                status = acpi_ex_resolve_operands (AML_LNOT_OP, &return_desc, walk_state);
563
                if (ACPI_FAILURE (status)) {
564
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %s\n",
565
                                acpi_ps_get_opcode_name (walk_state->opcode), acpi_format_exception(status)));
566
 
567
                        goto cleanup;
568
                }
569
 
570
                /*
571
                 * return_desc is now guaranteed to be an Integer object
572
                 * Do the actual increment or decrement
573
                 */
574
                if (AML_INCREMENT_OP == walk_state->opcode) {
575
                        return_desc->integer.value++;
576
                }
577
                else {
578
                        return_desc->integer.value--;
579
                }
580
 
581
                /* Store the result back in the original descriptor */
582
 
583
                status = acpi_ex_store (return_desc, operand[0], walk_state);
584
                break;
585
 
586
 
587
        case AML_TYPE_OP:               /* object_type (source_object) */
588
 
589
                /* Get the type of the base object */
590
 
591
                status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, NULL);
592
                if (ACPI_FAILURE (status)) {
593
                        goto cleanup;
594
                }
595
 
596
                /* Allocate a descriptor to hold the type. */
597
 
598
                return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
599
                if (!return_desc) {
600
                        status = AE_NO_MEMORY;
601
                        goto cleanup;
602
                }
603
 
604
                return_desc->integer.value = type;
605
                break;
606
 
607
 
608
        case AML_SIZE_OF_OP:            /* size_of (source_object) */
609
 
610
                /* Get the base object */
611
 
612
                status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, &temp_desc);
613
                if (ACPI_FAILURE (status)) {
614
                        goto cleanup;
615
                }
616
 
617
                /*
618
                 * Type is guaranteed to be a buffer, string, or package at this
619
                 * point (even if the original operand was an object reference, it
620
                 * will be resolved and typechecked during operand resolution.)
621
                 */
622
                switch (type) {
623
                case ACPI_TYPE_BUFFER:
624
                        value = temp_desc->buffer.length;
625
                        break;
626
 
627
                case ACPI_TYPE_STRING:
628
                        value = temp_desc->string.length;
629
                        break;
630
 
631
                case ACPI_TYPE_PACKAGE:
632
                        value = temp_desc->package.count;
633
                        break;
634
 
635
                default:
636
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "size_of, Not Buf/Str/Pkg - found type %s\n",
637
                                acpi_ut_get_type_name (type)));
638
                        status = AE_AML_OPERAND_TYPE;
639
                        goto cleanup;
640
                }
641
 
642
                /*
643
                 * Now that we have the size of the object, create a result
644
                 * object to hold the value
645
                 */
646
                return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
647
                if (!return_desc) {
648
                        status = AE_NO_MEMORY;
649
                        goto cleanup;
650
                }
651
 
652
                return_desc->integer.value = value;
653
                break;
654
 
655
 
656
        case AML_REF_OF_OP:             /* ref_of (source_object) */
657
 
658
                status = acpi_ex_get_object_reference (operand[0], &return_desc, walk_state);
659
                if (ACPI_FAILURE (status)) {
660
                        goto cleanup;
661
                }
662
                break;
663
 
664
 
665
        case AML_DEREF_OF_OP:           /* deref_of (obj_reference | String) */
666
 
667
                /* Check for a method local or argument, or standalone String */
668
 
669
                if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) != ACPI_DESC_TYPE_NAMED) {
670
                        switch (ACPI_GET_OBJECT_TYPE (operand[0])) {
671
                        case ACPI_TYPE_LOCAL_REFERENCE:
672
                                /*
673
                                 * This is a deref_of (local_x | arg_x)
674
                                 *
675
                                 * Must resolve/dereference the local/arg reference first
676
                                 */
677
                                switch (operand[0]->reference.opcode) {
678
                                case AML_LOCAL_OP:
679
                                case AML_ARG_OP:
680
 
681
                                        /* Set Operand[0] to the value of the local/arg */
682
 
683
                                        status = acpi_ds_method_data_get_value (operand[0]->reference.opcode,
684
                                                         operand[0]->reference.offset, walk_state, &temp_desc);
685
                                        if (ACPI_FAILURE (status)) {
686
                                                goto cleanup;
687
                                        }
688
 
689
                                        /*
690
                                         * Delete our reference to the input object and
691
                                         * point to the object just retrieved
692
                                         */
693
                                        acpi_ut_remove_reference (operand[0]);
694
                                        operand[0] = temp_desc;
695
                                        break;
696
 
697
                                case AML_REF_OF_OP:
698
 
699
                                        /* Get the object to which the reference refers */
700
 
701
                                        temp_desc = operand[0]->reference.object;
702
                                        acpi_ut_remove_reference (operand[0]);
703
                                        operand[0] = temp_desc;
704
                                        break;
705
 
706
                                default:
707
 
708
                                        /* Must be an Index op - handled below */
709
                                        break;
710
                                }
711
                                break;
712
 
713
 
714
                        case ACPI_TYPE_STRING:
715
 
716
                                /*
717
                                 * This is a deref_of (String). The string is a reference to a named ACPI object.
718
                                 *
719
                                 * 1) Find the owning Node
720
                                 * 2) Dereference the node to an actual object.  Could be a Field, so we nee
721
                                 *    to resolve the node to a value.
722
                                 */
723
                                status = acpi_ns_get_node_by_path (operand[0]->string.pointer,
724
                                                  walk_state->scope_info->scope.node, ACPI_NS_SEARCH_PARENT,
725
                                                  ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &return_desc));
726
                                if (ACPI_FAILURE (status)) {
727
                                        goto cleanup;
728
                                }
729
 
730
                                status = acpi_ex_resolve_node_to_value (
731
                                                  ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &return_desc), walk_state);
732
                                goto cleanup;
733
 
734
 
735
                        default:
736
 
737
                                status = AE_AML_OPERAND_TYPE;
738
                                goto cleanup;
739
                        }
740
                }
741
 
742
                /* Operand[0] may have changed from the code above */
743
 
744
                if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) == ACPI_DESC_TYPE_NAMED) {
745
                        /*
746
                         * This is a deref_of (object_reference)
747
                         * Get the actual object from the Node (This is the dereference).
748
                         * -- This case may only happen when a local_x or arg_x is dereferenced above.
749
                         */
750
                        return_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) operand[0]);
751
                }
752
                else {
753
                        /*
754
                         * This must be a reference object produced by either the Index() or
755
                         * ref_of() operator
756
                         */
757
                        switch (operand[0]->reference.opcode) {
758
                        case AML_INDEX_OP:
759
 
760
                                /*
761
                                 * The target type for the Index operator must be
762
                                 * either a Buffer or a Package
763
                                 */
764
                                switch (operand[0]->reference.target_type) {
765
                                case ACPI_TYPE_BUFFER_FIELD:
766
 
767
                                        temp_desc = operand[0]->reference.object;
768
 
769
                                        /*
770
                                         * Create a new object that contains one element of the
771
                                         * buffer -- the element pointed to by the index.
772
                                         *
773
                                         * NOTE: index into a buffer is NOT a pointer to a
774
                                         * sub-buffer of the main buffer, it is only a pointer to a
775
                                         * single element (byte) of the buffer!
776
                                         */
777
                                        return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
778
                                        if (!return_desc) {
779
                                                status = AE_NO_MEMORY;
780
                                                goto cleanup;
781
                                        }
782
 
783
                                        /*
784
                                         * Since we are returning the value of the buffer at the
785
                                         * indexed location, we don't need to add an additional
786
                                         * reference to the buffer itself.
787
                                         */
788
                                        return_desc->integer.value =
789
                                                temp_desc->buffer.pointer[operand[0]->reference.offset];
790
                                        break;
791
 
792
 
793
                                case ACPI_TYPE_PACKAGE:
794
 
795
                                        /*
796
                                         * Return the referenced element of the package.  We must add
797
                                         * another reference to the referenced object, however.
798
                                         */
799
                                        return_desc = *(operand[0]->reference.where);
800
                                        if (!return_desc) {
801
                                                /*
802
                                                 * We can't return a NULL dereferenced value.  This is
803
                                                 * an uninitialized package element and is thus a
804
                                                 * severe error.
805
                                                 */
806
                                                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "NULL package element obj %p\n",
807
                                                        operand[0]));
808
                                                status = AE_AML_UNINITIALIZED_ELEMENT;
809
                                                goto cleanup;
810
                                        }
811
 
812
                                        acpi_ut_add_reference (return_desc);
813
                                        break;
814
 
815
 
816
                                default:
817
 
818
                                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Index target_type %X in obj %p\n",
819
                                                operand[0]->reference.target_type, operand[0]));
820
                                        status = AE_AML_OPERAND_TYPE;
821
                                        goto cleanup;
822
                                }
823
                                break;
824
 
825
 
826
                        case AML_REF_OF_OP:
827
 
828
                                return_desc = operand[0]->reference.object;
829
 
830
                                if (ACPI_GET_DESCRIPTOR_TYPE (return_desc) == ACPI_DESC_TYPE_NAMED) {
831
 
832
                                        return_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) return_desc);
833
                                }
834
 
835
                                /* Add another reference to the object! */
836
 
837
                                acpi_ut_add_reference (return_desc);
838
                                break;
839
 
840
 
841
                        default:
842
                                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode in ref(%p) - %X\n",
843
                                        operand[0], operand[0]->reference.opcode));
844
 
845
                                status = AE_TYPE;
846
                                goto cleanup;
847
                        }
848
                }
849
                break;
850
 
851
 
852
        default:
853
 
854
                ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_0T_1R: Unknown opcode %X\n",
855
                        walk_state->opcode));
856
                status = AE_AML_BAD_OPCODE;
857
                goto cleanup;
858
        }
859
 
860
 
861
cleanup:
862
 
863
        /* Delete return object on error */
864
 
865
        if (ACPI_FAILURE (status)) {
866
                acpi_ut_remove_reference (return_desc);
867
        }
868
 
869
        walk_state->result_obj = return_desc;
870
        return_ACPI_STATUS (status);
871
}
872
 

powered by: WebSVN 2.1.0

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