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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/******************************************************************************
2
 *
3
 * Module Name: dsopcode - Dispatcher Op Region support and handling of
4
 *                         "control" opcodes
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/amlcode.h>
49
#include <acpi/acdispat.h>
50
#include <acpi/acinterp.h>
51
#include <acpi/acnamesp.h>
52
#include <acpi/acevents.h>
53
 
54
#define _COMPONENT          ACPI_DISPATCHER
55
         ACPI_MODULE_NAME    ("dsopcode")
56
 
57
 
58
/*****************************************************************************
59
 *
60
 * FUNCTION:    acpi_ds_execute_arguments
61
 *
62
 * PARAMETERS:  Node                - Parent NS node
63
 *              aml_length          - Length of executable AML
64
 *              aml_start           - Pointer to the AML
65
 *
66
 * RETURN:      Status.
67
 *
68
 * DESCRIPTION: Late (deferred) execution of region or field arguments
69
 *
70
 ****************************************************************************/
71
 
72
acpi_status
73
acpi_ds_execute_arguments (
74
        struct acpi_namespace_node      *node,
75
        struct acpi_namespace_node      *scope_node,
76
        u32                             aml_length,
77
        u8                              *aml_start)
78
{
79
        acpi_status                     status;
80
        union acpi_parse_object         *op;
81
        struct acpi_walk_state          *walk_state;
82
        union acpi_parse_object         *arg;
83
 
84
 
85
        ACPI_FUNCTION_TRACE ("ds_execute_arguments");
86
 
87
 
88
        /*
89
         * Allocate a new parser op to be the root of the parsed tree
90
         */
91
        op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP);
92
        if (!op) {
93
                return_ACPI_STATUS (AE_NO_MEMORY);
94
        }
95
 
96
        /* Save the Node for use in acpi_ps_parse_aml */
97
 
98
        op->common.node = scope_node;
99
 
100
        /* Create and initialize a new parser state */
101
 
102
        walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
103
        if (!walk_state) {
104
                return_ACPI_STATUS (AE_NO_MEMORY);
105
        }
106
 
107
        status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,
108
                          aml_length, NULL, NULL, 1);
109
        if (ACPI_FAILURE (status)) {
110
                acpi_ds_delete_walk_state (walk_state);
111
                return_ACPI_STATUS (status);
112
        }
113
 
114
        /* Mark this parse as a deferred opcode */
115
 
116
        walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;
117
        walk_state->deferred_node = node;
118
 
119
        /* Pass1: Parse the entire declaration */
120
 
121
        status = acpi_ps_parse_aml (walk_state);
122
        if (ACPI_FAILURE (status)) {
123
                acpi_ps_delete_parse_tree (op);
124
                return_ACPI_STATUS (status);
125
        }
126
 
127
        /* Get and init the Op created above */
128
 
129
        arg = op->common.value.arg;
130
        op->common.node = node;
131
        arg->common.node = node;
132
        acpi_ps_delete_parse_tree (op);
133
 
134
        /* Evaluate the deferred arguments */
135
 
136
        op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP);
137
        if (!op) {
138
                return_ACPI_STATUS (AE_NO_MEMORY);
139
        }
140
 
141
        op->common.node = scope_node;
142
 
143
        /* Create and initialize a new parser state */
144
 
145
        walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
146
        if (!walk_state) {
147
                return_ACPI_STATUS (AE_NO_MEMORY);
148
        }
149
 
150
        /* Execute the opcode and arguments */
151
 
152
        status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,
153
                          aml_length, NULL, NULL, 3);
154
        if (ACPI_FAILURE (status)) {
155
                acpi_ds_delete_walk_state (walk_state);
156
                return_ACPI_STATUS (status);
157
        }
158
 
159
        /* Mark this execution as a deferred opcode */
160
 
161
        walk_state->deferred_node = node;
162
        status = acpi_ps_parse_aml (walk_state);
163
        acpi_ps_delete_parse_tree (op);
164
        return_ACPI_STATUS (status);
165
}
166
 
167
 
168
/*****************************************************************************
169
 *
170
 * FUNCTION:    acpi_ds_get_buffer_field_arguments
171
 *
172
 * PARAMETERS:  obj_desc        - A valid buffer_field object
173
 *
174
 * RETURN:      Status.
175
 *
176
 * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
177
 *              evaluation of these field attributes.
178
 *
179
 ****************************************************************************/
180
 
181
acpi_status
182
acpi_ds_get_buffer_field_arguments (
183
        union acpi_operand_object       *obj_desc)
