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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [acpi/] [executer/] [exstore.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: exstore - AML Interpreter object store support
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/acdispat.h>
48
#include <acpi/acinterp.h>
49
#include <acpi/amlcode.h>
50
#include <acpi/acnamesp.h>
51
 
52
 
53
#define _COMPONENT          ACPI_EXECUTER
54
         ACPI_MODULE_NAME    ("exstore")
55
 
56
 
57
/*******************************************************************************
58
 *
59
 * FUNCTION:    acpi_ex_store
60
 *
61
 * PARAMETERS:  *source_desc        - Value to be stored
62
 *              *dest_desc          - Where to store it.  Must be an NS node
63
 *                                    or an union acpi_operand_object of type
64
 *                                    Reference;
65
 *              walk_state          - Current walk state
66
 *
67
 * RETURN:      Status
68
 *
69
 * DESCRIPTION: Store the value described by source_desc into the location
70
 *              described by dest_desc. Called by various interpreter
71
 *              functions to store the result of an operation into
72
 *              the destination operand -- not just simply the actual "Store"
73
 *              ASL operator.
74
 *
75
 ******************************************************************************/
76
 
77
acpi_status
78
acpi_ex_store (
79
        union acpi_operand_object       *source_desc,
80
        union acpi_operand_object       *dest_desc,
81
        struct acpi_walk_state          *walk_state)
82
{
83
        acpi_status                     status = AE_OK;
84
        union acpi_operand_object       *ref_desc = dest_desc;
85
 
86
 
87
        ACPI_FUNCTION_TRACE_PTR ("ex_store", dest_desc);
88
 
89
 
90
        /* Validate parameters */
91
 
92
        if (!source_desc || !dest_desc) {
93
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null parameter\n"));
94
                return_ACPI_STATUS (AE_AML_NO_OPERAND);
95
        }
96
 
97
        /* dest_desc can be either a namespace node or an ACPI object */
98
 
99
        if (ACPI_GET_DESCRIPTOR_TYPE (dest_desc) == ACPI_DESC_TYPE_NAMED) {
100
                /*
101
                 * Dest is a namespace node,
102
                 * Storing an object into a Named node.
103
                 */
104
                status = acpi_ex_store_object_to_node (source_desc,
105
                                 (struct acpi_namespace_node *) dest_desc, walk_state);
106
 
107
                return_ACPI_STATUS (status);
108
        }
109
 
110
        /* Destination object must be a Reference or a Constant object */
111
 
112
        switch (ACPI_GET_OBJECT_TYPE (dest_desc)) {
113
        case ACPI_TYPE_LOCAL_REFERENCE:
114
                break;
115
 
116
        case ACPI_TYPE_INTEGER:
117
 
118
                /* Allow stores to Constants -- a Noop as per ACPI spec */
119
 
120
                if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
121
                        return_ACPI_STATUS (AE_OK);
122
                }
123
 
124
                /*lint -fallthrough */
125
 
126
        default:
127
 
128
                /* Destination is not a Reference object */
129
 
130
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
131
                        "Destination is not a Reference or Constant object [%p]\n", dest_desc));
132
 
133
                ACPI_DUMP_STACK_ENTRY (source_desc);
134
                ACPI_DUMP_STACK_ENTRY (dest_desc);
135
                ACPI_DUMP_OPERANDS (&dest_desc, ACPI_IMODE_EXECUTE, "ex_store",
136
                                  2, "Target is not a Reference or Constant object");
137
 
138
                return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
139
        }
140
 
141
        /*
142
         * Examine the Reference opcode.  These cases are handled:
143
         *
144
         * 1) Store to Name (Change the object associated with a name)
145
         * 2) Store to an indexed area of a Buffer or Package
146
         * 3) Store to a Method Local or Arg
147
         * 4) Store to the debug object
148
         */
