exstorob.c revision 71867
1
2/******************************************************************************
3 *
4 * Module Name: amstorob - AML Interpreter object store support, store to object
5 *              $Revision: 22 $
6 *
7 *****************************************************************************/
8
9/******************************************************************************
10 *
11 * 1. Copyright Notice
12 *
13 * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
14 * All rights reserved.
15 *
16 * 2. License
17 *
18 * 2.1. This is your license from Intel Corp. under its intellectual property
19 * rights.  You may have additional license terms from the party that provided
20 * you this software, covering your right to use that party's intellectual
21 * property rights.
22 *
23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24 * copy of the source code appearing in this file ("Covered Code") an
25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26 * base code distributed originally by Intel ("Original Intel Code") to copy,
27 * make derivatives, distribute, use and display any portion of the Covered
28 * Code in any form, with the right to sublicense such rights; and
29 *
30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31 * license (with the right to sublicense), under only those claims of Intel
32 * patents that are infringed by the Original Intel Code, to make, use, sell,
33 * offer to sell, and import the Covered Code and derivative works thereof
34 * solely to the minimum extent necessary to exercise the above copyright
35 * license, and in no event shall the patent license extend to any additions
36 * to or modifications of the Original Intel Code.  No other license or right
37 * is granted directly or by implication, estoppel or otherwise;
38 *
39 * The above copyright and patent license is granted only if the following
40 * conditions are met:
41 *
42 * 3. Conditions
43 *
44 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45 * Redistribution of source code of any substantial portion of the Covered
46 * Code or modification with rights to further distribute source must include
47 * the above Copyright Notice, the above License, this list of Conditions,
48 * and the following Disclaimer and Export Compliance provision.  In addition,
49 * Licensee must cause all Covered Code to which Licensee contributes to
50 * contain a file documenting the changes Licensee made to create that Covered
51 * Code and the date of any change.  Licensee must include in that file the
52 * documentation of any changes made by any predecessor Licensee.  Licensee
53 * must include a prominent statement that the modification is derived,
54 * directly or indirectly, from Original Intel Code.
55 *
56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57 * Redistribution of source code of any substantial portion of the Covered
58 * Code or modification without rights to further distribute source must
59 * include the following Disclaimer and Export Compliance provision in the
60 * documentation and/or other materials provided with distribution.  In
61 * addition, Licensee may not authorize further sublicense of source of any
62 * portion of the Covered Code, and must include terms to the effect that the
63 * license from Licensee to its licensee is limited to the intellectual
64 * property embodied in the software Licensee provides to its licensee, and
65 * not to intellectual property embodied in modifications its licensee may
66 * make.
67 *
68 * 3.3. Redistribution of Executable. Redistribution in executable form of any
69 * substantial portion of the Covered Code or modification must reproduce the
70 * above Copyright Notice, and the following Disclaimer and Export Compliance
71 * provision in the documentation and/or other materials provided with the
72 * distribution.
73 *
74 * 3.4. Intel retains all right, title, and interest in and to the Original
75 * Intel Code.
76 *
77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78 * Intel shall be used in advertising or otherwise to promote the sale, use or
79 * other dealings in products derived from or relating to the Covered Code
80 * without prior written authorization from Intel.
81 *
82 * 4. Disclaimer and Export Compliance
83 *
84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90 * PARTICULAR PURPOSE.
91 *
92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99 * LIMITED REMEDY.
100 *
101 * 4.3. Licensee shall not export, either directly or indirectly, any of this
102 * software or system incorporating such software without first obtaining any
103 * required license or other approval from the U. S. Department of Commerce or
104 * any other agency or department of the United States Government.  In the
105 * event Licensee exports any such software from the United States or
106 * re-exports any such software from a foreign destination, Licensee shall
107 * ensure that the distribution and export/re-export of the software is in
108 * compliance with all laws, regulations, orders, or other restrictions of the
109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110 * any of its subsidiaries will export/re-export any technical data, process,
111 * software, or service, directly or indirectly, to any country for which the
112 * United States government or any agency thereof requires an export license,
113 * other governmental approval, or letter of assurance, without first obtaining
114 * such license, approval or letter.
115 *
116 *****************************************************************************/
117
118#define __AMSTOROB_C__
119
120#include "acpi.h"
121#include "acparser.h"
122#include "acdispat.h"
123#include "acinterp.h"
124#include "amlcode.h"
125#include "acnamesp.h"
126#include "actables.h"
127
128
129#define _COMPONENT          INTERPRETER
130        MODULE_NAME         ("amstorob")
131
132
133
134/*******************************************************************************
135 *
136 * FUNCTION:    AcpiAmlCopyBufferToBuffer
137 *
138 * PARAMETERS:  SourceDesc          - Source object to copy
139 *              TargetDesc          - Destination object of the copy
140 *
141 * RETURN:      Status
142 *
143 * DESCRIPTION: Copy a buffer object to another buffer object.
144 *
145 ******************************************************************************/
146
147ACPI_STATUS
148AcpiAmlCopyBufferToBuffer (
149    ACPI_OPERAND_OBJECT     *SourceDesc,
150    ACPI_OPERAND_OBJECT     *TargetDesc)
151{
152    UINT32                  Length;
153    UINT8                   *Buffer;
154
155
156    /*
157     * We know that SourceDesc is a buffer by now
158     */
159    Buffer = (UINT8 *) SourceDesc->Buffer.Pointer;
160    Length = SourceDesc->Buffer.Length;
161
162    /*
163     * Buffer is a static allocation,
164     * only place what will fit in the buffer.
165     */
166    if (Length <= TargetDesc->Buffer.Length)
167    {
168        /* Clear existing buffer and copy in the new one */
169
170        MEMSET(TargetDesc->Buffer.Pointer, 0, TargetDesc->Buffer.Length);
171        MEMCPY(TargetDesc->Buffer.Pointer, Buffer, Length);
172    }
173
174    else
175    {
176        /*
177         * Truncate the source, copy only what will fit
178         */
179        MEMCPY(TargetDesc->Buffer.Pointer, Buffer, TargetDesc->Buffer.Length);
180
181        DEBUG_PRINT (ACPI_INFO,
182            ("AmlStoreObjectToNode: Truncating src buffer from %X to %X\n",
183            Length, TargetDesc->Buffer.Length));
184    }
185
186    return (AE_OK);
187}
188
189
190
191
192/*******************************************************************************
193 *
194 * FUNCTION:    AcpiAmlCopyStringToString
195 *
196 * PARAMETERS:  SourceDesc          - Source object to copy
197 *              TargetDesc          - Destination object of the copy
198 *
199 * RETURN:      Status
200 *
201 * DESCRIPTION: Copy a String object to another String object
202 *
203 ******************************************************************************/
204
205ACPI_STATUS
206AcpiAmlCopyStringToString (
207    ACPI_OPERAND_OBJECT     *SourceDesc,
208    ACPI_OPERAND_OBJECT     *TargetDesc)
209{
210    UINT32                  Length;
211    UINT8                   *Buffer;
212
213
214    /*
215     * We know that SourceDesc is a string by now.
216     */
217    Buffer = (UINT8 *) SourceDesc->String.Pointer;
218    Length = SourceDesc->String.Length;
219
220    /*
221     * Setting a string value replaces the old string
222     */
223    if (Length < TargetDesc->String.Length)
224    {
225        /* Clear old string and copy in the new one */
226
227        MEMSET(TargetDesc->String.Pointer, 0, TargetDesc->String.Length);
228        MEMCPY(TargetDesc->String.Pointer, Buffer, Length);
229    }
230
231    else
232    {
233        /*
234         * Free the current buffer, then allocate a buffer
235         * large enough to hold the value
236         */
237        if (TargetDesc->String.Pointer &&
238            !AcpiTbSystemTablePointer (TargetDesc->String.Pointer))
239        {
240            /*
241             * Only free if not a pointer into the DSDT
242             */
243            AcpiCmFree(TargetDesc->String.Pointer);
244        }
245
246        TargetDesc->String.Pointer = AcpiCmAllocate (Length + 1);
247        TargetDesc->String.Length = Length;
248
249        if (!TargetDesc->String.Pointer)
250        {
251            return (AE_NO_MEMORY);
252        }
253
254        MEMCPY(TargetDesc->String.Pointer, Buffer, Length);
255    }
256
257    return (AE_OK);
258}
259
260
261
262
263
264/*******************************************************************************
265 *
266 * FUNCTION:    AcpiAmlCopyIntegerToIndexField
267 *
268 * PARAMETERS:  SourceDesc          - Source object to copy
269 *              TargetDesc          - Destination object of the copy
270 *
271 * RETURN:      Status
272 *
273 * DESCRIPTION: Write an Integer to an Index Field
274 *
275 ******************************************************************************/
276
277ACPI_STATUS
278AcpiAmlCopyIntegerToIndexField (
279    ACPI_OPERAND_OBJECT     *SourceDesc,
280    ACPI_OPERAND_OBJECT     *TargetDesc)
281{
282    ACPI_STATUS             Status;
283    BOOLEAN                 Locked;
284
285
286    /*
287     * Get the global lock if needed
288     */
289    Locked = AcpiAmlAcquireGlobalLock (TargetDesc->IndexField.LockRule);
290
291    /*
292     * Set Index value to select proper Data register
293     * perform the update (Set index)
294     */
295    Status = AcpiAmlAccessNamedField (ACPI_WRITE,
296                            TargetDesc->IndexField.Index,
297                            &TargetDesc->IndexField.Value,
298                            sizeof (TargetDesc->IndexField.Value));
299    if (ACPI_SUCCESS (Status))
300    {
301        /* SetIndex was successful, next set Data value */
302
303        Status = AcpiAmlAccessNamedField (ACPI_WRITE,
304                            TargetDesc->IndexField.Data,
305                            &SourceDesc->Integer.Value,
306                            sizeof (SourceDesc->Integer.Value));
307
308        DEBUG_PRINT (ACPI_INFO,
309            ("AmlStoreObjectToNode: IndexField: set data returned %s\n",
310            AcpiCmFormatException (Status)));
311    }
312
313    else
314    {
315        DEBUG_PRINT (ACPI_INFO,
316            ("AmlStoreObjectToNode: IndexField: set index returned %s\n",
317            AcpiCmFormatException (Status)));
318    }
319
320
321    /*
322     * Release global lock if we acquired it earlier
323     */
324    AcpiAmlReleaseGlobalLock (Locked);
325
326    return (Status);
327}
328
329
330
331/*******************************************************************************
332 *
333 * FUNCTION:    AcpiAmlCopyIntegerToBankField
334 *
335 * PARAMETERS:  SourceDesc          - Source object to copy
336 *              TargetDesc          - Destination object of the copy
337 *
338 * RETURN:      Status
339 *
340 * DESCRIPTION: Write an Integer to a Bank Field
341 *
342 ******************************************************************************/
343
344ACPI_STATUS
345AcpiAmlCopyIntegerToBankField (
346    ACPI_OPERAND_OBJECT     *SourceDesc,
347    ACPI_OPERAND_OBJECT     *TargetDesc)
348{
349    ACPI_STATUS             Status;
350    BOOLEAN                 Locked;
351
352
353    /*
354     * Get the global lock if needed
355     */
356    Locked = AcpiAmlAcquireGlobalLock (TargetDesc->IndexField.LockRule);
357
358
359
360    /*
361     * Set Bank value to select proper Bank
362     * Perform the update (Set Bank Select)
363     */
364
365    Status = AcpiAmlAccessNamedField (ACPI_WRITE,
366                            TargetDesc->BankField.BankSelect,
367                            &TargetDesc->BankField.Value,
368                            sizeof (TargetDesc->BankField.Value));
369    if (ACPI_SUCCESS (Status))
370    {
371        /* Set bank select successful, set data value  */
372
373        Status = AcpiAmlAccessNamedField (ACPI_WRITE,
374                            TargetDesc->BankField.BankSelect,
375                            &SourceDesc->BankField.Value,
376                            sizeof (SourceDesc->BankField.Value));
377    }
378
379    else
380    {
381        DEBUG_PRINT (ACPI_INFO,
382            ("AmlStoreObjectToNode: BankField: set bakn returned %s\n",
383            AcpiCmFormatException (Status)));
384    }
385
386
387    /*
388     * Release global lock if we acquired it earlier
389     */
390    AcpiAmlReleaseGlobalLock (Locked);
391
392    return (Status);
393}
394
395
396
397
398/*******************************************************************************
399 *
400 * FUNCTION:    AcpiAmlCopyDataToNamedField
401 *
402 * PARAMETERS:  SourceDesc          - Source object to copy
403 *              Node                - Destination Namespace node
404 *
405 * RETURN:      Status
406 *
407 * DESCRIPTION: Copy raw data to a Named Field.  No implicit conversion
408 *              is performed on the source object
409 *
410 ******************************************************************************/
411
412ACPI_STATUS
413AcpiAmlCopyDataToNamedField (
414    ACPI_OPERAND_OBJECT     *SourceDesc,
415    ACPI_NAMESPACE_NODE     *Node)
416{
417    ACPI_STATUS             Status;
418    BOOLEAN                 Locked;
419    UINT32                  Length;
420    UINT8                   *Buffer;
421
422
423    /*
424     * Named fields (CreateXxxField) - We don't perform any conversions on the
425     * source operand, just use the raw data
426     */
427    switch (SourceDesc->Common.Type)
428    {
429    case ACPI_TYPE_INTEGER:
430        Buffer = (UINT8 *) &SourceDesc->Integer.Value;
431        Length = sizeof (SourceDesc->Integer.Value);
432        break;
433
434    case ACPI_TYPE_BUFFER:
435        Buffer = (UINT8 *) SourceDesc->Buffer.Pointer;
436        Length = SourceDesc->Buffer.Length;
437        break;
438
439    case ACPI_TYPE_STRING:
440        Buffer = (UINT8 *) SourceDesc->String.Pointer;
441        Length = SourceDesc->String.Length;
442        break;
443
444    default:
445        return (AE_TYPE);
446    }
447
448    /*
449     * Get the global lock if needed before the update
450     * TBD: not needed!
451     */
452    Locked = AcpiAmlAcquireGlobalLock (SourceDesc->Field.LockRule);
453
454    Status = AcpiAmlAccessNamedField (ACPI_WRITE,
455                                Node, Buffer, Length);
456
457    AcpiAmlReleaseGlobalLock (Locked);
458
459    return (Status);
460}
461
462
463
464
465/*******************************************************************************
466 *
467 * FUNCTION:    AcpiAmlCopyIntegerToFieldUnit
468 *
469 * PARAMETERS:  SourceDesc          - Source object to copy
470 *              TargetDesc          - Destination object of the copy
471 *
472 * RETURN:      Status
473 *
474 * DESCRIPTION: Write an Integer to a Field Unit.
475 *
476 ******************************************************************************/
477
478ACPI_STATUS
479AcpiAmlCopyIntegerToFieldUnit (
480    ACPI_OPERAND_OBJECT     *SourceDesc,
481    ACPI_OPERAND_OBJECT     *TargetDesc)
482{
483    ACPI_STATUS             Status = AE_OK;
484    UINT8                   *Location = NULL;
485    UINT32                  Mask;
486    UINT32                  NewValue;
487    BOOLEAN                 Locked = FALSE;
488
489
490
491    FUNCTION_TRACE ("AmlCopyIntegerToFieldUnit");
492
493    /*
494     * If the Field Buffer and Index have not been previously evaluated,
495     * evaluate them and save the results.
496     */
497    if (!(TargetDesc->Common.Flags & AOPOBJ_DATA_VALID))
498    {
499        Status = AcpiDsGetFieldUnitArguments (TargetDesc);
500        if (ACPI_FAILURE (Status))
501        {
502            return_ACPI_STATUS (Status);
503        }
504    }
505
506    if ((!TargetDesc->FieldUnit.Container ||
507        ACPI_TYPE_BUFFER != TargetDesc->FieldUnit.Container->Common.Type))
508    {
509        DEBUG_PRINT (ACPI_ERROR,
510            ("Null Container or wrong type: %p", TargetDesc->FieldUnit.Container));
511
512        if (TargetDesc->FieldUnit.Container)
513        {
514            DEBUG_PRINT_RAW (ACPI_ERROR, (" Type %X",
515                TargetDesc->FieldUnit.Container->Common.Type));
516        }
517        DEBUG_PRINT_RAW (ACPI_ERROR, ("\n"));
518
519        return_ACPI_STATUS (AE_AML_INTERNAL);
520    }
521
522    /*
523     * Get the global lock if needed
524     */
525    Locked = AcpiAmlAcquireGlobalLock (TargetDesc->FieldUnit.LockRule);
526
527    /*
528     * TBD: [Unhandled] REMOVE this limitation
529     * Make sure the operation is within the limits of our implementation
530     * this is not a Spec limitation!!
531     */
532    if (TargetDesc->FieldUnit.Length + TargetDesc->FieldUnit.BitOffset > 32)
533    {
534        DEBUG_PRINT (ACPI_ERROR,
535            ("AmlCopyIntegerToFieldUnit: FieldUnit: Implementation limitation - Field exceeds UINT32\n"));
536        return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
537    }
538
539    /* Field location is (base of buffer) + (byte offset) */
540
541    Location = TargetDesc->FieldUnit.Container->Buffer.Pointer
542                    + TargetDesc->FieldUnit.Offset;
543
544    /*
545     * Construct Mask with 1 bits where the field is,
546     * 0 bits elsewhere
547     */
548    Mask = ((UINT32) 1 << TargetDesc->FieldUnit.Length) - ((UINT32)1
549                        << TargetDesc->FieldUnit.BitOffset);
550
551    DEBUG_PRINT (TRACE_EXEC,
552        ("** Store %lx in buffer %p byte %ld bit %X width %d addr %p mask %08lx\n",
553        SourceDesc->Integer.Value,
554        TargetDesc->FieldUnit.Container->Buffer.Pointer,
555        TargetDesc->FieldUnit.Offset, TargetDesc->FieldUnit.BitOffset,
556        TargetDesc->FieldUnit.Length,Location, Mask));
557
558    /* Zero out the field in the buffer */
559
560    MOVE_UNALIGNED32_TO_32 (&NewValue, Location);
561    NewValue &= ~Mask;
562
563    /*
564     * Shift and mask the new value into position,
565     * and or it into the buffer.
566     */
567    NewValue |= (SourceDesc->Integer.Value << TargetDesc->FieldUnit.BitOffset) &
568                Mask;
569
570    /* Store back the value */
571
572    MOVE_UNALIGNED32_TO_32 (Location, &NewValue);
573
574    DEBUG_PRINT (TRACE_EXEC, ("New Field value %08lx\n", NewValue));
575    return_ACPI_STATUS (AE_OK);
576}
577
578
579
580
581
582