184
{
185
        union acpi_operand_object       *extra_desc;
186
        struct acpi_namespace_node      *node;
187
        acpi_status                     status;
188
 
189
 
190
        ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_field_arguments", obj_desc);
191
 
192
 
193
        if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
194
                return_ACPI_STATUS (AE_OK);
195
        }
196
 
197
        /* Get the AML pointer (method object) and buffer_field node */
198
 
199
        extra_desc = acpi_ns_get_secondary_object (obj_desc);
200
        node = obj_desc->buffer_field.node;
201
 
202
        ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_BUFFER_FIELD, node, NULL));
203
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] buffer_field Arg Init\n",
204
                acpi_ut_get_node_name (node)));
205
 
206
        /* Execute the AML code for the term_arg arguments */
207
 
208
        status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node),
209
                         extra_desc->extra.aml_length, extra_desc->extra.aml_start);
210
        return_ACPI_STATUS (status);
211
}
212
 
213
 
214
/*****************************************************************************
215
 *
216
 * FUNCTION:    acpi_ds_get_buffer_arguments
217
 *
218
 * PARAMETERS:  obj_desc        - A valid Buffer object
219
 *
220
 * RETURN:      Status.
221
 *
222
 * DESCRIPTION: Get Buffer length and initializer byte list.  This implements
223
 *              the late evaluation of these attributes.
224
 *
225
 ****************************************************************************/
226
 
227
acpi_status
228
acpi_ds_get_buffer_arguments (
229
        union acpi_operand_object       *obj_desc)
230
{
231
        struct acpi_namespace_node      *node;
232
        acpi_status                     status;
233
 
234
 
235
        ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_arguments", obj_desc);
236
 
237
 
238
        if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
239
                return_ACPI_STATUS (AE_OK);
240
        }
241
 
242
        /* Get the Buffer node */
243
 
244
        node = obj_desc->buffer.node;
245
        if (!node) {
246
                ACPI_REPORT_ERROR ((
247
                                "No pointer back to NS node in buffer obj %p\n", obj_desc));
248
                return_ACPI_STATUS (AE_AML_INTERNAL);
249
        }
250
 
251
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
252
 
253
        /* Execute the AML code for the term_arg arguments */
254
 
255
        status = acpi_ds_execute_arguments (node, node,
256
                         obj_desc->buffer.aml_length, obj_desc->buffer.aml_start);
257
        return_ACPI_STATUS (status);
258
}
259
 
260
 
261
/*****************************************************************************
262
 *
263
 * FUNCTION:    acpi_ds_get_package_arguments
264
 *
265
 * PARAMETERS:  obj_desc        - A valid Package object
266
 *
267
 * RETURN:      Status.
268
 *
269
 * DESCRIPTION: Get Package length and initializer byte list.  This implements
270
 *              the late evaluation of these attributes.
271
 *
272
 ****************************************************************************/
273
 
274
acpi_status
275
acpi_ds_get_package_arguments (
276
        union acpi_operand_object       *obj_desc)
277
{
278
        struct acpi_namespace_node      *node;
279
        acpi_status                     status;
280
 
281
 
282
        ACPI_FUNCTION_TRACE_PTR ("ds_get_package_arguments", obj_desc);
283
 
284
 
285
        if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
286
                return_ACPI_STATUS (AE_OK);
287
        }
288
 
289
        /* Get the Package node */
290
 
291
        node = obj_desc->package.node;
292
        if (!node) {
293
                ACPI_REPORT_ERROR ((
294
                                "No pointer back to NS node in package %p\n", obj_desc));
295
                return_ACPI_STATUS (AE_AML_INTERNAL);
296
        }
297
 
298
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n"));
299
 
300
        /* Execute the AML code for the term_arg arguments */
301
 
302
        status = acpi_ds_execute_arguments (node, node,
303
                         obj_desc->package.aml_length, obj_desc->package.aml_start);
304
        return_ACPI_STATUS (status);
305
}
306
 
307
 
308
/*****************************************************************************
309
 *
310
 * FUNCTION:    acpi_ds_get_region_arguments
311
 *
312
 * PARAMETERS:  obj_desc        - A valid region object
313
 *
314
 * RETURN:      Status.
315
 *
316
 * DESCRIPTION: Get region address and length.  This implements the late
317
 *              evaluation of these region attributes.
318
 *
319
 ****************************************************************************/
320
 
321
acpi_status
322
acpi_ds_get_region_arguments (
323
        union acpi_operand_object       *obj_desc)
324
{
325
        struct acpi_namespace_node      *node;
326
        acpi_status                     status;
327
        union acpi_operand_object       *extra_desc;
328
 
329
 
330
        ACPI_FUNCTION_TRACE_PTR ("ds_get_region_arguments", obj_desc);
331
 
332
 
333
        if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
334
                return_ACPI_STATUS (AE_OK);
335
        }
