Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/acpica/components/utilities/utcopy.c
48406 views
1
/******************************************************************************
2
*
3
* Module Name: utcopy - Internal to external object translation utilities
4
*
5
*****************************************************************************/
6
7
/******************************************************************************
8
*
9
* 1. Copyright Notice
10
*
11
* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
12
* All rights reserved.
13
*
14
* 2. License
15
*
16
* 2.1. This is your license from Intel Corp. under its intellectual property
17
* rights. You may have additional license terms from the party that provided
18
* you this software, covering your right to use that party's intellectual
19
* property rights.
20
*
21
* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
* copy of the source code appearing in this file ("Covered Code") an
23
* irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
* base code distributed originally by Intel ("Original Intel Code") to copy,
25
* make derivatives, distribute, use and display any portion of the Covered
26
* Code in any form, with the right to sublicense such rights; and
27
*
28
* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
* license (with the right to sublicense), under only those claims of Intel
30
* patents that are infringed by the Original Intel Code, to make, use, sell,
31
* offer to sell, and import the Covered Code and derivative works thereof
32
* solely to the minimum extent necessary to exercise the above copyright
33
* license, and in no event shall the patent license extend to any additions
34
* to or modifications of the Original Intel Code. No other license or right
35
* is granted directly or by implication, estoppel or otherwise;
36
*
37
* The above copyright and patent license is granted only if the following
38
* conditions are met:
39
*
40
* 3. Conditions
41
*
42
* 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
* Redistribution of source code of any substantial portion of the Covered
44
* Code or modification with rights to further distribute source must include
45
* the above Copyright Notice, the above License, this list of Conditions,
46
* and the following Disclaimer and Export Compliance provision. In addition,
47
* Licensee must cause all Covered Code to which Licensee contributes to
48
* contain a file documenting the changes Licensee made to create that Covered
49
* Code and the date of any change. Licensee must include in that file the
50
* documentation of any changes made by any predecessor Licensee. Licensee
51
* must include a prominent statement that the modification is derived,
52
* directly or indirectly, from Original Intel Code.
53
*
54
* 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
* Redistribution of source code of any substantial portion of the Covered
56
* Code or modification without rights to further distribute source must
57
* include the following Disclaimer and Export Compliance provision in the
58
* documentation and/or other materials provided with distribution. In
59
* addition, Licensee may not authorize further sublicense of source of any
60
* portion of the Covered Code, and must include terms to the effect that the
61
* license from Licensee to its licensee is limited to the intellectual
62
* property embodied in the software Licensee provides to its licensee, and
63
* not to intellectual property embodied in modifications its licensee may
64
* make.
65
*
66
* 3.3. Redistribution of Executable. Redistribution in executable form of any
67
* substantial portion of the Covered Code or modification must reproduce the
68
* above Copyright Notice, and the following Disclaimer and Export Compliance
69
* provision in the documentation and/or other materials provided with the
70
* distribution.
71
*
72
* 3.4. Intel retains all right, title, and interest in and to the Original
73
* Intel Code.
74
*
75
* 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
* Intel shall be used in advertising or otherwise to promote the sale, use or
77
* other dealings in products derived from or relating to the Covered Code
78
* without prior written authorization from Intel.
79
*
80
* 4. Disclaimer and Export Compliance
81
*
82
* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85
* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86
* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87
* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
* PARTICULAR PURPOSE.
89
*
90
* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96
* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
* LIMITED REMEDY.
98
*
99
* 4.3. Licensee shall not export, either directly or indirectly, any of this
100
* software or system incorporating such software without first obtaining any
101
* required license or other approval from the U. S. Department of Commerce or
102
* any other agency or department of the United States Government. In the
103
* event Licensee exports any such software from the United States or
104
* re-exports any such software from a foreign destination, Licensee shall
105
* ensure that the distribution and export/re-export of the software is in
106
* compliance with all laws, regulations, orders, or other restrictions of the
107
* U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
* any of its subsidiaries will export/re-export any technical data, process,
109
* software, or service, directly or indirectly, to any country for which the
110
* United States government or any agency thereof requires an export license,
111
* other governmental approval, or letter of assurance, without first obtaining
112
* such license, approval or letter.
113
*
114
*****************************************************************************
115
*
116
* Alternatively, you may choose to be licensed under the terms of the
117
* following license:
118
*
119
* Redistribution and use in source and binary forms, with or without
120
* modification, are permitted provided that the following conditions
121
* are met:
122
* 1. Redistributions of source code must retain the above copyright
123
* notice, this list of conditions, and the following disclaimer,
124
* without modification.
125
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
126
* substantially similar to the "NO WARRANTY" disclaimer below
127
* ("Disclaimer") and any redistribution must be conditioned upon
128
* including a substantially similar Disclaimer requirement for further
129
* binary redistribution.
130
* 3. Neither the names of the above-listed copyright holders nor the names
131
* of any contributors may be used to endorse or promote products derived
132
* from this software without specific prior written permission.
133
*
134
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145
*
146
* Alternatively, you may choose to be licensed under the terms of the
147
* GNU General Public License ("GPL") version 2 as published by the Free
148
* Software Foundation.
149
*
150
*****************************************************************************/
151
152
#include <contrib/dev/acpica/include/acpi.h>
153
#include <contrib/dev/acpica/include/accommon.h>
154
#include <contrib/dev/acpica/include/acnamesp.h>
155
156
157
#define _COMPONENT ACPI_UTILITIES
158
ACPI_MODULE_NAME ("utcopy")
159
160
/* Local prototypes */
161
162
static ACPI_STATUS
163
AcpiUtCopyIsimpleToEsimple (
164
ACPI_OPERAND_OBJECT *InternalObject,
165
ACPI_OBJECT *ExternalObject,
166
UINT8 *DataSpace,
167
ACPI_SIZE *BufferSpaceUsed);
168
169
static ACPI_STATUS
170
AcpiUtCopyIelementToIelement (
171
UINT8 ObjectType,
172
ACPI_OPERAND_OBJECT *SourceObject,
173
ACPI_GENERIC_STATE *State,
174
void *Context);
175
176
static ACPI_STATUS
177
AcpiUtCopyIpackageToEpackage (
178
ACPI_OPERAND_OBJECT *InternalObject,
179
UINT8 *Buffer,
180
ACPI_SIZE *SpaceUsed);
181
182
static ACPI_STATUS
183
AcpiUtCopyEsimpleToIsimple(
184
ACPI_OBJECT *UserObj,
185
ACPI_OPERAND_OBJECT **ReturnObj);
186
187
static ACPI_STATUS
188
AcpiUtCopyEpackageToIpackage (
189
ACPI_OBJECT *ExternalObject,
190
ACPI_OPERAND_OBJECT **InternalObject);
191
192
static ACPI_STATUS
193
AcpiUtCopySimpleObject (
194
ACPI_OPERAND_OBJECT *SourceDesc,
195
ACPI_OPERAND_OBJECT *DestDesc);
196
197
static ACPI_STATUS
198
AcpiUtCopyIelementToEelement (
199
UINT8 ObjectType,
200
ACPI_OPERAND_OBJECT *SourceObject,
201
ACPI_GENERIC_STATE *State,
202
void *Context);
203
204
static ACPI_STATUS
205
AcpiUtCopyIpackageToIpackage (
206
ACPI_OPERAND_OBJECT *SourceObj,
207
ACPI_OPERAND_OBJECT *DestObj,
208
ACPI_WALK_STATE *WalkState);
209
210
211
/*******************************************************************************
212
*
213
* FUNCTION: AcpiUtCopyIsimpleToEsimple
214
*
215
* PARAMETERS: InternalObject - Source object to be copied
216
* ExternalObject - Where to return the copied object
217
* DataSpace - Where object data is returned (such as
218
* buffer and string data)
219
* BufferSpaceUsed - Length of DataSpace that was used
220
*
221
* RETURN: Status
222
*
223
* DESCRIPTION: This function is called to copy a simple internal object to
224
* an external object.
225
*
226
* The DataSpace buffer is assumed to have sufficient space for
227
* the object.
228
*
229
******************************************************************************/
230
231
static ACPI_STATUS
232
AcpiUtCopyIsimpleToEsimple (
233
ACPI_OPERAND_OBJECT *InternalObject,
234
ACPI_OBJECT *ExternalObject,
235
UINT8 *DataSpace,
236
ACPI_SIZE *BufferSpaceUsed)
237
{
238
ACPI_STATUS Status = AE_OK;
239
240
241
ACPI_FUNCTION_TRACE (UtCopyIsimpleToEsimple);
242
243
244
*BufferSpaceUsed = 0;
245
246
/*
247
* Check for NULL object case (could be an uninitialized
248
* package element)
249
*/
250
if (!InternalObject)
251
{
252
return_ACPI_STATUS (AE_OK);
253
}
254
255
/* Always clear the external object */
256
257
memset (ExternalObject, 0, sizeof (ACPI_OBJECT));
258
259
/*
260
* In general, the external object will be the same type as
261
* the internal object
262
*/
263
ExternalObject->Type = InternalObject->Common.Type;
264
265
/* However, only a limited number of external types are supported */
266
267
switch (InternalObject->Common.Type)
268
{
269
case ACPI_TYPE_STRING:
270
271
ExternalObject->String.Pointer = (char *) DataSpace;
272
ExternalObject->String.Length = InternalObject->String.Length;
273
*BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
274
(ACPI_SIZE) InternalObject->String.Length + 1);
275
276
memcpy ((void *) DataSpace,
277
(void *) InternalObject->String.Pointer,
278
(ACPI_SIZE) InternalObject->String.Length + 1);
279
break;
280
281
case ACPI_TYPE_BUFFER:
282
283
ExternalObject->Buffer.Pointer = DataSpace;
284
ExternalObject->Buffer.Length = InternalObject->Buffer.Length;
285
*BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
286
InternalObject->String.Length);
287
288
memcpy ((void *) DataSpace,
289
(void *) InternalObject->Buffer.Pointer,
290
InternalObject->Buffer.Length);
291
break;
292
293
case ACPI_TYPE_INTEGER:
294
295
ExternalObject->Integer.Value = InternalObject->Integer.Value;
296
break;
297
298
case ACPI_TYPE_LOCAL_REFERENCE:
299
300
/* This is an object reference. */
301
302
switch (InternalObject->Reference.Class)
303
{
304
case ACPI_REFCLASS_NAME:
305
/*
306
* For namepath, return the object handle ("reference")
307
* We are referring to the namespace node
308
*/
309
ExternalObject->Reference.Handle =
310
InternalObject->Reference.Node;
311
ExternalObject->Reference.ActualType =
312
AcpiNsGetType (InternalObject->Reference.Node);
313
break;
314
315
default:
316
317
/* All other reference types are unsupported */
318
319
return_ACPI_STATUS (AE_TYPE);
320
}
321
break;
322
323
case ACPI_TYPE_PROCESSOR:
324
325
ExternalObject->Processor.ProcId =
326
InternalObject->Processor.ProcId;
327
ExternalObject->Processor.PblkAddress =
328
InternalObject->Processor.Address;
329
ExternalObject->Processor.PblkLength =
330
InternalObject->Processor.Length;
331
break;
332
333
case ACPI_TYPE_POWER:
334
335
ExternalObject->PowerResource.SystemLevel =
336
InternalObject->PowerResource.SystemLevel;
337
338
ExternalObject->PowerResource.ResourceOrder =
339
InternalObject->PowerResource.ResourceOrder;
340
break;
341
342
default:
343
/*
344
* There is no corresponding external object type
345
*/
346
ACPI_ERROR ((AE_INFO,
347
"Unsupported object type, cannot convert to external object: %s",
348
AcpiUtGetTypeName (InternalObject->Common.Type)));
349
350
return_ACPI_STATUS (AE_SUPPORT);
351
}
352
353
return_ACPI_STATUS (Status);
354
}
355
356
357
/*******************************************************************************
358
*
359
* FUNCTION: AcpiUtCopyIelementToEelement
360
*
361
* PARAMETERS: ACPI_PKG_CALLBACK
362
*
363
* RETURN: Status
364
*
365
* DESCRIPTION: Copy one package element to another package element
366
*
367
******************************************************************************/
368
369
static ACPI_STATUS
370
AcpiUtCopyIelementToEelement (
371
UINT8 ObjectType,
372
ACPI_OPERAND_OBJECT *SourceObject,
373
ACPI_GENERIC_STATE *State,
374
void *Context)
375
{
376
ACPI_STATUS Status = AE_OK;
377
ACPI_PKG_INFO *Info = (ACPI_PKG_INFO *) Context;
378
ACPI_SIZE ObjectSpace;
379
UINT32 ThisIndex;
380
ACPI_OBJECT *TargetObject;
381
382
383
ACPI_FUNCTION_ENTRY ();
384
385
386
ThisIndex = State->Pkg.Index;
387
TargetObject = (ACPI_OBJECT *) &((ACPI_OBJECT *)
388
(State->Pkg.DestObject))->Package.Elements[ThisIndex];
389
390
switch (ObjectType)
391
{
392
case ACPI_COPY_TYPE_SIMPLE:
393
/*
394
* This is a simple or null object
395
*/
396
Status = AcpiUtCopyIsimpleToEsimple (SourceObject,
397
TargetObject, Info->FreeSpace, &ObjectSpace);
398
if (ACPI_FAILURE (Status))
399
{
400
return (Status);
401
}
402
break;
403
404
case ACPI_COPY_TYPE_PACKAGE:
405
/*
406
* Build the package object
407
*/
408
TargetObject->Type = ACPI_TYPE_PACKAGE;
409
TargetObject->Package.Count = SourceObject->Package.Count;
410
TargetObject->Package.Elements =
411
ACPI_CAST_PTR (ACPI_OBJECT, Info->FreeSpace);
412
413
/*
414
* Pass the new package object back to the package walk routine
415
*/
416
State->Pkg.ThisTargetObj = TargetObject;
417
418
/*
419
* Save space for the array of objects (Package elements)
420
* update the buffer length counter
421
*/
422
ObjectSpace = ACPI_ROUND_UP_TO_NATIVE_WORD (
423
(ACPI_SIZE) TargetObject->Package.Count *
424
sizeof (ACPI_OBJECT));
425
break;
426
427
default:
428
429
return (AE_BAD_PARAMETER);
430
}
431
432
Info->FreeSpace += ObjectSpace;
433
Info->Length += ObjectSpace;
434
return (Status);
435
}
436
437
438
/*******************************************************************************
439
*
440
* FUNCTION: AcpiUtCopyIpackageToEpackage
441
*
442
* PARAMETERS: InternalObject - Pointer to the object we are returning
443
* Buffer - Where the object is returned
444
* SpaceUsed - Where the object length is returned
445
*
446
* RETURN: Status
447
*
448
* DESCRIPTION: This function is called to place a package object in a user
449
* buffer. A package object by definition contains other objects.
450
*
451
* The buffer is assumed to have sufficient space for the object.
452
* The caller must have verified the buffer length needed using
453
* the AcpiUtGetObjectSize function before calling this function.
454
*
455
******************************************************************************/
456
457
static ACPI_STATUS
458
AcpiUtCopyIpackageToEpackage (
459
ACPI_OPERAND_OBJECT *InternalObject,
460
UINT8 *Buffer,
461
ACPI_SIZE *SpaceUsed)
462
{
463
ACPI_OBJECT *ExternalObject;
464
ACPI_STATUS Status;
465
ACPI_PKG_INFO Info;
466
467
468
ACPI_FUNCTION_TRACE (UtCopyIpackageToEpackage);
469
470
471
/*
472
* First package at head of the buffer
473
*/
474
ExternalObject = ACPI_CAST_PTR (ACPI_OBJECT, Buffer);
475
476
/*
477
* Free space begins right after the first package
478
*/
479
Info.Length = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
480
Info.FreeSpace = Buffer +
481
ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
482
Info.ObjectSpace = 0;
483
Info.NumPackages = 1;
484
485
ExternalObject->Type = InternalObject->Common.Type;
486
ExternalObject->Package.Count = InternalObject->Package.Count;
487
ExternalObject->Package.Elements =
488
ACPI_CAST_PTR (ACPI_OBJECT, Info.FreeSpace);
489
490
/*
491
* Leave room for an array of ACPI_OBJECTS in the buffer
492
* and move the free space past it
493
*/
494
Info.Length += (ACPI_SIZE) ExternalObject->Package.Count *
495
ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
496
Info.FreeSpace += ExternalObject->Package.Count *
497
ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
498
499
Status = AcpiUtWalkPackageTree (InternalObject, ExternalObject,
500
AcpiUtCopyIelementToEelement, &Info);
501
502
*SpaceUsed = Info.Length;
503
return_ACPI_STATUS (Status);
504
}
505
506
507
/*******************************************************************************
508
*
509
* FUNCTION: AcpiUtCopyIobjectToEobject
510
*
511
* PARAMETERS: InternalObject - The internal object to be converted
512
* RetBuffer - Where the object is returned
513
*
514
* RETURN: Status
515
*
516
* DESCRIPTION: This function is called to build an API object to be returned
517
* to the caller.
518
*
519
******************************************************************************/
520
521
ACPI_STATUS
522
AcpiUtCopyIobjectToEobject (
523
ACPI_OPERAND_OBJECT *InternalObject,
524
ACPI_BUFFER *RetBuffer)
525
{
526
ACPI_STATUS Status;
527
528
529
ACPI_FUNCTION_TRACE (UtCopyIobjectToEobject);
530
531
532
if (InternalObject->Common.Type == ACPI_TYPE_PACKAGE)
533
{
534
/*
535
* Package object: Copy all subobjects (including
536
* nested packages)
537
*/
538
Status = AcpiUtCopyIpackageToEpackage (InternalObject,
539
RetBuffer->Pointer, &RetBuffer->Length);
540
}
541
else
542
{
543
/*
544
* Build a simple object (no nested objects)
545
*/
546
Status = AcpiUtCopyIsimpleToEsimple (InternalObject,
547
ACPI_CAST_PTR (ACPI_OBJECT, RetBuffer->Pointer),
548
ACPI_ADD_PTR (UINT8, RetBuffer->Pointer,
549
ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT))),
550
&RetBuffer->Length);
551
/*
552
* build simple does not include the object size in the length
553
* so we add it in here
554
*/
555
RetBuffer->Length += sizeof (ACPI_OBJECT);
556
}
557
558
return_ACPI_STATUS (Status);
559
}
560
561
562
/*******************************************************************************
563
*
564
* FUNCTION: AcpiUtCopyEsimpleToIsimple
565
*
566
* PARAMETERS: ExternalObject - The external object to be converted
567
* RetInternalObject - Where the internal object is returned
568
*
569
* RETURN: Status
570
*
571
* DESCRIPTION: This function copies an external object to an internal one.
572
* NOTE: Pointers can be copied, we don't need to copy data.
573
* (The pointers have to be valid in our address space no matter
574
* what we do with them!)
575
*
576
******************************************************************************/
577
578
static ACPI_STATUS
579
AcpiUtCopyEsimpleToIsimple (
580
ACPI_OBJECT *ExternalObject,
581
ACPI_OPERAND_OBJECT **RetInternalObject)
582
{
583
ACPI_OPERAND_OBJECT *InternalObject;
584
585
586
ACPI_FUNCTION_TRACE (UtCopyEsimpleToIsimple);
587
588
589
/*
590
* Simple types supported are: String, Buffer, Integer
591
*/
592
switch (ExternalObject->Type)
593
{
594
case ACPI_TYPE_STRING:
595
case ACPI_TYPE_BUFFER:
596
case ACPI_TYPE_INTEGER:
597
case ACPI_TYPE_LOCAL_REFERENCE:
598
599
InternalObject = AcpiUtCreateInternalObject (
600
(UINT8) ExternalObject->Type);
601
if (!InternalObject)
602
{
603
return_ACPI_STATUS (AE_NO_MEMORY);
604
}
605
break;
606
607
case ACPI_TYPE_ANY: /* This is the case for a NULL object */
608
609
*RetInternalObject = NULL;
610
return_ACPI_STATUS (AE_OK);
611
612
default:
613
614
/* All other types are not supported */
615
616
ACPI_ERROR ((AE_INFO,
617
"Unsupported object type, cannot convert to internal object: %s",
618
AcpiUtGetTypeName (ExternalObject->Type)));
619
620
return_ACPI_STATUS (AE_SUPPORT);
621
}
622
623
624
/* Must COPY string and buffer contents */
625
626
switch (ExternalObject->Type)
627
{
628
case ACPI_TYPE_STRING:
629
630
InternalObject->String.Pointer =
631
ACPI_ALLOCATE_ZEROED ((ACPI_SIZE)
632
ExternalObject->String.Length + 1);
633
634
if (!InternalObject->String.Pointer)
635
{
636
goto ErrorExit;
637
}
638
639
memcpy (InternalObject->String.Pointer,
640
ExternalObject->String.Pointer,
641
ExternalObject->String.Length);
642
643
InternalObject->String.Length = ExternalObject->String.Length;
644
break;
645
646
case ACPI_TYPE_BUFFER:
647
648
InternalObject->Buffer.Pointer =
649
ACPI_ALLOCATE_ZEROED (ExternalObject->Buffer.Length);
650
if (!InternalObject->Buffer.Pointer)
651
{
652
goto ErrorExit;
653
}
654
655
memcpy (InternalObject->Buffer.Pointer,
656
ExternalObject->Buffer.Pointer,
657
ExternalObject->Buffer.Length);
658
659
InternalObject->Buffer.Length = ExternalObject->Buffer.Length;
660
661
/* Mark buffer data valid */
662
663
InternalObject->Buffer.Flags |= AOPOBJ_DATA_VALID;
664
break;
665
666
case ACPI_TYPE_INTEGER:
667
668
InternalObject->Integer.Value = ExternalObject->Integer.Value;
669
break;
670
671
case ACPI_TYPE_LOCAL_REFERENCE:
672
673
/* An incoming reference is defined to be a namespace node */
674
675
InternalObject->Reference.Class = ACPI_REFCLASS_REFOF;
676
InternalObject->Reference.Object = ExternalObject->Reference.Handle;
677
break;
678
679
default:
680
681
/* Other types can't get here */
682
683
break;
684
}
685
686
*RetInternalObject = InternalObject;
687
return_ACPI_STATUS (AE_OK);
688
689
690
ErrorExit:
691
AcpiUtRemoveReference (InternalObject);
692
return_ACPI_STATUS (AE_NO_MEMORY);
693
}
694
695
696
/*******************************************************************************
697
*
698
* FUNCTION: AcpiUtCopyEpackageToIpackage
699
*
700
* PARAMETERS: ExternalObject - The external object to be converted
701
* InternalObject - Where the internal object is returned
702
*
703
* RETURN: Status
704
*
705
* DESCRIPTION: Copy an external package object to an internal package.
706
* Handles nested packages.
707
*
708
******************************************************************************/
709
710
static ACPI_STATUS
711
AcpiUtCopyEpackageToIpackage (
712
ACPI_OBJECT *ExternalObject,
713
ACPI_OPERAND_OBJECT **InternalObject)
714
{
715
ACPI_STATUS Status = AE_OK;
716
ACPI_OPERAND_OBJECT *PackageObject;
717
ACPI_OPERAND_OBJECT **PackageElements;
718
UINT32 i;
719
720
721
ACPI_FUNCTION_TRACE (UtCopyEpackageToIpackage);
722
723
724
/* Create the package object */
725
726
PackageObject = AcpiUtCreatePackageObject (
727
ExternalObject->Package.Count);
728
if (!PackageObject)
729
{
730
return_ACPI_STATUS (AE_NO_MEMORY);
731
}
732
733
PackageElements = PackageObject->Package.Elements;
734
735
/*
736
* Recursive implementation. Probably ok, since nested external
737
* packages as parameters should be very rare.
738
*/
739
for (i = 0; i < ExternalObject->Package.Count; i++)
740
{
741
Status = AcpiUtCopyEobjectToIobject (
742
&ExternalObject->Package.Elements[i],
743
&PackageElements[i]);
744
if (ACPI_FAILURE (Status))
745
{
746
/* Truncate package and delete it */
747
748
PackageObject->Package.Count = i;
749
PackageElements[i] = NULL;
750
AcpiUtRemoveReference (PackageObject);
751
return_ACPI_STATUS (Status);
752
}
753
}
754
755
/* Mark package data valid */
756
757
PackageObject->Package.Flags |= AOPOBJ_DATA_VALID;
758
759
*InternalObject = PackageObject;
760
return_ACPI_STATUS (Status);
761
}
762
763
764
/*******************************************************************************
765
*
766
* FUNCTION: AcpiUtCopyEobjectToIobject
767
*
768
* PARAMETERS: ExternalObject - The external object to be converted
769
* InternalObject - Where the internal object is returned
770
*
771
* RETURN: Status
772
*
773
* DESCRIPTION: Converts an external object to an internal object.
774
*
775
******************************************************************************/
776
777
ACPI_STATUS
778
AcpiUtCopyEobjectToIobject (
779
ACPI_OBJECT *ExternalObject,
780
ACPI_OPERAND_OBJECT **InternalObject)
781
{
782
ACPI_STATUS Status;
783
784
785
ACPI_FUNCTION_TRACE (UtCopyEobjectToIobject);
786
787
788
if (ExternalObject->Type == ACPI_TYPE_PACKAGE)
789
{
790
Status = AcpiUtCopyEpackageToIpackage (
791
ExternalObject, InternalObject);
792
}
793
else
794
{
795
/*
796
* Build a simple object (no nested objects)
797
*/
798
Status = AcpiUtCopyEsimpleToIsimple (ExternalObject,
799
InternalObject);
800
}
801
802
return_ACPI_STATUS (Status);
803
}
804
805
806
/*******************************************************************************
807
*
808
* FUNCTION: AcpiUtCopySimpleObject
809
*
810
* PARAMETERS: SourceDesc - The internal object to be copied
811
* DestDesc - New target object
812
*
813
* RETURN: Status
814
*
815
* DESCRIPTION: Simple copy of one internal object to another. Reference count
816
* of the destination object is preserved.
817
*
818
******************************************************************************/
819
820
static ACPI_STATUS
821
AcpiUtCopySimpleObject (
822
ACPI_OPERAND_OBJECT *SourceDesc,
823
ACPI_OPERAND_OBJECT *DestDesc)
824
{
825
UINT16 ReferenceCount;
826
ACPI_OPERAND_OBJECT *NextObject;
827
ACPI_STATUS Status;
828
ACPI_SIZE CopySize;
829
830
831
/* Save fields from destination that we don't want to overwrite */
832
833
ReferenceCount = DestDesc->Common.ReferenceCount;
834
NextObject = DestDesc->Common.NextObject;
835
836
/*
837
* Copy the entire source object over the destination object.
838
* Note: Source can be either an operand object or namespace node.
839
*/
840
CopySize = sizeof (ACPI_OPERAND_OBJECT);
841
if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
842
{
843
CopySize = sizeof (ACPI_NAMESPACE_NODE);
844
}
845
846
memcpy (ACPI_CAST_PTR (char, DestDesc),
847
ACPI_CAST_PTR (char, SourceDesc), CopySize);
848
849
/* Restore the saved fields */
850
851
DestDesc->Common.ReferenceCount = ReferenceCount;
852
DestDesc->Common.NextObject = NextObject;
853
854
/* New object is not static, regardless of source */
855
856
DestDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER;
857
858
/* Handle the objects with extra data */
859
860
switch (DestDesc->Common.Type)
861
{
862
case ACPI_TYPE_BUFFER:
863
/*
864
* Allocate and copy the actual buffer if and only if:
865
* 1) There is a valid buffer pointer
866
* 2) The buffer has a length > 0
867
*/
868
if ((SourceDesc->Buffer.Pointer) &&
869
(SourceDesc->Buffer.Length))
870
{
871
DestDesc->Buffer.Pointer =
872
ACPI_ALLOCATE (SourceDesc->Buffer.Length);
873
if (!DestDesc->Buffer.Pointer)
874
{
875
return (AE_NO_MEMORY);
876
}
877
878
/* Copy the actual buffer data */
879
880
memcpy (DestDesc->Buffer.Pointer,
881
SourceDesc->Buffer.Pointer, SourceDesc->Buffer.Length);
882
}
883
break;
884
885
case ACPI_TYPE_STRING:
886
/*
887
* Allocate and copy the actual string if and only if:
888
* 1) There is a valid string pointer
889
* (Pointer to a NULL string is allowed)
890
*/
891
if (SourceDesc->String.Pointer)
892
{
893
DestDesc->String.Pointer =
894
ACPI_ALLOCATE ((ACPI_SIZE) SourceDesc->String.Length + 1);
895
if (!DestDesc->String.Pointer)
896
{
897
return (AE_NO_MEMORY);
898
}
899
900
/* Copy the actual string data */
901
902
memcpy (DestDesc->String.Pointer, SourceDesc->String.Pointer,
903
(ACPI_SIZE) SourceDesc->String.Length + 1);
904
}
905
break;
906
907
case ACPI_TYPE_LOCAL_REFERENCE:
908
/*
909
* We copied the reference object, so we now must add a reference
910
* to the object pointed to by the reference
911
*
912
* DDBHandle reference (from Load/LoadTable) is a special reference,
913
* it does not have a Reference.Object, so does not need to
914
* increase the reference count
915
*/
916
if (SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE)
917
{
918
break;
919
}
920
921
AcpiUtAddReference (SourceDesc->Reference.Object);
922
break;
923
924
case ACPI_TYPE_REGION:
925
/*
926
* We copied the Region Handler, so we now must add a reference
927
*/
928
if (DestDesc->Region.Handler)
929
{
930
AcpiUtAddReference (DestDesc->Region.Handler);
931
}
932
break;
933
934
/*
935
* For Mutex and Event objects, we cannot simply copy the underlying
936
* OS object. We must create a new one.
937
*/
938
case ACPI_TYPE_MUTEX:
939
940
Status = AcpiOsCreateMutex (&DestDesc->Mutex.OsMutex);
941
if (ACPI_FAILURE (Status))
942
{
943
return (Status);
944
}
945
break;
946
947
case ACPI_TYPE_EVENT:
948
949
Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0,
950
&DestDesc->Event.OsSemaphore);
951
if (ACPI_FAILURE (Status))
952
{
953
return (Status);
954
}
955
break;
956
957
default:
958
959
/* Nothing to do for other simple objects */
960
961
break;
962
}
963
964
return (AE_OK);
965
}
966
967
968
/*******************************************************************************
969
*
970
* FUNCTION: AcpiUtCopyIelementToIelement
971
*
972
* PARAMETERS: ACPI_PKG_CALLBACK
973
*
974
* RETURN: Status
975
*
976
* DESCRIPTION: Copy one package element to another package element
977
*
978
******************************************************************************/
979
980
static ACPI_STATUS
981
AcpiUtCopyIelementToIelement (
982
UINT8 ObjectType,
983
ACPI_OPERAND_OBJECT *SourceObject,
984
ACPI_GENERIC_STATE *State,
985
void *Context)
986
{
987
ACPI_STATUS Status = AE_OK;
988
UINT32 ThisIndex;
989
ACPI_OPERAND_OBJECT **ThisTargetPtr;
990
ACPI_OPERAND_OBJECT *TargetObject;
991
992
993
ACPI_FUNCTION_ENTRY ();
994
995
996
ThisIndex = State->Pkg.Index;
997
ThisTargetPtr = (ACPI_OPERAND_OBJECT **)
998
&State->Pkg.DestObject->Package.Elements[ThisIndex];
999
1000
switch (ObjectType)
1001
{
1002
case ACPI_COPY_TYPE_SIMPLE:
1003
1004
/* A null source object indicates a (legal) null package element */
1005
1006
if (SourceObject)
1007
{
1008
/*
1009
* This is a simple object, just copy it
1010
*/
1011
TargetObject = AcpiUtCreateInternalObject (
1012
SourceObject->Common.Type);
1013
if (!TargetObject)
1014
{
1015
return (AE_NO_MEMORY);
1016
}
1017
1018
Status = AcpiUtCopySimpleObject (SourceObject, TargetObject);
1019
if (ACPI_FAILURE (Status))
1020
{
1021
goto ErrorExit;
1022
}
1023
1024
*ThisTargetPtr = TargetObject;
1025
}
1026
else
1027
{
1028
/* Pass through a null element */
1029
1030
*ThisTargetPtr = NULL;
1031
}
1032
break;
1033
1034
case ACPI_COPY_TYPE_PACKAGE:
1035
/*
1036
* This object is a package - go down another nesting level
1037
* Create and build the package object
1038
*/
1039
TargetObject = AcpiUtCreatePackageObject (
1040
SourceObject->Package.Count);
1041
if (!TargetObject)
1042
{
1043
return (AE_NO_MEMORY);
1044
}
1045
1046
TargetObject->Common.Flags = SourceObject->Common.Flags;
1047
1048
/* Pass the new package object back to the package walk routine */
1049
1050
State->Pkg.ThisTargetObj = TargetObject;
1051
1052
/* Store the object pointer in the parent package object */
1053
1054
*ThisTargetPtr = TargetObject;
1055
break;
1056
1057
default:
1058
1059
return (AE_BAD_PARAMETER);
1060
}
1061
1062
return (Status);
1063
1064
ErrorExit:
1065
AcpiUtRemoveReference (TargetObject);
1066
return (Status);
1067
}
1068
1069
1070
/*******************************************************************************
1071
*
1072
* FUNCTION: AcpiUtCopyIpackageToIpackage
1073
*
1074
* PARAMETERS: SourceObj - Pointer to the source package object
1075
* DestObj - Where the internal object is returned
1076
* WalkState - Current Walk state descriptor
1077
*
1078
* RETURN: Status
1079
*
1080
* DESCRIPTION: This function is called to copy an internal package object
1081
* into another internal package object.
1082
*
1083
******************************************************************************/
1084
1085
static ACPI_STATUS
1086
AcpiUtCopyIpackageToIpackage (
1087
ACPI_OPERAND_OBJECT *SourceObj,
1088
ACPI_OPERAND_OBJECT *DestObj,
1089
ACPI_WALK_STATE *WalkState)
1090
{
1091
ACPI_STATUS Status = AE_OK;
1092
1093
1094
ACPI_FUNCTION_TRACE (UtCopyIpackageToIpackage);
1095
1096
1097
DestObj->Common.Type = SourceObj->Common.Type;
1098
DestObj->Common.Flags = SourceObj->Common.Flags;
1099
DestObj->Package.Count = SourceObj->Package.Count;
1100
1101
/*
1102
* Create the object array and walk the source package tree
1103
*/
1104
DestObj->Package.Elements = ACPI_ALLOCATE_ZEROED (
1105
((ACPI_SIZE) SourceObj->Package.Count + 1) *
1106
sizeof (void *));
1107
if (!DestObj->Package.Elements)
1108
{
1109
ACPI_ERROR ((AE_INFO, "Package allocation failure"));
1110
return_ACPI_STATUS (AE_NO_MEMORY);
1111
}
1112
1113
/*
1114
* Copy the package element-by-element by walking the package "tree".
1115
* This handles nested packages of arbitrary depth.
1116
*/
1117
Status = AcpiUtWalkPackageTree (SourceObj, DestObj,
1118
AcpiUtCopyIelementToIelement, WalkState);
1119
if (ACPI_FAILURE (Status))
1120
{
1121
/* On failure, delete the destination package object */
1122
1123
AcpiUtRemoveReference (DestObj);
1124
}
1125
1126
return_ACPI_STATUS (Status);
1127
}
1128
1129
1130
/*******************************************************************************
1131
*
1132
* FUNCTION: AcpiUtCopyIobjectToIobject
1133
*
1134
* PARAMETERS: SourceDesc - The internal object to be copied
1135
* DestDesc - Where the copied object is returned
1136
* WalkState - Current walk state
1137
*
1138
* RETURN: Status
1139
*
1140
* DESCRIPTION: Copy an internal object to a new internal object
1141
*
1142
******************************************************************************/
1143
1144
ACPI_STATUS
1145
AcpiUtCopyIobjectToIobject (
1146
ACPI_OPERAND_OBJECT *SourceDesc,
1147
ACPI_OPERAND_OBJECT **DestDesc,
1148
ACPI_WALK_STATE *WalkState)
1149
{
1150
ACPI_STATUS Status = AE_OK;
1151
1152
1153
ACPI_FUNCTION_TRACE (UtCopyIobjectToIobject);
1154
1155
1156
/* Create the top level object */
1157
1158
*DestDesc = AcpiUtCreateInternalObject (SourceDesc->Common.Type);
1159
if (!*DestDesc)
1160
{
1161
return_ACPI_STATUS (AE_NO_MEMORY);
1162
}
1163
1164
/* Copy the object and possible subobjects */
1165
1166
if (SourceDesc->Common.Type == ACPI_TYPE_PACKAGE)
1167
{
1168
Status = AcpiUtCopyIpackageToIpackage (
1169
SourceDesc, *DestDesc, WalkState);
1170
}
1171
else
1172
{
1173
Status = AcpiUtCopySimpleObject (SourceDesc, *DestDesc);
1174
}
1175
1176
/* Delete the allocated object if copy failed */
1177
1178
if (ACPI_FAILURE (Status))
1179
{
1180
AcpiUtRemoveReference (*DestDesc);
1181
}
1182
1183
return_ACPI_STATUS (Status);
1184
}
1185
1186