149
        switch (ref_desc->reference.opcode) {
150
        case AML_NAME_OP:
151
        case AML_REF_OF_OP:
152
 
153
                /* Storing an object into a Name "container" */
154
 
155
                status = acpi_ex_store_object_to_node (source_desc, ref_desc->reference.object,
156
                                  walk_state);
157
                break;
158
 
159
 
160
        case AML_INDEX_OP:
161
 
162
                /* Storing to an Index (pointer into a packager or buffer) */
163
 
164
                status = acpi_ex_store_object_to_index (source_desc, ref_desc, walk_state);
165
                break;
166
 
167
 
168
        case AML_LOCAL_OP:
169
        case AML_ARG_OP:
170
 
171
                /* Store to a method local/arg  */
172
 
173
                status = acpi_ds_store_object_to_local (ref_desc->reference.opcode,
174
                                  ref_desc->reference.offset, source_desc, walk_state);
175
                break;
176
 
177
 
178
        case AML_DEBUG_OP:
179
 
180
                /*
181
                 * Storing to the Debug object causes the value stored to be
182
                 * displayed and otherwise has no effect -- see ACPI Specification
183
                 */
184
                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "**** Write to Debug Object: ****:\n\n"));
185
 
186
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %s: ",
187
                                  acpi_ut_get_object_type_name (source_desc)));
188
 
189
                switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
190
                case ACPI_TYPE_INTEGER:
191
 
192
                        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X%8.8X\n",
193
                                        ACPI_FORMAT_UINT64 (source_desc->integer.value)));
194
                        break;
195
 
196
 
197
                case ACPI_TYPE_BUFFER:
198
 
199
                        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Length 0x%.2X",
200
                                        (u32) source_desc->buffer.length));
201
                        ACPI_DUMP_BUFFER (source_desc->buffer.pointer,
202
                                (source_desc->buffer.length < 32) ? source_desc->buffer.length : 32);
203
                        break;
204
 
205
 
206
                case ACPI_TYPE_STRING:
207
 
208
                        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Length 0x%.2X, \"%s\"\n",
209
                                        source_desc->string.length, source_desc->string.pointer));
210
                        break;
211
 
212
 
213
                case ACPI_TYPE_PACKAGE:
214
 
215
                        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Size 0x%.2X Elements Ptr - %p\n",
216
                                        source_desc->package.count, source_desc->package.elements));
217
                        break;
218
 
219
 
220
                default:
221
 
222
                        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%p\n",
223
                                        source_desc));
224
                        break;
225
                }
226
 
227
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
228
                break;
229
 
230
 
231
        default:
232
 
233
                ACPI_REPORT_ERROR (("ex_store: Unknown Reference opcode %X\n",
234
                        ref_desc->reference.opcode));
235
                ACPI_DUMP_ENTRY (ref_desc, ACPI_LV_ERROR);
236
 
237
                status = AE_AML_INTERNAL;
238
                break;
239
        }
240
 
241
        return_ACPI_STATUS (status);
242
}
243
 
244
 
245
/*******************************************************************************
246
 *
247
 * FUNCTION:    acpi_ex_store_object_to_index
248
 *
249
 * PARAMETERS:  *source_desc            - Value to be stored
250
 *              *dest_desc              - Named object to receive the value
251
 *              walk_state              - Current walk state
252
 *
253
 * RETURN:      Status
254
 *
255
 * DESCRIPTION: Store the object to indexed Buffer or Package element
256
 *
257
 ******************************************************************************/
258
 
259
acpi_status
260
acpi_ex_store_object_to_index (
261
        union acpi_operand_object       *source_desc,
262
        union acpi_operand_object       *index_desc,
263
        struct acpi_walk_state          *walk_state)