336
 
337
        extra_desc = acpi_ns_get_secondary_object (obj_desc);
338
        if (!extra_desc) {
339
                return_ACPI_STATUS (AE_NOT_EXIST);
340
        }
341
 
342
        /* Get the Region node */
343
 
344
        node = obj_desc->region.node;
345
 
346
        ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL));
347
 
348
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] op_region Arg Init at AML %p\n",
349
                acpi_ut_get_node_name (node), extra_desc->extra.aml_start));
350
 
351
        /* Execute the argument AML */
352
 
353
        status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node),
354
                         extra_desc->extra.aml_length, extra_desc->extra.aml_start);
355
        return_ACPI_STATUS (status);
356
}
357
 
358
 
359
/*****************************************************************************
360
 *
361
 * FUNCTION:    acpi_ds_initialize_region
362
 *
363
 * PARAMETERS:  Op              - A valid region Op object
364
 *
365
 * RETURN:      Status
366
 *
367
 * DESCRIPTION: Front end to ev_initialize_region
368
 *
369
 ****************************************************************************/
370
 
371
acpi_status
372
acpi_ds_initialize_region (
373
        acpi_handle                     obj_handle)
374
{
375
        union acpi_operand_object       *obj_desc;
376
        acpi_status                     status;
377
 
378
 
379
        obj_desc = acpi_ns_get_attached_object (obj_handle);
380
 
381
        /* Namespace is NOT locked */
382
 
383
        status = acpi_ev_initialize_region (obj_desc, FALSE);
384
        return (status);
385
}
386
 
387
 
388
/*****************************************************************************
389
 *
390
 * FUNCTION:    acpi_ds_init_buffer_field
391
 *
392
 * PARAMETERS:  aml_opcode      - create_xxx_field
393
 *              obj_desc        - buffer_field object
394
 *              buffer_desc     - Host Buffer
395
 *              offset_desc     - Offset into buffer
396
 *              Length          - Length of field (CREATE_FIELD_OP only)
397
 *              Result          - Where to store the result
398
 *
399
 * RETURN:      Status
400
 *
401
 * DESCRIPTION: Perform actual initialization of a buffer field
402
 *
403
 ****************************************************************************/
404
 
405
acpi_status
406
acpi_ds_init_buffer_field (
407
        u16                             aml_opcode,
408
        union acpi_operand_object       *obj_desc,
409
        union acpi_operand_object       *buffer_desc,
410
        union acpi_operand_object       *offset_desc,
411
        union acpi_operand_object       *length_desc,
412
        union acpi_operand_object       *result_desc)
413
{
414
        u32                             offset;
415
        u32                             bit_offset;
416
        u32                             bit_count;
417
        u8                              field_flags;
418
        acpi_status                     status;
419
 
420
 
421
        ACPI_FUNCTION_TRACE_PTR ("ds_init_buffer_field", obj_desc);
422
 
423
 
424
        /* Host object must be a Buffer */
425
 
426
        if (ACPI_GET_OBJECT_TYPE (buffer_desc) != ACPI_TYPE_BUFFER) {
427
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
428
                        "Target of Create Field is not a Buffer object - %s\n",
429
                        acpi_ut_get_object_type_name (buffer_desc)));
430
 
431
                status = AE_AML_OPERAND_TYPE;
432
                goto cleanup;
433
        }
434
 
435
        /*
436
         * The last parameter to all of these opcodes (result_desc) started
437
         * out as a name_string, and should therefore now be a NS node
438
         * after resolution in acpi_ex_resolve_operands().
439
         */
440
        if (ACPI_GET_DESCRIPTOR_TYPE (result_desc) != ACPI_DESC_TYPE_NAMED) {
441
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination not a NS Node [%s]\n",
442
                                acpi_ps_get_opcode_name (aml_opcode), acpi_ut_get_descriptor_name (result_desc)));
443
 
444
                status = AE_AML_OPERAND_TYPE;
445
                goto cleanup;
446
        }
447
 
448
        offset = (u32) offset_desc->integer.value;
449
 
450
        /*
451
         * Setup the Bit offsets and counts, according to the opcode
452
         */
