exstorob.c revision 73561
1
2/******************************************************************************
3 *
4 * Module Name: amstorob - AML Interpreter object store support, store to object
5 *              $Revision: 23 $
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     * If target is a buffer of length zero, allocate a new
164     * buffer of the proper length
165     */
166    if (TargetDesc->Buffer.Length == 0)
167    {
168        TargetDesc->Buffer.Pointer = AcpiCmAllocate (Length);
169        if (!TargetDesc->Buffer.Pointer)
170        {
171            return (AE_NO_MEMORY);
172        }
173
174        TargetDesc->Buffer.Length = Length;
175    }
176
177    /*
178     * Buffer is a static allocation,
179     * only place what will fit in the buffer.
180     */
181    if (Length <= TargetDesc->Buffer.Length)
182    {
183        /* Clear existing buffer and copy in the new one */
184
185        MEMSET(TargetDesc->Buffer.Pointer, 0, TargetDesc->Buffer.Length);
186        MEMCPY(TargetDesc->Buffer.Pointer, Buffer, Length);
187    }
188
189    else
190    {
191        /*
192         * Truncate the source, copy only what will fit
193         */
194        MEMCPY(TargetDesc->Buffer.Pointer, Buffer, TargetDesc->Buffer.Length);
195
196        DEBUG_PRINT (ACPI_INFO,
197            ("AmlCopyBufferToBuffer: Truncating src buffer from %X to %X\n",
198            Length, TargetDesc->Buffer.Length));
199    }
200
201    return (AE_OK);
202}
203
204
205
206
207/*******************************************************************************
208 *
209 * FUNCTION:    AcpiAmlCopyStringToString
210 *
211 * PARAMETERS:  SourceDesc          - Source object to copy
212 *              TargetDesc          - Destination object of the copy
213 *
214 * RETURN:      Status
215 *
216 * DESCRIPTION: Copy a String object to another String object
217 *
218 ******************************************************************************/
219
220ACPI_STATUS
221AcpiAmlCopyStringToString (
222    ACPI_OPERAND_OBJECT     *SourceDesc,
223    ACPI_OPERAND_OBJECT     *TargetDesc)
224{
225    UINT32                  Length;
226    UINT8                   *Buffer;
227
228
229    /*
230     * We know that SourceDesc is a string by now.
231     */
232    Buffer = (UINT8 *) SourceDesc->String.Pointer;
233    Length = SourceDesc->String.Length;
234
235    /*
236     * Setting a string value replaces the old string
237     */
238    if (Length < TargetDesc->String.Length)
239    {
240        /* Clear old string and copy in the new one */
241
242        MEMSET(TargetDesc->String.Pointer, 0, TargetDesc->String.Length);
243        MEMCPY(TargetDesc->String.Pointer, Buffer, Length);
244    }
245
246    else
247    {
248        /*
249         * Free the current buffer, then allocate a buffer
250         * large enough to hold the value
251         */
252        if (TargetDesc->String.Pointer &&
253            !AcpiTbSystemTablePointer (TargetDesc->String.Pointer))
254        {
255            /*
256             * Only free if not a pointer into the DSDT
257             */
258            AcpiCmFree(TargetDesc->String.Pointer);
259        }
260
261        TargetDesc->String.Pointer = AcpiCmAllocate (Length + 1);
262        if (!TargetDesc->String.Pointer)
263        {
264            return (AE_NO_MEMORY);
265        }
266        TargetDesc->String.Length = Length;
267
268
269        MEMCPY(TargetDesc->String.Pointer, Buffer, Length);
270    }
271
272    return (AE_OK);
273}
274
275
276
277
278
279/*******************************************************************************
280 *
281 * FUNCTION:    AcpiAmlCopyIntegerToIndexField
282 *
283 * PARAMETERS:  SourceDesc          - Source object to copy
284 *              TargetDesc          - Destination object of the copy
285 *
286 * RETURN:      Status
287 *
288 * DESCRIPTION: Write an Integer to an Index Field
289 *
290 ******************************************************************************/
291
292ACPI_STATUS
293AcpiAmlCopyIntegerToIndexField (
294    ACPI_OPERAND_OBJECT     *SourceDesc,
295    ACPI_OPERAND_OBJECT     *TargetDesc)
296{
297    ACPI_STATUS             Status;
298    BOOLEAN                 Locked;
299
300
301    /*
302     * Get the global lock if needed
303     */
304    Locked = AcpiAmlAcquireGlobalLock (TargetDesc->IndexField.LockRule);
305
306    /*
307     * Set Index value to select proper Data register
308     * perform the update (Set index)
309     */
310    Status = AcpiAmlAccessNamedField (ACPI_WRITE,
311                            TargetDesc->IndexField.Index,
312                            &TargetDesc->IndexField.Value,
313                            sizeof (TargetDesc->IndexField.Value));
314    if (ACPI_SUCCESS (Status))
315    {
316        /* SetIndex was successful, next set Data value */
317
318        Status = AcpiAmlAccessNamedField (ACPI_WRITE,
319                            TargetDesc->IndexField.Data,
320                            &SourceDesc->Integer.Value,
321                            sizeof (SourceDesc->Integer.Value));
322
323        DEBUG_PRINT (ACPI_INFO,
324            ("AmlCopyIntegerToIndexField: IndexField: set data returned %s\n",
325            AcpiCmFormatException (Status)));
326    }
327
328    else
329    {
330        DEBUG_PRINT (ACPI_INFO,
331            ("AmlCopyIntegerToIndexField: IndexField: set index returned %s\n",
332            AcpiCmFormatException (Status)));
333    }
334
335
336    /*
337     * Release global lock if we acquired it earlier
338     */
339    AcpiAmlReleaseGlobalLock (Locked);
340
341    return (Status);
342}
343
344
345
346/*******************************************************************************
347 *
348 * FUNCTION:    AcpiAmlCopyIntegerToBankField
349 *
350 * PARAMETERS:  SourceDesc          - Source object to copy
351 *              TargetDesc          - Destination object of the copy
352 *
353 * RETURN:      Status
354 *
355 * DESCRIPTION: Write an Integer to a Bank Field
356 *
357 ******************************************************************************/
358
359ACPI_STATUS
360AcpiAmlCopyIntegerToBankField (
361    ACPI_OPERAND_OBJECT     *SourceDesc,
362    ACPI_OPERAND_OBJECT     *TargetDesc)
363{
364    ACPI_STATUS             Status;
365    BOOLEAN                 Locked;
366
367
368    /*
369     * Get the global lock if needed
370     */
371    Locked = AcpiAmlAcquireGlobalLock (TargetDesc->IndexField.LockRule);
372
373
374
375    /*
376     * Set Bank value to select proper Bank
377     * Perform the update (Set Bank Select)
378     */
379
380    Status = AcpiAmlAccessNamedField (ACPI_WRITE,
381                            TargetDesc->BankField.BankSelect,
382                            &TargetDesc->BankField.Value,
383                            sizeof (TargetDesc->BankField.Value));
384    if (ACPI_SUCCESS (Status))
385    {
386        /* Set bank select successful, set data value  */
387
388        Status = AcpiAmlAccessNamedField (ACPI_WRITE,
389                            TargetDesc->BankField.BankSelect,
390                            &SourceDesc->BankField.Value,
391                            sizeof (SourceDesc->BankField.Value));
392    }
393
394    else
395    {
396        DEBUG_PRINT (ACPI_INFO,
397            ("AmlCopyIntegerToBankField: BankField: set bakn returned %s\n",
398            AcpiCmFormatException (Status)));
399    }
400
401
402    /*
403     * Release global lock if we acquired it earlier
404     */
405    AcpiAmlReleaseGlobalLock (Locked);
406
407    return (Status);
408}
409
410
411
412
413/*******************************************************************************
414 *
415 * FUNCTION:    AcpiAmlCopyDataToNamedField
416 *
417 * PARAMETERS:  SourceDesc          - Source object to copy
418 *              Node                - Destination Namespace node
419 *
420 * RETURN:      Status
421 *
422 * DESCRIPTION: Copy raw data to a Named Field.  No implicit conversion
423 *              is performed on the source object
424 *
425 ******************************************************************************/
426
427ACPI_STATUS
428AcpiAmlCopyDataToNamedField (
429    ACPI_OPERAND_OBJECT     *SourceDesc,
430    ACPI_NAMESPACE_NODE     *Node)
431{
432    ACPI_STATUS             Status;
433    BOOLEAN                 Locked;
434    UINT32                  Length;
435    UINT8                   *Buffer;
436
437
438    /*
439     * Named fields (CreateXxxField) - We don't perform any conversions on the
440     * source operand, just use the raw data
441     */
442    switch (SourceDesc->Common.Type)
443    {
444    case ACPI_TYPE_INTEGER:
445        Buffer = (UINT8 *) &SourceDesc->Integer.Value;
446        Length = sizeof (SourceDesc->Integer.Value);
447        break;
448
449    case ACPI_TYPE_BUFFER:
450        Buffer = (UINT8 *) SourceDesc->Buffer.Pointer;
451        Length = SourceDesc->Buffer.Length;
452        break;
453
454    case ACPI_TYPE_STRING:
455        Buffer = (UINT8 *) SourceDesc->String.Pointer;
456        Length = SourceDesc->String.Length;
457        break;
458
459    default:
460        return (AE_TYPE);
461    }
462
463    /*
464     * Get the global lock if needed before the update
465     * TBD: not needed!
466     */
467    Locked = AcpiAmlAcquireGlobalLock (SourceDesc->Field.LockRule);
468
469    Status = AcpiAmlAccessNamedField (ACPI_WRITE,
470                                Node, Buffer, Length);
471
472    AcpiAmlReleaseGlobalLock (Locked);
473
474    return (Status);
475}
476
477
478
479
480/*******************************************************************************
481 *
482 * FUNCTION:    AcpiAmlCopyIntegerToFieldUnit
483 *
484 * PARAMETERS:  SourceDesc          - Source object to copy
485 *              TargetDesc          - Destination object of the copy
486 *
487 * RETURN:      Status
488 *
489 * DESCRIPTION: Write an Integer to a Field Unit.
490 *
491 ******************************************************************************/
492
493ACPI_STATUS
494AcpiAmlCopyIntegerToFieldUnit (
495    ACPI_OPERAND_OBJECT     *SourceDesc,
496    ACPI_OPERAND_OBJECT     *TargetDesc)
497{
498    ACPI_STATUS             Status = AE_OK;
499    UINT8                   *Location = NULL;
500    UINT32                  Mask;
501    UINT32                  NewValue;
502    BOOLEAN                 Locked = FALSE;
503
504
505
506    FUNCTION_TRACE ("AmlCopyIntegerToFieldUnit");
507
508    /*
509     * If the Field Buffer and Index have not been previously evaluated,
510     * evaluate them and save the results.
511     */
512    if (!(TargetDesc->Common.Flags & AOPOBJ_DATA_VALID))
513    {
514        Status = AcpiDsGetFieldUnitArguments (TargetDesc);
515        if (ACPI_FAILURE (Status))
516        {
517            return_ACPI_STATUS (Status);
518        }
519    }
520
521    if ((!TargetDesc->FieldUnit.Container ||
522        ACPI_TYPE_BUFFER != TargetDesc->FieldUnit.Container->Common.Type))
523    {
524        DEBUG_PRINT (ACPI_ERROR,
525            ("Null Container or wrong type: %p", TargetDesc->FieldUnit.Container));
526
527        if (TargetDesc->FieldUnit.Container)
528        {
529            DEBUG_PRINT_RAW (ACPI_ERROR, (" Type %X",
530                TargetDesc->FieldUnit.Container->Common.Type));
531        }
532        DEBUG_PRINT_RAW (ACPI_ERROR, ("\n"));
533
534        return_ACPI_STATUS (AE_AML_INTERNAL);
535    }
536
537    /*
538     * Get the global lock if needed
539     */
540    Locked = AcpiAmlAcquireGlobalLock (TargetDesc->FieldUnit.LockRule);
541
542    /*
543     * TBD: [Unhandled] REMOVE this limitation
544     * Make sure the operation is within the limits of our implementation
545     * this is not a Spec limitation!!
546     */
547    if (TargetDesc->FieldUnit.Length + TargetDesc->FieldUnit.BitOffset > 32)
548    {
549        DEBUG_PRINT (ACPI_ERROR,
550            ("AmlCopyIntegerToFieldUnit: FieldUnit: Implementation limitation - Field exceeds UINT32\n"));
551        return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
552    }
553
554    /* Field location is (base of buffer) + (byte offset) */
555
556    Location = TargetDesc->FieldUnit.Container->Buffer.Pointer
557                    + TargetDesc->FieldUnit.Offset;
558
559    /*
560     * Construct Mask with 1 bits where the field is,
561     * 0 bits elsewhere
562     */
563    Mask = ((UINT32) 1 << TargetDesc->FieldUnit.Length) - ((UINT32)1
564                        << TargetDesc->FieldUnit.BitOffset);
565
566    DEBUG_PRINT (TRACE_EXEC,
567        ("** Store %lx in buffer %p byte %ld bit %X width %d addr %p mask %08lx\n",
568        SourceDesc->Integer.Value,
569        TargetDesc->FieldUnit.Container->Buffer.Pointer,
570        TargetDesc->FieldUnit.Offset, TargetDesc->FieldUnit.BitOffset,
571        TargetDesc->FieldUnit.Length,Location, Mask));
572
573    /* Zero out the field in the buffer */
574
575    MOVE_UNALIGNED32_TO_32 (&NewValue, Location);
576    NewValue &= ~Mask;
577
578    /*
579     * Shift and mask the new value into position,
580     * and or it into the buffer.
581     */
582    NewValue |= (SourceDesc->Integer.Value << TargetDesc->FieldUnit.BitOffset) &
583                Mask;
584
585    /* Store back the value */
586
587    MOVE_UNALIGNED32_TO_32 (Location, &NewValue);
588
589    DEBUG_PRINT (TRACE_EXEC, ("New Field value %08lx\n", NewValue));
590    return_ACPI_STATUS (AE_OK);
591}
592
593
594
595
596
597