264
{
265
        acpi_status                     status = AE_OK;
266
        union acpi_operand_object       *obj_desc;
267
        union acpi_operand_object       *new_desc;
268
        u8                              value = 0;
269
        u32                             i;
270
 
271
 
272
        ACPI_FUNCTION_TRACE ("ex_store_object_to_index");
273
 
274
 
275
        /*
276
         * Destination must be a reference pointer, and
277
         * must point to either a buffer or a package
278
         */
279
        switch (index_desc->reference.target_type) {
280
        case ACPI_TYPE_PACKAGE:
281
                /*
282
                 * Storing to a package element is not simple.  The source must be
283
                 * evaluated and converted to the type of the destination and then the
284
                 * source is copied into the destination - we can't just point to the
285
                 * source object.
286
                 */
287
                /*
288
                 * The object at *(index_desc->Reference.Where) is the
289
                 * element within the package that is to be modified.
290
                 * The parent package object is at index_desc->Reference.Object
291
                 */
292
                obj_desc = *(index_desc->reference.where);
293
 
294
                /* Do the conversion/store */
295
 
296
                status = acpi_ex_store_object_to_object (source_desc, obj_desc, &new_desc,
297
                                  walk_state);
298
                if (ACPI_FAILURE (status)) {
299
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
300
                                "Could not store object to indexed package element\n"));
301
                        return_ACPI_STATUS (status);
302
                }
303
 
304
                /*
305
                 * If a new object was created, we must install it as the new
306
                 * package element
307
                 */
308
                if (new_desc != obj_desc) {
309
                        acpi_ut_remove_reference (obj_desc);
310
                        *(index_desc->reference.where) = new_desc;
311
 
312
                        /* If same as the original source, add a reference */
313
 
314
                        if (new_desc == source_desc) {
315
                                acpi_ut_add_reference (new_desc);
316
                        }
317
 
318
                        /* Increment reference count by the ref count of the parent package -1 */
319
 
320
                        for (i = 1; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) {
321
                                acpi_ut_add_reference (new_desc);
322
                        }
323
                }
324
                break;
325
 
326
 
327
        case ACPI_TYPE_BUFFER_FIELD:
328
 
329
                /*
330
                 * Store into a Buffer (not actually a real buffer_field) at a
331
                 * location defined by an Index.
332
                 *
333
                 * The first 8-bit element of the source object is written to the
334
                 * 8-bit Buffer location defined by the Index destination object,
335
                 * according to the ACPI 2.0 specification.
336
                 */
337
 
338
                /*
339
                 * Make sure the target is a Buffer
340
                 */
341
                obj_desc = index_desc->reference.object;
342
                if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_BUFFER) {
343
                        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
344
                }
345
 
346
                /*
347
                 * The assignment of the individual elements will be slightly
348
                 * different for each source type.
349
                 */
350
                switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
351
                case ACPI_TYPE_INTEGER:
352
 
353
                        /* Use the least-significant byte of the integer */
354
 
355
                        value = (u8) (source_desc->integer.value);
356
                        break;
357
 
358
                case ACPI_TYPE_BUFFER:
359
 
360
                        value = source_desc->buffer.pointer[0];
361
                        break;
362
 
363
                case ACPI_TYPE_STRING:
364
 
365
                        value = (u8) source_desc->string.pointer[0];
366
                        break;
367
 
368
                default:
369
 
370
                        /* All other types are invalid */
371
 
372
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
373
                                "Source must be Integer/Buffer/String type, not %s\n",
374
                                acpi_ut_get_object_type_name (source_desc)));
375
                        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
376
                }
377
 
378
                /* Store the source value into the target buffer byte */
379
 
380
                obj_desc->buffer.pointer[index_desc->reference.offset] = value;
381
                break;
382
 
383
 
384
        default:
385
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
386
                        "Target is not a Package or buffer_field\n"));
387
                status = AE_AML_OPERAND_TYPE;
388
                break;
389
        }
390
 
391
        return_ACPI_STATUS (status);
392
}
393
 
394
 
395
/*******************************************************************************
396
 *
397
 * FUNCTION:    acpi_ex_store_object_to_node
398
 *
399
 * PARAMETERS:  source_desc             - Value to be stored
400
 *              Node                    - Named object to receive the value
401
 *              walk_state              - Current walk state
402
 *
403
 * RETURN:      Status
404
 *
405
 * DESCRIPTION: Store the object to the named object.
406
 *
407
 *              The Assignment of an object to a named object is handled here
408
 *              The value passed in will replace the current value (if any)
409
 *              with the input value.
410
 *
411
 *              When storing into an object the data is converted to the
412
 *              target object type then stored in the object.  This means
413
 *              that the target object type (for an initialized target) will
414
 *              not be changed by a store operation.
415
 *
416
 *              Assumes parameters are already validated.
417
 *
418
 ******************************************************************************/