453
        switch (aml_opcode) {
454
        case AML_CREATE_FIELD_OP:
455
 
456
                /* Offset is in bits, count is in bits */
457
 
458
                bit_offset = offset;
459
                bit_count  = (u32) length_desc->integer.value;
460
                field_flags = AML_FIELD_ACCESS_BYTE;
461
                break;
462
 
463
        case AML_CREATE_BIT_FIELD_OP:
464
 
465
                /* Offset is in bits, Field is one bit */
466
 
467
                bit_offset = offset;
468
                bit_count  = 1;
469
                field_flags = AML_FIELD_ACCESS_BYTE;
470
                break;
471
 
472
        case AML_CREATE_BYTE_FIELD_OP:
473
 
474
                /* Offset is in bytes, field is one byte */
475
 
476
                bit_offset = 8 * offset;
477
                bit_count  = 8;
478
                field_flags = AML_FIELD_ACCESS_BYTE;
479
                break;
480
 
481
        case AML_CREATE_WORD_FIELD_OP:
482
 
483
                /* Offset is in bytes, field is one word */
484
 
485
                bit_offset = 8 * offset;
486
                bit_count  = 16;
487
                field_flags = AML_FIELD_ACCESS_WORD;
488
                break;
489
 
490
        case AML_CREATE_DWORD_FIELD_OP:
491
 
492
                /* Offset is in bytes, field is one dword */
493
 
494
                bit_offset = 8 * offset;
495
                bit_count  = 32;
496
                field_flags = AML_FIELD_ACCESS_DWORD;
497
                break;
498
 
499
        case AML_CREATE_QWORD_FIELD_OP:
500
 
501
                /* Offset is in bytes, field is one qword */
502
 
503
                bit_offset = 8 * offset;
504
                bit_count  = 64;
505
                field_flags = AML_FIELD_ACCESS_QWORD;
506
                break;
507
 
508
        default:
509
 
510
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
511
                        "Unknown field creation opcode %02x\n",
512
                        aml_opcode));
513
                status = AE_AML_BAD_OPCODE;
514
                goto cleanup;
515
        }
516
 
517
        /* Entire field must fit within the current length of the buffer */
518
 
519
        if ((bit_offset + bit_count) >
520
                (8 * (u32) buffer_desc->buffer.length)) {
521
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
522
                        "Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n",
523
                         acpi_ut_get_node_name (result_desc),
524
                         bit_offset + bit_count,
525
                         acpi_ut_get_node_name (buffer_desc->buffer.node),
526
                         8 * (u32) buffer_desc->buffer.length));
527
                status = AE_AML_BUFFER_LIMIT;
528
                goto cleanup;
529
        }
530
 
531
        /*
532
         * Initialize areas of the field object that are common to all fields
533
         * For field_flags, use LOCK_RULE = 0 (NO_LOCK), UPDATE_RULE = 0 (UPDATE_PRESERVE)
534
         */
535
        status = acpi_ex_prep_common_field_object (obj_desc, field_flags, 0,
536
                          bit_offset, bit_count);
537
        if (ACPI_FAILURE (status)) {
538
                goto cleanup;
539
        }
540
 
541
        obj_desc->buffer_field.buffer_obj = buffer_desc;
542
 
543
        /* Reference count for buffer_desc inherits obj_desc count */
544
 
545
        buffer_desc->common.reference_count = (u16) (buffer_desc->common.reference_count +
546
                          obj_desc->common.reference_count);
547
 
548
 
549
cleanup:
550
 
551
        /* Always delete the operands */
552
 
553
        acpi_ut_remove_reference (offset_desc);
554
        acpi_ut_remove_reference (buffer_desc);
555
 
556
        if (aml_opcode == AML_CREATE_FIELD_OP) {
557
                acpi_ut_remove_reference (length_desc);
558
        }
559
 
560
        /* On failure, delete the result descriptor */
561
 
562
        if (ACPI_FAILURE (status)) {
563
                acpi_ut_remove_reference (result_desc); /* Result descriptor */
564
        }
565
        else {
566
                /* Now the address and length are valid for this buffer_field */
567
 
568
                obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID;
569
        }
570
 
571
        return_ACPI_STATUS (status);
572
}
573
 
574
 
575
/*****************************************************************************
576
 *
577
 * FUNCTION:    acpi_ds_eval_buffer_field_operands
578
 *
579
 * PARAMETERS:  walk_state      - Current walk
580
 *              Op              - A valid buffer_field Op object
581
 *
582
 * RETURN:      Status
583
 *
584
 * DESCRIPTION: Get buffer_field Buffer and Index
585
 *              Called from acpi_ds_exec_end_op during buffer_field parse tree walk
586
 *
587
 ****************************************************************************/
588
 
589
acpi_status
590
acpi_ds_eval_buffer_field_operands (
591
        struct acpi_walk_state          *walk_state,
592
        union acpi_parse_object         *op)
