Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/acpica/compiler/aslresource.c
48371 views
1
/******************************************************************************
2
*
3
* Module Name: aslresource - Resource template/descriptor 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/compiler/aslcompiler.h>
153
#include "aslcompiler.y.h"
154
#include <contrib/dev/acpica/include/amlcode.h>
155
156
157
#define _COMPONENT ACPI_COMPILER
158
ACPI_MODULE_NAME ("aslresource")
159
160
161
/*******************************************************************************
162
*
163
* FUNCTION: RsSmallAddressCheck
164
*
165
* PARAMETERS: Minimum - Address Min value
166
* Maximum - Address Max value
167
* Length - Address range value
168
* Alignment - Address alignment value
169
* MinOp - Original Op for Address Min
170
* MaxOp - Original Op for Address Max
171
* LengthOp - Original Op for address range
172
* AlignOp - Original Op for address alignment. If
173
* NULL, means "zero value for alignment is
174
* OK, and means 64K alignment" (for
175
* Memory24 descriptor)
176
* Op - Parent Op for entire construct
177
*
178
* RETURN: None. Adds error messages to error log if necessary
179
*
180
* DESCRIPTION: Perform common value checks for "small" address descriptors.
181
* Currently:
182
* Io, Memory24, Memory32
183
*
184
******************************************************************************/
185
186
void
187
RsSmallAddressCheck (
188
UINT8 Type,
189
UINT32 Minimum,
190
UINT32 Maximum,
191
UINT32 Length,
192
UINT32 Alignment,
193
ACPI_PARSE_OBJECT *MinOp,
194
ACPI_PARSE_OBJECT *MaxOp,
195
ACPI_PARSE_OBJECT *LengthOp,
196
ACPI_PARSE_OBJECT *AlignOp,
197
ACPI_PARSE_OBJECT *Op)
198
{
199
200
if (AslGbl_NoResourceChecking)
201
{
202
return;
203
}
204
205
/*
206
* Check for a so-called "null descriptor". These are descriptors that are
207
* created with most fields set to zero. The intent is that the descriptor
208
* will be updated/completed at runtime via a BufferField.
209
*
210
* If the descriptor does NOT have a resource tag, it cannot be referenced
211
* by a BufferField and we will flag this as an error. Conversely, if
212
* the descriptor has a resource tag, we will assume that a BufferField
213
* will be used to dynamically update it, so no error.
214
*
215
* A possible enhancement to this check would be to verify that in fact
216
* a BufferField is created using the resource tag, and perhaps even
217
* verify that a Store is performed to the BufferField.
218
*
219
* Note: for these descriptors, Alignment is allowed to be zero
220
*/
221
if (!Minimum && !Maximum && !Length)
222
{
223
if (!Op->Asl.ExternalName)
224
{
225
/* No resource tag. Descriptor is fixed and is also illegal */
226
227
AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
228
}
229
230
return;
231
}
232
233
/*
234
* Range checks for Memory24 and Memory32.
235
* IO descriptor has different definition of min/max, don't check.
236
*/
237
if (Type != ACPI_RESOURCE_NAME_IO)
238
{
239
/* Basic checks on Min/Max/Length */
240
241
if (Minimum > Maximum)
242
{
243
AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
244
}
245
else if (Length > (Maximum - Minimum + 1))
246
{
247
AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
248
}
249
250
/* Special case for Memory24, min/max values are compressed */
251
252
if (Type == ACPI_RESOURCE_NAME_MEMORY24)
253
{
254
if (!Alignment) /* Alignment==0 means 64K alignment */
255
{
256
Alignment = ACPI_UINT16_MAX + 1;
257
}
258
259
Minimum <<= 8;
260
Maximum <<= 8;
261
}
262
}
263
264
/* Alignment of zero is not in ACPI spec, but is used to mean byte acc */
265
266
if (!Alignment)
267
{
268
Alignment = 1;
269
}
270
271
/* Addresses must be an exact multiple of the alignment value */
272
273
if (Minimum % Alignment)
274
{
275
AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
276
}
277
if (Maximum % Alignment)
278
{
279
AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, NULL);
280
}
281
}
282
283
284
/*******************************************************************************
285
*
286
* FUNCTION: RsLargeAddressCheck
287
*
288
* PARAMETERS: Minimum - Address Min value
289
* Maximum - Address Max value
290
* Length - Address range value
291
* Granularity - Address granularity value
292
* Flags - General flags for address descriptors:
293
* _MIF, _MAF, _DEC
294
* MinOp - Original Op for Address Min
295
* MaxOp - Original Op for Address Max
296
* LengthOp - Original Op for address range
297
* GranOp - Original Op for address granularity
298
* Op - Parent Op for entire construct
299
*
300
* RETURN: None. Adds error messages to error log if necessary
301
*
302
* DESCRIPTION: Perform common value checks for "large" address descriptors.
303
* Currently:
304
* WordIo, WordBusNumber, WordSpace
305
* DWordIo, DWordMemory, DWordSpace
306
* QWordIo, QWordMemory, QWordSpace
307
* ExtendedIo, ExtendedMemory, ExtendedSpace
308
*
309
* _MIF flag set means that the minimum address is fixed and is not relocatable
310
* _MAF flag set means that the maximum address is fixed and is not relocatable
311
* Length of zero means that the record size is variable
312
*
313
* This function implements the LEN/MIF/MAF/MIN/MAX/GRA rules within Table 6-40
314
* of the ACPI 4.0a specification. Added 04/2010.
315
*
316
******************************************************************************/
317
318
void
319
RsLargeAddressCheck (
320
UINT64 Minimum,
321
UINT64 Maximum,
322
UINT64 Length,
323
UINT64 Granularity,
324
UINT8 Flags,
325
ACPI_PARSE_OBJECT *MinOp,
326
ACPI_PARSE_OBJECT *MaxOp,
327
ACPI_PARSE_OBJECT *LengthOp,
328
ACPI_PARSE_OBJECT *GranOp,
329
ACPI_PARSE_OBJECT *Op)
330
{
331
332
if (AslGbl_NoResourceChecking)
333
{
334
return;
335
}
336
337
/*
338
* Check for a so-called "null descriptor". These are descriptors that are
339
* created with most fields set to zero. The intent is that the descriptor
340
* will be updated/completed at runtime via a BufferField.
341
*
342
* If the descriptor does NOT have a resource tag, it cannot be referenced
343
* by a BufferField and we will flag this as an error. Conversely, if
344
* the descriptor has a resource tag, we will assume that a BufferField
345
* will be used to dynamically update it, so no error.
346
*
347
* A possible enhancement to this check would be to verify that in fact
348
* a BufferField is created using the resource tag, and perhaps even
349
* verify that a Store is performed to the BufferField.
350
*/
351
if (!Minimum && !Maximum && !Length && !Granularity)
352
{
353
if (!Op->Asl.ExternalName)
354
{
355
/* No resource tag. Descriptor is fixed and is also illegal */
356
357
AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
358
}
359
360
return;
361
}
362
363
/* Basic checks on Min/Max/Length */
364
365
if (Minimum > Maximum)
366
{
367
AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
368
return;
369
}
370
else if (Length > (Maximum - Minimum + 1))
371
{
372
AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
373
return;
374
}
375
376
/* If specified (non-zero), ensure granularity is a power-of-two minus one */
377
378
if (Granularity)
379
{
380
if ((Granularity + 1) &
381
Granularity)
382
{
383
AslError (ASL_ERROR, ASL_MSG_INVALID_GRANULARITY, GranOp, NULL);
384
return;
385
}
386
}
387
388
/*
389
* Check the various combinations of Length, MinFixed, and MaxFixed
390
*/
391
if (Length)
392
{
393
/* Fixed non-zero length */
394
395
switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
396
{
397
case 0:
398
/*
399
* Fixed length, variable locations (both _MIN and _MAX).
400
* Length must be a multiple of granularity
401
*/
402
if (Granularity & Length)
403
{
404
AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, LengthOp, NULL);
405
}
406
break;
407
408
case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
409
410
/* Fixed length, fixed location. Granularity must be zero */
411
412
if (Granularity != 0)
413
{
414
AslError (ASL_ERROR, ASL_MSG_INVALID_GRAN_FIXED, GranOp, NULL);
415
}
416
417
/* Length must be exactly the size of the min/max window */
418
419
if (Length != (Maximum - Minimum + 1))
420
{
421
AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH_FIXED, LengthOp, NULL);
422
}
423
break;
424
425
/* All other combinations are invalid */
426
427
case ACPI_RESOURCE_FLAG_MIF:
428
case ACPI_RESOURCE_FLAG_MAF:
429
default:
430
431
AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
432
}
433
}
434
else
435
{
436
/* Variable length (length==0) */
437
438
switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
439
{
440
case 0:
441
/*
442
* Both _MIN and _MAX are variable.
443
* No additional requirements, just exit
444
*/
445
break;
446
447
case ACPI_RESOURCE_FLAG_MIF:
448
449
/* _MIN is fixed. _MIN must be multiple of _GRA */
450
451
/*
452
* The granularity is defined by the ACPI specification to be a
453
* power-of-two minus one, therefore the granularity is a
454
* bitmask which can be used to easily validate the addresses.
455
*/
456
if (Granularity & Minimum)
457
{
458
AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
459
}
460
break;
461
462
case ACPI_RESOURCE_FLAG_MAF:
463
464
/* _MAX is fixed. (_MAX + 1) must be multiple of _GRA */
465
466
if (Granularity & (Maximum + 1))
467
{
468
AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, "-1");
469
}
470
break;
471
472
/* Both MIF/MAF set is invalid if length is zero */
473
474
case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
475
default:
476
477
AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
478
}
479
}
480
}
481
482
483
/*******************************************************************************
484
*
485
* FUNCTION: RsGetStringDataLength
486
*
487
* PARAMETERS: InitializerOp - Start of a subtree of init nodes
488
*
489
* RETURN: Valid string length if a string node is found (otherwise 0)
490
*
491
* DESCRIPTION: In a list of peer nodes, find the first one that contains a
492
* string and return the length of the string.
493
*
494
******************************************************************************/
495
496
UINT16
497
RsGetStringDataLength (
498
ACPI_PARSE_OBJECT *InitializerOp)
499
{
500
501
while (InitializerOp)
502
{
503
if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
504
{
505
return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1));
506
}
507
508
InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
509
}
510
511
return (0);
512
}
513
514
515
/*******************************************************************************
516
*
517
* FUNCTION: RsAllocateResourceNode
518
*
519
* PARAMETERS: Size - Size of node in bytes
520
*
521
* RETURN: The allocated node - aborts on allocation failure
522
*
523
* DESCRIPTION: Allocate a resource description node and the resource
524
* descriptor itself (the nodes are used to link descriptors).
525
*
526
******************************************************************************/
527
528
ASL_RESOURCE_NODE *
529
RsAllocateResourceNode (
530
UINT32 Size)
531
{
532
ASL_RESOURCE_NODE *Rnode;
533
534
535
/* Allocate the node */
536
537
Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE));
538
539
/* Allocate the resource descriptor itself */
540
541
Rnode->Buffer = UtLocalCalloc (Size);
542
Rnode->BufferLength = Size;
543
return (Rnode);
544
}
545
546
547
/*******************************************************************************
548
*
549
* FUNCTION: RsCreateResourceField
550
*
551
* PARAMETERS: Op - Resource field node
552
* Name - Name of the field (Used only to reference
553
* the field in the ASL, not in the AML)
554
* ByteOffset - Offset from the field start
555
* BitOffset - Additional bit offset
556
* BitLength - Number of bits in the field
557
*
558
* RETURN: None, sets fields within the input node
559
*
560
* DESCRIPTION: Utility function to generate a named bit field within a
561
* resource descriptor. Mark a node as 1) a field in a resource
562
* descriptor, and 2) set the value to be a BIT offset
563
*
564
******************************************************************************/
565
566
void
567
RsCreateResourceField (
568
ACPI_PARSE_OBJECT *Op,
569
char *Name,
570
UINT32 ByteOffset,
571
UINT32 BitOffset,
572
UINT32 BitLength)
573
{
574
575
Op->Asl.ExternalName = Name;
576
Op->Asl.CompileFlags |= OP_IS_RESOURCE_FIELD;
577
578
Op->Asl.Value.Tag.BitOffset = (ByteOffset * 8) + BitOffset;
579
Op->Asl.Value.Tag.BitLength = BitLength;
580
}
581
582
583
/*******************************************************************************
584
*
585
* FUNCTION: RsSetFlagBits
586
*
587
* PARAMETERS: *Flags - Pointer to the flag byte
588
* Op - Flag initialization node
589
* Position - Bit position within the flag byte
590
* Default - Used if the node is DEFAULT.
591
*
592
* RETURN: Sets bits within the *Flags output byte.
593
*
594
* DESCRIPTION: Set a bit in a cumulative flags word from an initialization
595
* node. Will use a default value if the node is DEFAULT, meaning
596
* that no value was specified in the ASL. Used to merge multiple
597
* keywords into a single flags byte.
598
*
599
******************************************************************************/
600
601
void
602
RsSetFlagBits (
603
UINT8 *Flags,
604
ACPI_PARSE_OBJECT *Op,
605
UINT8 Position,
606
UINT8 DefaultBit)
607
{
608
609
if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
610
{
611
/* Use the default bit */
612
613
*Flags |= (DefaultBit << Position);
614
}
615
else
616
{
617
/* Use the bit specified in the initialization node */
618
619
*Flags |= (((UINT8) Op->Asl.Value.Integer) << Position);
620
}
621
}
622
623
624
void
625
RsSetFlagBits16 (
626
UINT16 *Flags,
627
ACPI_PARSE_OBJECT *Op,
628
UINT8 Position,
629
UINT8 DefaultBit)
630
{
631
632
if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
633
{
634
/* Use the default bit */
635
636
*Flags |= (DefaultBit << Position);
637
}
638
else
639
{
640
/* Use the bit specified in the initialization node */
641
642
*Flags |= (((UINT16) Op->Asl.Value.Integer) << Position);
643
}
644
}
645
646
647
/*******************************************************************************
648
*
649
* FUNCTION: RsCompleteNodeAndGetNext
650
*
651
* PARAMETERS: Op - Resource node to be completed
652
*
653
* RETURN: The next peer to the input node.
654
*
655
* DESCRIPTION: Mark the current node completed and return the next peer.
656
* The node ParseOpcode is set to DEFAULT_ARG, meaning that
657
* this node is to be ignored from now on.
658
*
659
******************************************************************************/
660
661
ACPI_PARSE_OBJECT *
662
RsCompleteNodeAndGetNext (
663
ACPI_PARSE_OBJECT *Op)
664
{
665
666
/* Mark this node unused */
667
668
Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
669
670
/* Move on to the next peer node in the initializer list */
671
672
return (ASL_GET_PEER_NODE (Op));
673
}
674
675
676
/*******************************************************************************
677
*
678
* FUNCTION: RsCheckListForDuplicates
679
*
680
* PARAMETERS: Op - First op in the initializer list
681
*
682
* RETURN: None
683
*
684
* DESCRIPTION: Check an initializer list for duplicate values. Emits an error
685
* if any duplicates are found.
686
*
687
******************************************************************************/
688
689
void
690
RsCheckListForDuplicates (
691
ACPI_PARSE_OBJECT *Op)
692
{
693
ACPI_PARSE_OBJECT *NextValueOp = Op;
694
ACPI_PARSE_OBJECT *NextOp;
695
UINT32 Value;
696
697
698
if (!Op)
699
{
700
return;
701
}
702
703
/* Search list once for each value in the list */
704
705
while (NextValueOp)
706
{
707
Value = (UINT32) NextValueOp->Asl.Value.Integer;
708
709
/* Compare this value to all remaining values in the list */
710
711
NextOp = ASL_GET_PEER_NODE (NextValueOp);
712
while (NextOp)
713
{
714
if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
715
{
716
/* Compare values */
717
718
if (Value == (UINT32) NextOp->Asl.Value.Integer)
719
{
720
/* Emit error only once per duplicate node */
721
722
if (!(NextOp->Asl.CompileFlags & OP_IS_DUPLICATE))
723
{
724
NextOp->Asl.CompileFlags |= OP_IS_DUPLICATE;
725
AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM,
726
NextOp, NULL);
727
}
728
}
729
}
730
731
NextOp = ASL_GET_PEER_NODE (NextOp);
732
}
733
734
NextValueOp = ASL_GET_PEER_NODE (NextValueOp);
735
}
736
}
737
738
739
/*******************************************************************************
740
*
741
* FUNCTION: RsDoOneResourceDescriptor
742
*
743
* PARAMETERS: DescriptorTypeOp - Parent parse node of the descriptor
744
* CurrentByteOffset - Offset in the resource descriptor
745
* buffer.
746
*
747
* RETURN: A valid resource node for the descriptor
748
*
749
* DESCRIPTION: Dispatches the processing of one resource descriptor
750
*
751
******************************************************************************/
752
753
ASL_RESOURCE_NODE *
754
RsDoOneResourceDescriptor (
755
ASL_RESOURCE_INFO *Info,
756
UINT8 *State)
757
{
758
ASL_RESOURCE_NODE *Rnode = NULL;
759
760
761
/* Construct the resource */
762
763
switch (Info->DescriptorTypeOp->Asl.ParseOpcode)
764
{
765
766
case PARSEOP_CLOCKINPUT:
767
768
Rnode = RsDoClockInputDescriptor(Info);
769
break;
770
771
case PARSEOP_DMA:
772
773
Rnode = RsDoDmaDescriptor (Info);
774
break;
775
776
case PARSEOP_FIXEDDMA:
777
778
Rnode = RsDoFixedDmaDescriptor (Info);
779
break;
780
781
case PARSEOP_DWORDIO:
782
783
Rnode = RsDoDwordIoDescriptor (Info);
784
break;
785
786
case PARSEOP_DWORDMEMORY:
787
788
Rnode = RsDoDwordMemoryDescriptor (Info);
789
break;
790
791
case PARSEOP_DWORDPCC:
792
793
Rnode = RsDoDwordPccDescriptor (Info);
794
break;
795
796
case PARSEOP_DWORDSPACE:
797
798
Rnode = RsDoDwordSpaceDescriptor (Info);
799
break;
800
801
case PARSEOP_ENDDEPENDENTFN:
802
803
switch (*State)
804
{
805
case ACPI_RSTATE_NORMAL:
806
807
AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT,
808
Info->DescriptorTypeOp, NULL);
809
break;
810
811
case ACPI_RSTATE_START_DEPENDENT:
812
813
AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
814
Info->DescriptorTypeOp, NULL);
815
break;
816
817
case ACPI_RSTATE_DEPENDENT_LIST:
818
default:
819
820
break;
821
}
822
823
*State = ACPI_RSTATE_NORMAL;
824
Rnode = RsDoEndDependentDescriptor (Info);
825
break;
826
827
case PARSEOP_ENDTAG:
828
829
Rnode = RsDoEndTagDescriptor (Info);
830
break;
831
832
case PARSEOP_EXTENDEDIO:
833
834
Rnode = RsDoExtendedIoDescriptor (Info);
835
break;
836
837
case PARSEOP_EXTENDEDMEMORY:
838
839
Rnode = RsDoExtendedMemoryDescriptor (Info);
840
break;
841
842
case PARSEOP_EXTENDEDSPACE:
843
844
Rnode = RsDoExtendedSpaceDescriptor (Info);
845
break;
846
847
case PARSEOP_FIXEDIO:
848
849
Rnode = RsDoFixedIoDescriptor (Info);
850
break;
851
852
case PARSEOP_INTERRUPT:
853
854
Rnode = RsDoInterruptDescriptor (Info);
855
break;
856
857
case PARSEOP_IO:
858
859
Rnode = RsDoIoDescriptor (Info);
860
break;
861
862
case PARSEOP_IRQ:
863
864
Rnode = RsDoIrqDescriptor (Info);
865
break;
866
867
case PARSEOP_IRQNOFLAGS:
868
869
Rnode = RsDoIrqNoFlagsDescriptor (Info);
870
break;
871
872
case PARSEOP_MEMORY24:
873
874
Rnode = RsDoMemory24Descriptor (Info);
875
break;
876
877
case PARSEOP_MEMORY32:
878
879
Rnode = RsDoMemory32Descriptor (Info);
880
break;
881
882
case PARSEOP_MEMORY32FIXED:
883
884
Rnode = RsDoMemory32FixedDescriptor (Info);
885
break;
886
887
case PARSEOP_QWORDIO:
888
889
Rnode = RsDoQwordIoDescriptor (Info);
890
break;
891
892
case PARSEOP_QWORDMEMORY:
893
894
Rnode = RsDoQwordMemoryDescriptor (Info);
895
break;
896
897
case PARSEOP_QWORDPCC:
898
899
Rnode = RsDoQwordPccDescriptor (Info);
900
break;
901
902
case PARSEOP_QWORDSPACE:
903
904
Rnode = RsDoQwordSpaceDescriptor (Info);
905
break;
906
907
case PARSEOP_REGISTER:
908
909
Rnode = RsDoGeneralRegisterDescriptor (Info);
910
break;
911
912
case PARSEOP_STARTDEPENDENTFN:
913
914
switch (*State)
915
{
916
case ACPI_RSTATE_START_DEPENDENT:
917
918
AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
919
Info->DescriptorTypeOp, NULL);
920
break;
921
922
case ACPI_RSTATE_NORMAL:
923
case ACPI_RSTATE_DEPENDENT_LIST:
924
default:
925
926
break;
927
}
928
929
*State = ACPI_RSTATE_START_DEPENDENT;
930
Rnode = RsDoStartDependentDescriptor (Info);
931
*State = ACPI_RSTATE_DEPENDENT_LIST;
932
break;
933
934
case PARSEOP_STARTDEPENDENTFN_NOPRI:
935
936
switch (*State)
937
{
938
case ACPI_RSTATE_START_DEPENDENT:
939
940
AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
941
Info->DescriptorTypeOp, NULL);
942
break;
943
944
case ACPI_RSTATE_NORMAL:
945
case ACPI_RSTATE_DEPENDENT_LIST:
946
default:
947
948
break;
949
}
950
951
*State = ACPI_RSTATE_START_DEPENDENT;
952
Rnode = RsDoStartDependentNoPriDescriptor (Info);
953
*State = ACPI_RSTATE_DEPENDENT_LIST;
954
break;
955
956
case PARSEOP_VENDORLONG:
957
958
Rnode = RsDoVendorLargeDescriptor (Info);
959
break;
960
961
case PARSEOP_VENDORSHORT:
962
963
Rnode = RsDoVendorSmallDescriptor (Info);
964
break;
965
966
case PARSEOP_WORDBUSNUMBER:
967
968
Rnode = RsDoWordBusNumberDescriptor (Info);
969
break;
970
971
case PARSEOP_WORDIO:
972
973
Rnode = RsDoWordIoDescriptor (Info);
974
break;
975
976
case PARSEOP_WORDPCC:
977
978
Rnode = RsDoWordPccDescriptor (Info);
979
break;
980
981
case PARSEOP_WORDSPACE:
982
983
Rnode = RsDoWordSpaceDescriptor (Info);
984
break;
985
986
case PARSEOP_GPIO_INT:
987
988
Rnode = RsDoGpioIntDescriptor (Info);
989
break;
990
991
case PARSEOP_GPIO_IO:
992
993
Rnode = RsDoGpioIoDescriptor (Info);
994
break;
995
996
case PARSEOP_I2C_SERIALBUS:
997
case PARSEOP_I2C_SERIALBUS_V2:
998
999
Rnode = RsDoI2cSerialBusDescriptor (Info);
1000
break;
1001
1002
case PARSEOP_SPI_SERIALBUS:
1003
case PARSEOP_SPI_SERIALBUS_V2:
1004
1005
Rnode = RsDoSpiSerialBusDescriptor (Info);
1006
break;
1007
1008
case PARSEOP_UART_SERIALBUS:
1009
case PARSEOP_UART_SERIALBUS_V2:
1010
1011
Rnode = RsDoUartSerialBusDescriptor (Info);
1012
break;
1013
1014
case PARSEOP_CSI2_SERIALBUS:
1015
1016
Rnode = RsDoCsi2SerialBusDescriptor (Info);
1017
break;
1018
1019
case PARSEOP_PINCONFIG:
1020
1021
Rnode = RsDoPinConfigDescriptor (Info);
1022
break;
1023
1024
case PARSEOP_PINFUNCTION:
1025
1026
Rnode = RsDoPinFunctionDescriptor (Info);
1027
break;
1028
1029
case PARSEOP_PINGROUP:
1030
1031
Rnode = RsDoPinGroupDescriptor (Info);
1032
break;
1033
1034
case PARSEOP_PINGROUPFUNCTION:
1035
1036
Rnode = RsDoPinGroupFunctionDescriptor (Info);
1037
break;
1038
1039
case PARSEOP_PINGROUPCONFIG:
1040
1041
Rnode = RsDoPinGroupConfigDescriptor (Info);
1042
break;
1043
1044
case PARSEOP_DEFAULT_ARG:
1045
1046
/* Just ignore any of these, they are used as fillers/placeholders */
1047
break;
1048
1049
default:
1050
1051
printf ("Unknown resource descriptor type [%s]\n",
1052
Info->DescriptorTypeOp->Asl.ParseOpName);
1053
break;
1054
}
1055
1056
/*
1057
* Mark original node as unused, but head of a resource descriptor.
1058
* This allows the resource to be installed in the namespace so that
1059
* references to the descriptor can be resolved.
1060
*/
1061
Info->DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1062
Info->DescriptorTypeOp->Asl.CompileFlags = OP_IS_RESOURCE_DESC;
1063
Info->DescriptorTypeOp->Asl.Value.Integer = Info->CurrentByteOffset;
1064
1065
if (Rnode)
1066
{
1067
Info->DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength;
1068
Info->DescriptorTypeOp->Asl.Extra =
1069
((AML_RESOURCE *) Rnode->Buffer)->DescriptorType;
1070
}
1071
1072
return (Rnode);
1073
}
1074
1075
1076
/*******************************************************************************
1077
*
1078
* FUNCTION: RsLinkDescriptorChain
1079
*
1080
* PARAMETERS: PreviousRnode - Pointer to the node that will be previous
1081
* to the linked node, At exit, set to the
1082
* last node in the new chain.
1083
* Rnode - Resource node to link into the list
1084
*
1085
* RETURN: Cumulative buffer byte offset of the new segment of chain
1086
*
1087
* DESCRIPTION: Link a descriptor chain at the end of an existing chain.
1088
*
1089
******************************************************************************/
1090
1091
UINT32
1092
RsLinkDescriptorChain (
1093
ASL_RESOURCE_NODE **PreviousRnode,
1094
ASL_RESOURCE_NODE *Rnode)
1095
{
1096
ASL_RESOURCE_NODE *LastRnode;
1097
UINT32 CurrentByteOffset;
1098
1099
1100
/* Anything to do? */
1101
1102
if (!Rnode)
1103
{
1104
return (0);
1105
}
1106
1107
/* Point the previous node to the new node */
1108
1109
(*PreviousRnode)->Next = Rnode;
1110
CurrentByteOffset = Rnode->BufferLength;
1111
1112
/* Walk to the end of the chain headed by Rnode */
1113
1114
LastRnode = Rnode;
1115
while (LastRnode->Next)
1116
{
1117
LastRnode = LastRnode->Next;
1118
CurrentByteOffset += LastRnode->BufferLength;
1119
}
1120
1121
/* Previous node becomes the last node in the chain */
1122
1123
*PreviousRnode = LastRnode;
1124
return (CurrentByteOffset);
1125
}
1126
1127
1128
/*******************************************************************************
1129
*
1130
* FUNCTION: RsDoResourceTemplate
1131
*
1132
* PARAMETERS: Op - Parent of a resource template list
1133
*
1134
* RETURN: None. Sets input node to point to a list of AML code
1135
*
1136
* DESCRIPTION: Merge a list of resource descriptors into a single AML buffer,
1137
* in preparation for output to the AML output file.
1138
*
1139
******************************************************************************/
1140
1141
void
1142
RsDoResourceTemplate (
1143
ACPI_PARSE_OBJECT *Op)
1144
{
1145
ACPI_PARSE_OBJECT *BufferLengthOp;
1146
ACPI_PARSE_OBJECT *BufferOp;
1147
ACPI_PARSE_OBJECT *DescriptorTypeOp;
1148
ACPI_PARSE_OBJECT *LastOp = NULL;
1149
UINT32 CurrentByteOffset = 0;
1150
ASL_RESOURCE_NODE HeadRnode;
1151
ASL_RESOURCE_NODE *PreviousRnode;
1152
ASL_RESOURCE_NODE *Rnode;
1153
ASL_RESOURCE_INFO Info;
1154
UINT8 State;
1155
1156
1157
/* Mark parent as containing a resource template */
1158
1159
if (Op->Asl.Parent)
1160
{
1161
Op->Asl.Parent->Asl.CompileFlags |= OP_IS_RESOURCE_DESC;
1162
}
1163
1164
/* ResourceTemplate Opcode is first (Op) */
1165
/* Buffer Length node is first child */
1166
1167
BufferLengthOp = ASL_GET_CHILD_NODE (Op);
1168
1169
/* Buffer Op is first peer */
1170
1171
BufferOp = ASL_GET_PEER_NODE (BufferLengthOp);
1172
1173
/* First Descriptor type is next */
1174
1175
DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp);
1176
1177
/* DEFAULT_ARG indicates null template - ResourceTemplate(){} */
1178
1179
if (DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1180
{
1181
AslError (ASL_WARNING, ASL_MSG_NULL_RESOURCE_TEMPLATE,
1182
DescriptorTypeOp, DescriptorTypeOp->Asl.Value.String);
1183
}
1184
1185
/*
1186
* Process all resource descriptors in the list
1187
* Note: It is assumed that the EndTag node has been automatically
1188
* inserted at the end of the template by the parser.
1189
*/
1190
State = ACPI_RSTATE_NORMAL;
1191
PreviousRnode = &HeadRnode;
1192
while (DescriptorTypeOp)
1193
{
1194
/* Save information for optional mapfile */
1195
1196
if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONNECTION)
1197
{
1198
Info.MappingOp = Op->Asl.Parent;
1199
}
1200
else
1201
{
1202
Info.MappingOp = DescriptorTypeOp;
1203
}
1204
1205
Info.DescriptorTypeOp = DescriptorTypeOp;
1206
Info.CurrentByteOffset = CurrentByteOffset;
1207
1208
DescriptorTypeOp->Asl.CompileFlags |= OP_IS_RESOURCE_DESC;
1209
Rnode = RsDoOneResourceDescriptor (&Info, &State);
1210
1211
/*
1212
* Update current byte offset to indicate the number of bytes from the
1213
* start of the buffer. Buffer can include multiple descriptors, we
1214
* must keep track of the offset of not only each descriptor, but each
1215
* element (field) within each descriptor as well.
1216
*/
1217
CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode);
1218
1219
/* Get the next descriptor in the list */
1220
1221
LastOp = DescriptorTypeOp;
1222
DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp);
1223
}
1224
1225
if (State == ACPI_RSTATE_DEPENDENT_LIST)
1226
{
1227
if (LastOp)
1228
{
1229
LastOp = LastOp->Asl.Parent;
1230
}
1231
AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL);
1232
}
1233
1234
/*
1235
* Transform the nodes into the following
1236
*
1237
* Op -> AML_BUFFER_OP
1238
* First Child -> BufferLength
1239
* Second Child -> Descriptor Buffer (raw byte data)
1240
*/
1241
Op->Asl.ParseOpcode = PARSEOP_BUFFER;
1242
Op->Asl.AmlOpcode = AML_BUFFER_OP;
1243
Op->Asl.CompileFlags = OP_AML_PACKAGE | OP_IS_RESOURCE_DESC;
1244
UtSetParseOpName (Op);
1245
1246
BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
1247
BufferLengthOp->Asl.Value.Integer = CurrentByteOffset;
1248
(void) OpcSetOptimalIntegerSize (BufferLengthOp);
1249
UtSetParseOpName (BufferLengthOp);
1250
1251
BufferOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
1252
BufferOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN;
1253
BufferOp->Asl.AmlOpcodeLength = 0;
1254
BufferOp->Asl.AmlLength = CurrentByteOffset;
1255
BufferOp->Asl.Value.Buffer = ACPI_CAST_PTR (UINT8, HeadRnode.Next);
1256
BufferOp->Asl.CompileFlags |= OP_IS_RESOURCE_DATA;
1257
UtSetParseOpName (BufferOp);
1258
1259
return;
1260
}
1261
1262