419
 
420
acpi_status
421
acpi_ex_store_object_to_node (
422
        union acpi_operand_object       *source_desc,
423
        struct acpi_namespace_node      *node,
424
        struct acpi_walk_state          *walk_state)
425
{
426
        acpi_status                     status = AE_OK;
427
        union acpi_operand_object       *target_desc;
428
        union acpi_operand_object       *new_desc;
429
        acpi_object_type                target_type;
430
 
431
 
432
        ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_node", source_desc);
433
 
434
 
435
        /*
436
         * Get current type of the node, and object attached to Node
437
         */
438
        target_type = acpi_ns_get_type (node);
439
        target_desc = acpi_ns_get_attached_object (node);
440
 
441
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n",
442
                source_desc, acpi_ut_get_object_type_name (source_desc),
443
                          node, acpi_ut_get_type_name (target_type)));
444
 
445
        /*
446
         * Resolve the source object to an actual value
447
         * (If it is a reference object)
448
         */
449
        status = acpi_ex_resolve_object (&source_desc, target_type, walk_state);
450
        if (ACPI_FAILURE (status)) {
451
                return_ACPI_STATUS (status);
452
        }
453
 
454
        /*
455
         * Do the actual store operation
456
         */
457
        switch (target_type) {
458
        case ACPI_TYPE_BUFFER_FIELD:
459
        case ACPI_TYPE_LOCAL_REGION_FIELD:
460
        case ACPI_TYPE_LOCAL_BANK_FIELD:
461
        case ACPI_TYPE_LOCAL_INDEX_FIELD:
462
 
463
                /*
464
                 * For fields, copy the source data to the target field.
465
                 */
466
                status = acpi_ex_write_data_to_field (source_desc, target_desc, &walk_state->result_obj);
467
                break;
468
 
469
 
470
        case ACPI_TYPE_INTEGER:
471
        case ACPI_TYPE_STRING:
472
        case ACPI_TYPE_BUFFER:
473
 
474
                /*
475
                 * These target types are all of type Integer/String/Buffer, and
476
                 * therefore support implicit conversion before the store.
477
                 *
478
                 * Copy and/or convert the source object to a new target object
479
                 */
480
                status = acpi_ex_store_object_to_object (source_desc, target_desc, &new_desc, walk_state);
481
                if (ACPI_FAILURE (status)) {
482
                        return_ACPI_STATUS (status);
483
                }
484
 
485
                if (new_desc != target_desc) {
486
                        /*
487
                         * Store the new new_desc as the new value of the Name, and set
488
                         * the Name's type to that of the value being stored in it.
489
                         * source_desc reference count is incremented by attach_object.
490
                         *
491
                         * Note: This may change the type of the node if an explicit store
492
                         * has been performed such that the node/object type has been
493
                         * changed.
494
                         */
495
                        status = acpi_ns_attach_object (node, new_desc, new_desc->common.type);
496
 
497
                        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
498
                                "Store %s into %s via Convert/Attach\n",
499
                                acpi_ut_get_object_type_name (source_desc),
500
                                acpi_ut_get_object_type_name (new_desc)));
501
                }
502
                break;
503
 
504
 
505
        default:
506
 
507
                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
508
                        "Storing %s (%p) directly into node (%p), no implicit conversion\n",
509
                        acpi_ut_get_object_type_name (source_desc), source_desc, node));
510
 
511
                /* No conversions for all other types.  Just attach the source object */
512
 
513
                status = acpi_ns_attach_object (node, source_desc, ACPI_GET_OBJECT_TYPE (source_desc));
514
                break;
515
        }
516
 
517
        return_ACPI_STATUS (status);
518
}
519
 
520
 

powered by: WebSVN 2.1.0

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