593
{
594
        acpi_status                     status;
595
        union acpi_operand_object       *obj_desc;
596
        struct acpi_namespace_node      *node;
597
        union acpi_parse_object         *next_op;
598
 
599
 
600
        ACPI_FUNCTION_TRACE_PTR ("ds_eval_buffer_field_operands", op);
601
 
602
 
603
        /*
604
         * This is where we evaluate the address and length fields of the
605
         * create_xxx_field declaration
606
         */
607
        node =  op->common.node;
608
 
609
        /* next_op points to the op that holds the Buffer */
610
 
611
        next_op = op->common.value.arg;
612
 
613
        /* Evaluate/create the address and length operands */
614
 
615
        status = acpi_ds_create_operands (walk_state, next_op);
616
        if (ACPI_FAILURE (status)) {
617
                return_ACPI_STATUS (status);
618
        }
619
 
620
        obj_desc = acpi_ns_get_attached_object (node);
621
        if (!obj_desc) {
622
                return_ACPI_STATUS (AE_NOT_EXIST);
623
        }
624
 
625
        /* Resolve the operands */
626
 
627
        status = acpi_ex_resolve_operands (op->common.aml_opcode,
628
                          ACPI_WALK_OPERANDS, walk_state);
629
 
630
        ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
631
                          acpi_ps_get_opcode_name (op->common.aml_opcode),
632
                          walk_state->num_operands, "after acpi_ex_resolve_operands");
633
 
634
        if (ACPI_FAILURE (status)) {
635
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n",
636
                        acpi_ps_get_opcode_name (op->common.aml_opcode), status));
637
 
638
                return_ACPI_STATUS (status);
639
        }
640
 
641
        /* Initialize the Buffer Field */
642
 
643
        if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
644
                /* NOTE: Slightly different operands for this opcode */
645
 
646
                status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc,
647
                                 walk_state->operands[0], walk_state->operands[1],
648
                                 walk_state->operands[2], walk_state->operands[3]);
649
        }
650
        else {
651
                /* All other, create_xxx_field opcodes */
652
 
653
                status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc,
654
                                 walk_state->operands[0], walk_state->operands[1],
655
                                                  NULL, walk_state->operands[2]);
656
        }
657
 
658
        return_ACPI_STATUS (status);
659
}
660
 
661
 
662
/*****************************************************************************
663
 *
664
 * FUNCTION:    acpi_ds_eval_region_operands
665
 *
666
 * PARAMETERS:  walk_state      - Current walk
667
 *              Op              - A valid region Op object
668
 *
669
 * RETURN:      Status
670
 *
671
 * DESCRIPTION: Get region address and length
672
 *              Called from acpi_ds_exec_end_op during op_region parse tree walk
673
 *
674
 ****************************************************************************/
675
 
676
acpi_status
677
acpi_ds_eval_region_operands (
678
        struct acpi_walk_state          *walk_state,
679
        union acpi_parse_object         *op)
680
{
681
        acpi_status                     status;
682
        union acpi_operand_object       *obj_desc;
683
        union acpi_operand_object       *operand_desc;
684
        struct acpi_namespace_node      *node;
685
        union acpi_parse_object         *next_op;
686
 
687
 
688
        ACPI_FUNCTION_TRACE_PTR ("ds_eval_region_operands", op);
689
 
690
 
691
        /*
692
         * This is where we evaluate the address and length fields of the op_region declaration
693
         */
694
        node =  op->common.node;
695
 
696
        /* next_op points to the op that holds the space_iD */
697
 
698
        next_op = op->common.value.arg;
699
 
700
        /* next_op points to address op */
701
 
702
        next_op = next_op->common.next;
703
 
704
        /* Evaluate/create the address and length operands */
705
 
706
        status = acpi_ds_create_operands (walk_state, next_op);
707
        if (ACPI_FAILURE (status)) {
708
                return_ACPI_STATUS (status);
709
        }
710
 
711
        /* Resolve the length and address operands to numbers */
712
 
713
        status = acpi_ex_resolve_operands (op->common.aml_opcode, ACPI_WALK_OPERANDS, walk_state);
714
        if (ACPI_FAILURE (status)) {
715
                return_ACPI_STATUS (status);
716
        }
717
 
718
        ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
719
                          acpi_ps_get_opcode_name (op->common.aml_opcode),
720
                          1, "after acpi_ex_resolve_operands");
721
 
722
        obj_desc = acpi_ns_get_attached_object (node);
723
        if (!obj_desc) {
724
                return_ACPI_STATUS (AE_NOT_EXIST);
725
        }
726
 
727
        /*
728
         * Get the length operand and save it
729
         * (at Top of stack)
730
         */
731
        operand_desc = walk_state->operands[walk_state->num_operands - 1];
732
 
733
        obj_desc->region.length = (u32) operand_desc->integer.value;
734
        acpi_ut_remove_reference (operand_desc);
735
 
736
        /*
737
         * Get the address and save it
738
         * (at top of stack - 1)
739
         */
740
        operand_desc = walk_state->operands[walk_state->num_operands - 2];
741
 
742
        obj_desc->region.address = (acpi_physical_address) operand_desc->integer.value;
743
        acpi_ut_remove_reference (operand_desc);
744
 
745
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "rgn_obj %p Addr %8.8X%8.8X Len %X\n",
746
                obj_desc,
747
                ACPI_FORMAT_UINT64 (obj_desc->region.address),
748
                obj_desc->region.length));
749
 
750
        /* Now the address and length are valid for this opregion */
751
 
752
        obj_desc->region.flags |= AOPOBJ_DATA_VALID;
753
 
754
        return_ACPI_STATUS (status);
755
}
756
 
757
 
758
/*****************************************************************************
759
 *
760
 * FUNCTION:    acpi_ds_eval_data_object_operands
761
 *
762
 * PARAMETERS:  walk_state      - Current walk
763
 *              Op              - A valid data_object Op object
764
 *              obj_desc        - data_object
765
 *
766
 * RETURN:      Status
767
 *
768
 * DESCRIPTION: Get the operands and complete the following data objec types:
769
 *              Buffer
770
 *              Package
771
 *
772
 ****************************************************************************/
773
 
774
acpi_status
775
acpi_ds_eval_data_object_operands (
776
        struct acpi_walk_state          *walk_state,
777
        union acpi_parse_object         *op,
778
        union acpi_operand_object       *obj_desc)
779
{
780
        acpi_status                     status;
781
        union acpi_operand_object       *arg_desc;
782
        u32                             length;
783
 
784
 
785
        ACPI_FUNCTION_TRACE ("ds_eval_data_object_operands");
786
 
787
 
788
        /* The first operand (for all of these data objects) is the length */
789
 
790
        status = acpi_ds_create_operand (walk_state, op->common.value.arg, 1);
791
        if (ACPI_FAILURE (status)) {
792
                return_ACPI_STATUS (status);
793
        }
794
 
795
        status = acpi_ex_resolve_operands (walk_state->opcode,
796
                          &(walk_state->operands [walk_state->num_operands -1]),
797
                          walk_state);
798
        if (ACPI_FAILURE (status)) {
799
                return_ACPI_STATUS (status);
800
        }
801
 
802
        /* Extract length operand */
803
 
804
        arg_desc = walk_state->operands [walk_state->num_operands - 1];
805
        length = (u32) arg_desc->integer.value;
806
 
807
        /* Cleanup for length operand */
808
 
809
        status = acpi_ds_obj_stack_pop (1, walk_state);
810
        if (ACPI_FAILURE (status)) {
811
                return_ACPI_STATUS (status);
812
        }
813
 
814
        acpi_ut_remove_reference (arg_desc);
815
 
816
        /*
817
         * Create the actual data object
818
         */
819
        switch (op->common.aml_opcode) {
820
        case AML_BUFFER_OP:
821
 
822
                status = acpi_ds_build_internal_buffer_obj (walk_state, op, length, &obj_desc);
823
                break;
824
 
825
        case AML_PACKAGE_OP:
826
        case AML_VAR_PACKAGE_OP:
827
 
828
                status = acpi_ds_build_internal_package_obj (walk_state, op, length, &obj_desc);
829
                break;
830
 
831
        default:
832
                return_ACPI_STATUS (AE_AML_BAD_OPCODE);
833
        }
834
 
835
        if (ACPI_SUCCESS (status)) {
836
                /*
837
                 * Return the object in the walk_state, unless the parent is a package --
838
                 * in this case, the return object will be stored in the parse tree
839
                 * for the package.
840
                 */
841
                if ((!op->common.parent) ||
842
                        ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) &&
843
                         (op->common.parent->common.aml_opcode != AML_VAR_PACKAGE_OP) &&
844
                         (op->common.parent->common.aml_opcode != AML_NAME_OP))) {
845
                        walk_state->result_obj = obj_desc;
846
                }
847
        }
848
 
849
        return_ACPI_STATUS (status);
850
}
851
 
852
 
853
/*******************************************************************************
854
 *
855
 * FUNCTION:    acpi_ds_exec_begin_control_op
856
 *
857
 * PARAMETERS:  walk_list       - The list that owns the walk stack
858
 *              Op              - The control Op
859
 *
860
 * RETURN:      Status
861
 *
862
 * DESCRIPTION: Handles all control ops encountered during control method
863
 *              execution.
864
 *
865
 ******************************************************************************/
866
 
867
acpi_status
868
acpi_ds_exec_begin_control_op (
869
        struct acpi_walk_state          *walk_state,
870
        union acpi_parse_object         *op)
871
{
872
        acpi_status                     status = AE_OK;
873
        union acpi_generic_state        *control_state;
874
 
875
 
876
        ACPI_FUNCTION_NAME ("ds_exec_begin_control_op");
877
 
878
 
879
        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op,
880
                op->common.aml_opcode, walk_state));
881
 
882
        switch (op->common.aml_opcode) {
883
        case AML_IF_OP:
884
        case AML_WHILE_OP:
885
 
886
                /*
887
                 * IF/WHILE: Create a new control state to manage these
888
                 * constructs. We need to manage these as a stack, in order
889
                 * to handle nesting.
890
                 */
891
                control_state = acpi_ut_create_control_state ();
892
                if (!control_state) {
893
                        status = AE_NO_MEMORY;
894
                        break;
895
                }
896
                /*
897
                 * Save a pointer to the predicate for multiple executions
898
                 * of a loop
899
                 */
900
                control_state->control.aml_predicate_start = walk_state->parser_state.aml - 1;
901
                control_state->control.package_end = walk_state->parser_state.pkg_end;
902
                control_state->control.opcode = op->common.aml_opcode;
903
 
904
 
905
                /* Push the control state on this walk's control stack */
906
 
907
                acpi_ut_push_generic_state (&walk_state->control_state, control_state);
908
                break;
909
 
910
        case AML_ELSE_OP:
911
 
912
                /* Predicate is in the state object */
913
                /* If predicate is true, the IF was executed, ignore ELSE part */
914
 
915
                if (walk_state->last_predicate) {
916
                        status = AE_CTRL_TRUE;
917
                }
918
 
919
                break;
920
 
921
        case AML_RETURN_OP:
922
 
923
                break;
924
 
925
        default:
926
                break;
927
        }
928
 
929
        return (status);
930
}
931
 
932
 
933
/*******************************************************************************
934
 *
935
 * FUNCTION:    acpi_ds_exec_end_control_op
936
 *
937
 * PARAMETERS:  walk_list       - The list that owns the walk stack
938
 *              Op              - The control Op
939
 *
940
 * RETURN:      Status
941
 *
942
 * DESCRIPTION: Handles all control ops encountered during control method
943
 *              execution.
944
 *
945
 ******************************************************************************/
946
 
947
acpi_status
948
acpi_ds_exec_end_control_op (
949
        struct acpi_walk_state          *walk_state,
950
        union acpi_parse_object         *op)
951
{
952
        acpi_status                     status = AE_OK;
953
        union acpi_generic_state        *control_state;
954
 
955
 
956
        ACPI_FUNCTION_NAME ("ds_exec_end_control_op");
957
 
958
 
959
        switch (op->common.aml_opcode) {
960
        case AML_IF_OP:
961
 
962
                ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op));
963
 
964
                /*
965
                 * Save the result of the predicate in case there is an
966
                 * ELSE to come
967
                 */
968
                walk_state->last_predicate =
969
                        (u8) walk_state->control_state->common.value;
970
 
971
                /*
972
                 * Pop the control state that was created at the start
973
                 * of the IF and free it
974
                 */
975
                control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
976
                acpi_ut_delete_generic_state (control_state);
977
                break;
978
 
979
 
980
        case AML_ELSE_OP:
981
 
982
                break;
983
 
984
 
985
        case AML_WHILE_OP:
986
 
987
                ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op));
988
 
989
                if (walk_state->control_state->common.value) {
990
                        /* Predicate was true, go back and evaluate it again! */
991
 
992
                        status = AE_CTRL_PENDING;
993
                }
994
 
995
                ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] termination! Op=%p\n", op));
996
 
997
                /* Pop this control state and free it */
998
 
999
                control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
1000
 
1001
                walk_state->aml_last_while = control_state->control.aml_predicate_start;
1002
                acpi_ut_delete_generic_state (control_state);
1003
                break;
1004
 
1005
 
1006
        case AML_RETURN_OP:
1007
 
1008
                ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1009
                        "[RETURN_OP] Op=%p Arg=%p\n",op, op->common.value.arg));
1010
 
1011
                /*
1012
                 * One optional operand -- the return value
1013
                 * It can be either an immediate operand or a result that
1014
                 * has been bubbled up the tree
1015
                 */
1016
                if (op->common.value.arg) {
1017
                        /* Return statement has an immediate operand */
1018
 
1019
                        status = acpi_ds_create_operands (walk_state, op->common.value.arg);
1020
                        if (ACPI_FAILURE (status)) {
1021
                                return (status);
1022
                        }
1023
 
1024
                        /*
1025
                         * If value being returned is a Reference (such as
1026
                         * an arg or local), resolve it now because it may
1027
                         * cease to exist at the end of the method.
1028
                         */
1029
                        status = acpi_ex_resolve_to_value (&walk_state->operands [0], walk_state);
1030
                        if (ACPI_FAILURE (status)) {
1031
                                return (status);
1032
                        }
1033
 
1034
                        /*
1035
                         * Get the return value and save as the last result
1036
                         * value.  This is the only place where walk_state->return_desc
1037
                         * is set to anything other than zero!
1038
                         */
1039
                        walk_state->return_desc = walk_state->operands[0];
1040
                }
1041
                else if ((walk_state->results) &&
1042
                                 (walk_state->results->results.num_results > 0)) {
1043
                        /*
1044
                         * The return value has come from a previous calculation.
1045
                         *
1046
                         * If value being returned is a Reference (such as
1047
                         * an arg or local), resolve it now because it may
1048
                         * cease to exist at the end of the method.
1049
                         *
1050
                         * Allow references created by the Index operator to return unchanged.
1051
                         */
1052
                        if ((ACPI_GET_DESCRIPTOR_TYPE (walk_state->results->results.obj_desc[0]) == ACPI_DESC_TYPE_OPERAND) &&
1053
                                (ACPI_GET_OBJECT_TYPE (walk_state->results->results.obj_desc [0]) == ACPI_TYPE_LOCAL_REFERENCE) &&
1054
                                ((walk_state->results->results.obj_desc [0])->reference.opcode != AML_INDEX_OP)) {
1055
                                status = acpi_ex_resolve_to_value (&walk_state->results->results.obj_desc [0], walk_state);
1056
                                if (ACPI_FAILURE (status)) {
1057
                                        return (status);
1058
                                }
1059
                        }
1060
 
1061
                        walk_state->return_desc = walk_state->results->results.obj_desc [0];
1062
                }
1063
                else {
1064
                        /* No return operand */
1065
 
1066
                        if (walk_state->num_operands) {
1067
                                acpi_ut_remove_reference (walk_state->operands [0]);
1068
                        }
1069
 
1070
                        walk_state->operands [0]    = NULL;
1071
                        walk_state->num_operands    = 0;
1072
                        walk_state->return_desc     = NULL;
1073
                }
1074
 
1075
 
1076
                ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1077
                        "Completed RETURN_OP State=%p, ret_val=%p\n",
1078
                        walk_state, walk_state->return_desc));
1079
 
1080
                /* End the control method execution right now */
1081
 
1082
                status = AE_CTRL_TERMINATE;
1083
                break;
1084
 
1085
 
1086
        case AML_NOOP_OP:
1087
 
1088
                /* Just do nothing! */
1089
                break;
1090
 
1091
 
1092
        case AML_BREAK_POINT_OP:
1093
 
1094
                /* Call up to the OS service layer to handle this */
1095
 
1096
                status = acpi_os_signal (ACPI_SIGNAL_BREAKPOINT, "Executed AML Breakpoint opcode");
1097
 
1098
                /* If and when it returns, all done. */
1099
 
1100
                break;
1101
 
1102
 
1103
        case AML_BREAK_OP:
1104
        case AML_CONTINUE_OP: /* ACPI 2.0 */
1105
 
1106
 
1107
                /* Pop and delete control states until we find a while */
1108
 
1109
                while (walk_state->control_state &&
1110
                                (walk_state->control_state->control.opcode != AML_WHILE_OP)) {
1111
                        control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
1112
                        acpi_ut_delete_generic_state (control_state);
1113
                }
1114
 
1115
                /* No while found? */
1116
 
1117
                if (!walk_state->control_state) {
1118
                        return (AE_AML_NO_WHILE);
1119
                }
1120
 
1121
                /* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */
1122
 
1123
                walk_state->aml_last_while = walk_state->control_state->control.package_end;
1124
 
1125
                /* Return status depending on opcode */
1126
 
1127
                if (op->common.aml_opcode == AML_BREAK_OP) {
1128
                        status = AE_CTRL_BREAK;
1129
                }
1130
                else {
1131
                        status = AE_CTRL_CONTINUE;
1132
                }
1133
                break;
1134
 
1135
 
1136
        default:
1137
 
1138
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown control opcode=%X Op=%p\n",
1139
                        op->common.aml_opcode, op));
1140
 
1141
                status = AE_AML_BAD_OPCODE;
1142
                break;
1143
        }
1144
 
1145
        return (status);
1146
}
1147
 

powered by: WebSVN 2.1.0

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