]> git.proxmox.com Git - mirror_edk2.git/blob - DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / DynamicTablesPkg / Library / Common / AmlLib / CodeGen / AmlResourceDataCodeGen.c
1 /** @file
2 AML Resource Data Code Generation.
3
4 Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 @par Glossary:
9 - Rd or RD - Resource Data
10 - Rds or RDS - Resource Data Small
11 - Rdl or RDL - Resource Data Large
12 **/
13
14 #include <AmlNodeDefines.h>
15 #include <CodeGen/AmlResourceDataCodeGen.h>
16
17 #include <AmlCoreInterface.h>
18 #include <AmlDefines.h>
19 #include <Api/AmlApiHelper.h>
20 #include <Tree/AmlNode.h>
21 #include <ResourceData/AmlResourceData.h>
22
23 /** If ParentNode is not NULL, append RdNode.
24 If NewRdNode is not NULL, update its value to RdNode.
25
26 @param [in] RdNode Newly created Resource Data node.
27 RdNode is deleted if an error occurs.
28 @param [in] ParentNode If not NULL, ParentNode must:
29 - be a NameOp node, i.e. have the AML_NAME_OP
30 opcode (cf "Name ()" ASL statement)
31 - contain a list of resource data elements
32 (cf "ResourceTemplate ()" ASL statement)
33 RdNode is then added at the end of the variable
34 list of resource data elements, but before the
35 "End Tag" Resource Data.
36 @param [out] NewRdNode If not NULL:
37 - and Success, contains RdNode.
38 - and Error, reset to NULL.
39
40 @retval EFI_SUCCESS The function completed successfully.
41 @retval EFI_INVALID_PARAMETER Invalid parameter.
42 **/
43 STATIC
44 EFI_STATUS
45 EFIAPI
46 LinkRdNode (
47 IN AML_DATA_NODE *RdNode,
48 IN AML_OBJECT_NODE *ParentNode,
49 OUT AML_DATA_NODE **NewRdNode
50 )
51 {
52 EFI_STATUS Status;
53 EFI_STATUS Status1;
54 AML_OBJECT_NODE *BufferOpNode;
55
56 if (NewRdNode != NULL) {
57 *NewRdNode = NULL;
58 }
59
60 if (ParentNode != NULL) {
61 // Check this is a NameOp node.
62 if ((!AmlNodeHasOpCode (ParentNode, AML_NAME_OP, 0))) {
63 ASSERT (0);
64 Status = EFI_INVALID_PARAMETER;
65 goto error_handler;
66 }
67
68 // Get the value which is represented as a BufferOp object node
69 // which is the 2nd fixed argument (i.e. index 1).
70 BufferOpNode = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
71 ParentNode,
72 EAmlParseIndexTerm1
73 );
74 if ((BufferOpNode == NULL) ||
75 (AmlGetNodeType ((AML_NODE_HANDLE)BufferOpNode) != EAmlNodeObject) ||
76 (!AmlNodeHasOpCode (BufferOpNode, AML_BUFFER_OP, 0)))
77 {
78 ASSERT (0);
79 Status = EFI_INVALID_PARAMETER;
80 goto error_handler;
81 }
82
83 // Add RdNode as the last element, but before the EndTag.
84 Status = AmlAppendRdNode (BufferOpNode, RdNode);
85 if (EFI_ERROR (Status)) {
86 ASSERT (0);
87 goto error_handler;
88 }
89 }
90
91 if (NewRdNode != NULL) {
92 *NewRdNode = RdNode;
93 }
94
95 return EFI_SUCCESS;
96
97 error_handler:
98 Status1 = AmlDeleteTree ((AML_NODE_HEADER *)RdNode);
99 ASSERT_EFI_ERROR (Status1);
100 // Return original error.
101 return Status;
102 }
103
104 /** Construct the TypeSpecificFlags field for IO ranges.
105
106 See ACPI 6.4 spec, s19.6.34 for more.
107
108 @param [in] IsaRanges Possible values are:
109 0-Reserved
110 1-NonISAOnly
111 2-ISAOnly
112 3-EntireRange
113 See ACPI 6.4 spec, s19.6.34 for more.
114 @param [in] IsDenseTranslation TranslationDensity parameter.
115 @param [in] IsTypeStatic TranslationType parameter.
116
117 @return A type specific flags value.
118 MAX_UINT8 if error.
119 **/
120 STATIC
121 UINT8
122 EFIAPI
123 RdIoRangeSpecificFlags (
124 IN UINT8 IsaRanges,
125 IN BOOLEAN IsDenseTranslation,
126 IN BOOLEAN IsTypeStatic
127 )
128 {
129 // Only check type specific parameters.
130 if (IsaRanges > 3) {
131 ASSERT (0);
132 return MAX_UINT8;
133 }
134
135 // Construct TypeSpecificFlags and call the generic function.
136 // Cf ACPI 6.4 specification, Table 6.50:
137 // "Table 6.50: I/O Resource Flag (Resource Type = 1) Definitions"
138 return IsaRanges |
139 (IsTypeStatic ? 0 : BIT4) |
140 (IsDenseTranslation ? 0 : BIT5);
141 }
142
143 /** Construct the TypeSpecificFlags field for Memory ranges.
144
145 @param [in] Cacheable Possible values are:
146 0-The memory is non-cacheable
147 1-The memory is cacheable
148 2-The memory is cacheable and supports
149 write combining
150 3-The memory is cacheable and prefetchable
151 @param [in] IsReadWrite ReadAndWrite parameter.
152 @param [in] MemoryRangeType Possible values are:
153 0-AddressRangeMemory
154 1-AddressRangeReserved
155 2-AddressRangeACPI
156 3-AddressRangeNVS
157 See ACPI 6.4 spec, s19.6.35 for more.
158 @param [in] IsTypeStatic TranslationType parameter.
159
160 @return A type specific flags value.
161 MAX_UINT8 if error.
162 **/
163 STATIC
164 UINT8
165 EFIAPI
166 MemoryRangeSpecificFlags (
167 IN UINT8 Cacheable,
168 IN BOOLEAN IsReadWrite,
169 IN UINT8 MemoryRangeType,
170 IN BOOLEAN IsTypeStatic
171 )
172 {
173 // Only check type specific parameters.
174 if ((Cacheable > 3) ||
175 (MemoryRangeType > 3))
176 {
177 ASSERT (0);
178 return MAX_UINT8;
179 }
180
181 // Construct TypeSpecificFlags and call the generic function.
182 // Cf ACPI 6.4 specification, Table 6.49:
183 // "Memory Resource Flag (Resource Type = 0) Definitions"
184 return (IsReadWrite ? BIT0 : 0) |
185 (Cacheable << 1) |
186 (MemoryRangeType << 3) |
187 (IsTypeStatic ? 0 : BIT5);
188 }
189
190 /** Construct the GeneralFlags field of any Address Space Resource Descriptors.
191
192 E.g.:
193 ACPI 6.4 specification, s6.4.3.5.1 "QWord Address Space Descriptor"
194 for QWord
195
196 See ACPI 6.4 spec, s19.6.36 for more.
197
198 @param [in] IsPosDecode Decode parameter
199 @param [in] IsMinFixed Minimum address is fixed.
200 @param [in] IsMaxFixed Maximum address is fixed.
201
202 @return A type specific flags value.
203 **/
204 STATIC
205 UINT8
206 EFIAPI
207 AddressSpaceGeneralFlags (
208 IN BOOLEAN IsPosDecode,
209 IN BOOLEAN IsMinFixed,
210 IN BOOLEAN IsMaxFixed
211 )
212 {
213 return (IsPosDecode ? 0 : BIT1) |
214 (IsMinFixed ? BIT2 : 0) |
215 (IsMaxFixed ? BIT3 : 0);
216 }
217
218 /** Check Address Space Descriptor Fields.
219
220 Cf. ACPI 6.4 Table 6.44:
221 "Valid Combination of Address Space Descriptor Fields"
222
223 See ACPI 6.4 spec, s19.6.36 for more.
224
225 @param [in] IsMinFixed Minimum address is fixed.
226 @param [in] IsMaxFixed Maximum address is fixed.
227 @param [in] AddressGranularity Address granularity.
228 @param [in] AddressMinimum Minimum address.
229 @param [in] AddressMaximum Maximum address.
230 @param [in] AddressTranslation Address translation.
231 @param [in] RangeLength Range length.
232
233 @retval EFI_SUCCESS The function completed successfully.
234 @retval EFI_INVALID_PARAMETER Invalid parameter.
235 **/
236 STATIC
237 EFI_STATUS
238 EFIAPI
239 CheckAddressSpaceFields (
240 IN BOOLEAN IsMinFixed,
241 IN BOOLEAN IsMaxFixed,
242 IN UINT64 AddressGranularity,
243 IN UINT64 AddressMinimum,
244 IN UINT64 AddressMaximum,
245 IN UINT64 AddressTranslation,
246 IN UINT64 RangeLength
247 )
248 {
249 if ((AddressMinimum > AddressMaximum) ||
250 (RangeLength > (AddressMaximum - AddressMinimum + 1)) ||
251 ((AddressGranularity != 0) &&
252 (((AddressGranularity + 1) & AddressGranularity) != 0)))
253 {
254 ASSERT (0);
255 return EFI_INVALID_PARAMETER;
256 }
257
258 if (RangeLength != 0) {
259 if (IsMinFixed ^ IsMaxFixed) {
260 ASSERT (0);
261 return EFI_INVALID_PARAMETER;
262 } else if (IsMinFixed &&
263 IsMaxFixed &&
264 (AddressGranularity != 0) &&
265 ((AddressMaximum - AddressMinimum + 1) != RangeLength))
266 {
267 ASSERT (0);
268 return EFI_INVALID_PARAMETER;
269 }
270 } else {
271 if (IsMinFixed && IsMaxFixed) {
272 ASSERT (0);
273 return EFI_INVALID_PARAMETER;
274 } else if (IsMinFixed &&
275 ((AddressMinimum & AddressGranularity) != 0))
276 {
277 ASSERT (0);
278 return EFI_INVALID_PARAMETER;
279 } else if (IsMaxFixed &&
280 (((AddressMaximum + 1) & AddressGranularity) != 0))
281 {
282 ASSERT (0);
283 return EFI_INVALID_PARAMETER;
284 }
285 }
286
287 return EFI_SUCCESS;
288 }
289
290 /** Code generation for the "DWordSpace ()" ASL function.
291
292 The Resource Data effectively created is a DWord Address Space Resource
293 Data. Cf ACPI 6.4:
294 - s6.4.3.5.2 "DWord Address Space Descriptor".
295 - s19.6.36 "DWordSpace".
296
297 The created resource data node can be:
298 - appended to the list of resource data elements of the NameOpNode.
299 In such case NameOpNode must be defined by a the "Name ()" ASL statement
300 and initially contain a "ResourceTemplate ()".
301 - returned through the NewRdNode parameter.
302
303 See ACPI 6.4 spec, s19.6.36 for more.
304
305 @param [in] ResourceType Resource type.
306 Possible values are:
307 0: Memory range
308 1: I/O range
309 2: Bus number range
310 3-191: Reserved
311 192-255: Hardware Vendor Defined
312 See ACPI 6.4 spec, s6.4.3.5.2 for more.
313 @param [in] IsResourceConsumer ResourceUsage parameter.
314 @param [in] IsPosDecode Decode parameter
315 @param [in] IsMinFixed Minimum address is fixed.
316 @param [in] IsMaxFixed Maximum address is fixed.
317 @param [in] TypeSpecificFlags Type specific flags.
318 See ACPI 6.4 spec, s6.4.3.5.5
319 "Resource Type Specific Flags".
320 @param [in] AddressGranularity Address granularity.
321 @param [in] AddressMinimum Minimum address.
322 @param [in] AddressMaximum Maximum address.
323 @param [in] AddressTranslation Address translation.
324 @param [in] RangeLength Range length.
325 @param [in] ResourceSourceIndex Resource Source index.
326 Unused. Must be 0.
327 @param [in] ResourceSource Resource Source.
328 Unused. Must be NULL.
329 @param [in] NameOpNode NameOp object node defining a named object.
330 If provided, append the new resource data
331 node to the list of resource data elements
332 of this node.
333 @param [out] NewRdNode If provided and success,
334 contain the created node.
335
336 @retval EFI_SUCCESS The function completed successfully.
337 @retval EFI_INVALID_PARAMETER Invalid parameter.
338 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
339 **/
340 STATIC
341 EFI_STATUS
342 EFIAPI
343 AmlCodeGenRdDWordSpace (
344 IN UINT8 ResourceType,
345 IN BOOLEAN IsResourceConsumer,
346 IN BOOLEAN IsPosDecode,
347 IN BOOLEAN IsMinFixed,
348 IN BOOLEAN IsMaxFixed,
349 IN UINT8 TypeSpecificFlags,
350 IN UINT32 AddressGranularity,
351 IN UINT32 AddressMinimum,
352 IN UINT32 AddressMaximum,
353 IN UINT32 AddressTranslation,
354 IN UINT32 RangeLength,
355 IN UINT8 ResourceSourceIndex,
356 IN CONST CHAR8 *ResourceSource,
357 IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
358 OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
359 )
360 {
361 EFI_STATUS Status;
362 AML_DATA_NODE *RdNode;
363 EFI_ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR RdDWord;
364
365 // ResourceSource and ResourceSourceIndex are unused.
366 if ((TypeSpecificFlags == MAX_UINT8) ||
367 (ResourceSourceIndex != 0) ||
368 (ResourceSource != NULL) ||
369 ((NameOpNode == NULL) && (NewRdNode == NULL)))
370 {
371 ASSERT (0);
372 return EFI_INVALID_PARAMETER;
373 }
374
375 Status = CheckAddressSpaceFields (
376 IsMinFixed,
377 IsMaxFixed,
378 AddressGranularity,
379 AddressMinimum,
380 AddressMaximum,
381 AddressTranslation,
382 RangeLength
383 );
384 if (EFI_ERROR (Status)) {
385 ASSERT (0);
386 return Status;
387 }
388
389 // Header
390 RdDWord.Header.Header.Bits.Name =
391 ACPI_LARGE_DWORD_ADDRESS_SPACE_DESCRIPTOR_NAME;
392 RdDWord.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
393 RdDWord.Header.Length = sizeof (EFI_ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR) -
394 sizeof (ACPI_LARGE_RESOURCE_HEADER);
395
396 // Body
397 RdDWord.ResType = ResourceType;
398 RdDWord.GenFlag = AddressSpaceGeneralFlags (
399 IsPosDecode,
400 IsMinFixed,
401 IsMaxFixed
402 );
403 RdDWord.SpecificFlag = TypeSpecificFlags;
404 RdDWord.AddrSpaceGranularity = AddressGranularity;
405 RdDWord.AddrRangeMin = AddressMinimum;
406 RdDWord.AddrRangeMax = AddressMaximum;
407 RdDWord.AddrTranslationOffset = AddressTranslation;
408 RdDWord.AddrLen = RangeLength;
409
410 Status = AmlCreateDataNode (
411 EAmlNodeDataTypeResourceData,
412 (UINT8 *)&RdDWord,
413 sizeof (EFI_ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR),
414 &RdNode
415 );
416 if (EFI_ERROR (Status)) {
417 ASSERT (0);
418 return Status;
419 }
420
421 return LinkRdNode (RdNode, NameOpNode, NewRdNode);
422 }
423
424 /** Code generation for the "DWordIO ()" ASL function.
425
426 The Resource Data effectively created is a DWord Address Space Resource
427 Data. Cf ACPI 6.4:
428 - s6.4.3.5.2 "DWord Address Space Descriptor".
429 - s19.6.34 "DWordIO".
430
431 The created resource data node can be:
432 - appended to the list of resource data elements of the NameOpNode.
433 In such case NameOpNode must be defined by a the "Name ()" ASL statement
434 and initially contain a "ResourceTemplate ()".
435 - returned through the NewRdNode parameter.
436
437 See ACPI 6.4 spec, s19.6.34 for more.
438
439 @param [in] IsResourceConsumer ResourceUsage parameter.
440 @param [in] IsMinFixed Minimum address is fixed.
441 @param [in] IsMaxFixed Maximum address is fixed.
442 @param [in] IsPosDecode Decode parameter
443 @param [in] IsaRanges Possible values are:
444 0-Reserved
445 1-NonISAOnly
446 2-ISAOnly
447 3-EntireRange
448 @param [in] AddressGranularity Address granularity.
449 @param [in] AddressMinimum Minimum address.
450 @param [in] AddressMaximum Maximum address.
451 @param [in] AddressTranslation Address translation.
452 @param [in] RangeLength Range length.
453 @param [in] ResourceSourceIndex Resource Source index.
454 Unused. Must be 0.
455 @param [in] ResourceSource Resource Source.
456 Unused. Must be NULL.
457 @param [in] IsDenseTranslation TranslationDensity parameter.
458 @param [in] IsTypeStatic TranslationType parameter.
459 @param [in] NameOpNode NameOp object node defining a named object.
460 If provided, append the new resource data
461 node to the list of resource data elements
462 of this node.
463 @param [out] NewRdNode If provided and success,
464 contain the created node.
465
466 @retval EFI_SUCCESS The function completed successfully.
467 @retval EFI_INVALID_PARAMETER Invalid parameter.
468 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
469 **/
470 EFI_STATUS
471 EFIAPI
472 AmlCodeGenRdDWordIo (
473 IN BOOLEAN IsResourceConsumer,
474 IN BOOLEAN IsMinFixed,
475 IN BOOLEAN IsMaxFixed,
476 IN BOOLEAN IsPosDecode,
477 IN UINT8 IsaRanges,
478 IN UINT32 AddressGranularity,
479 IN UINT32 AddressMinimum,
480 IN UINT32 AddressMaximum,
481 IN UINT32 AddressTranslation,
482 IN UINT32 RangeLength,
483 IN UINT8 ResourceSourceIndex,
484 IN CONST CHAR8 *ResourceSource,
485 IN BOOLEAN IsDenseTranslation,
486 IN BOOLEAN IsTypeStatic,
487 IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
488 OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
489 )
490 {
491 return AmlCodeGenRdDWordSpace (
492 ACPI_ADDRESS_SPACE_TYPE_IO,
493 IsResourceConsumer,
494 IsPosDecode,
495 IsMinFixed,
496 IsMaxFixed,
497 RdIoRangeSpecificFlags (
498 IsaRanges,
499 IsDenseTranslation,
500 IsTypeStatic
501 ),
502 AddressGranularity,
503 AddressMinimum,
504 AddressMaximum,
505 AddressTranslation,
506 RangeLength,
507 ResourceSourceIndex,
508 ResourceSource,
509 NameOpNode,
510 NewRdNode
511 );
512 }
513
514 /** Code generation for the "DWordMemory ()" ASL function.
515
516 The Resource Data effectively created is a DWord Address Space Resource
517 Data. Cf ACPI 6.4:
518 - s6.4.3.5.2 "DWord Address Space Descriptor".
519 - s19.6.35 "DWordMemory".
520
521 The created resource data node can be:
522 - appended to the list of resource data elements of the NameOpNode.
523 In such case NameOpNode must be defined by a the "Name ()" ASL statement
524 and initially contain a "ResourceTemplate ()".
525 - returned through the NewRdNode parameter.
526
527 See ACPI 6.4 spec, s19.6.35 for more.
528
529 @param [in] IsResourceConsumer ResourceUsage parameter.
530 @param [in] IsPosDecode Decode parameter
531 @param [in] IsMinFixed Minimum address is fixed.
532 @param [in] IsMaxFixed Maximum address is fixed.
533 @param [in] Cacheable Possible values are:
534 0-The memory is non-cacheable
535 1-The memory is cacheable
536 2-The memory is cacheable and supports
537 write combining
538 3-The memory is cacheable and prefetchable
539 @param [in] IsReadWrite ReadAndWrite parameter.
540 @param [in] AddressGranularity Address granularity.
541 @param [in] AddressMinimum Minimum address.
542 @param [in] AddressMaximum Maximum address.
543 @param [in] AddressTranslation Address translation.
544 @param [in] RangeLength Range length.
545 @param [in] ResourceSourceIndex Resource Source index.
546 Unused. Must be 0.
547 @param [in] ResourceSource Resource Source.
548 Unused. Must be NULL.
549 @param [in] MemoryRangeType Possible values are:
550 0-AddressRangeMemory
551 1-AddressRangeReserved
552 2-AddressRangeACPI
553 3-AddressRangeNVS
554 @param [in] IsTypeStatic TranslationType parameter.
555 @param [in] NameOpNode NameOp object node defining a named object.
556 If provided, append the new resource data
557 node to the list of resource data elements
558 of this node.
559 @param [out] NewRdNode If provided and success,
560 contain the created node.
561
562 @retval EFI_SUCCESS The function completed successfully.
563 @retval EFI_INVALID_PARAMETER Invalid parameter.
564 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
565 **/
566 EFI_STATUS
567 EFIAPI
568 AmlCodeGenRdDWordMemory (
569 IN BOOLEAN IsResourceConsumer,
570 IN BOOLEAN IsPosDecode,
571 IN BOOLEAN IsMinFixed,
572 IN BOOLEAN IsMaxFixed,
573 IN UINT8 Cacheable,
574 IN BOOLEAN IsReadWrite,
575 IN UINT32 AddressGranularity,
576 IN UINT32 AddressMinimum,
577 IN UINT32 AddressMaximum,
578 IN UINT32 AddressTranslation,
579 IN UINT32 RangeLength,
580 IN UINT8 ResourceSourceIndex,
581 IN CONST CHAR8 *ResourceSource,
582 IN UINT8 MemoryRangeType,
583 IN BOOLEAN IsTypeStatic,
584 IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
585 OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
586 )
587 {
588 return AmlCodeGenRdDWordSpace (
589 ACPI_ADDRESS_SPACE_TYPE_MEM,
590 IsResourceConsumer,
591 IsPosDecode,
592 IsMinFixed,
593 IsMaxFixed,
594 MemoryRangeSpecificFlags (
595 Cacheable,
596 IsReadWrite,
597 MemoryRangeType,
598 IsTypeStatic
599 ),
600 AddressGranularity,
601 AddressMinimum,
602 AddressMaximum,
603 AddressTranslation,
604 RangeLength,
605 ResourceSourceIndex,
606 ResourceSource,
607 NameOpNode,
608 NewRdNode
609 );
610 }
611
612 /** Code generation for the "Memory32Fixed ()" ASL macro.
613
614 The Resource Data effectively created is a 32-bit Memory Resource
615 Data. Cf ACPI 6.4:
616 - s19.6.83 "Memory Resource Descriptor Macro".
617 - s19.2.8 "Memory32FixedTerm".
618
619 See ACPI 6.4 spec, s19.2.8 for more.
620
621 @param [in] IsReadWrite ReadAndWrite parameter.
622 @param [in] Address AddressBase parameter.
623 @param [in] RangeLength Range length.
624 @param [in] NameOpNode NameOp object node defining a named object.
625 If provided, append the new resource data
626 node to the list of resource data elements
627 of this node.
628 @param [out] NewMemNode If provided and success,
629 contain the created node.
630
631 @retval EFI_SUCCESS The function completed successfully.
632 @retval EFI_INVALID_PARAMETER Invalid parameter.
633 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
634 **/
635 EFI_STATUS
636 EFIAPI
637 AmlCodeGenRdMemory32Fixed (
638 BOOLEAN IsReadWrite,
639 UINT32 Address,
640 UINT32 RangeLength,
641 AML_OBJECT_NODE_HANDLE NameOpNode,
642 AML_DATA_NODE_HANDLE *NewMemNode
643 )
644 {
645 EFI_STATUS Status;
646 AML_DATA_NODE *MemNode;
647 EFI_ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR RangeDesc;
648
649 RangeDesc.Header.Header.Byte = ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR;
650 RangeDesc.Header.Length = sizeof (EFI_ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR) -
651 sizeof (ACPI_LARGE_RESOURCE_HEADER);
652 RangeDesc.Information = IsReadWrite ? BIT0 : 0;
653 RangeDesc.BaseAddress = Address;
654 RangeDesc.Length = RangeLength;
655
656 Status = AmlCreateDataNode (
657 EAmlNodeDataTypeResourceData,
658 (UINT8 *)&RangeDesc,
659 sizeof (RangeDesc),
660 &MemNode
661 );
662 if (EFI_ERROR (Status)) {
663 ASSERT (0);
664 return Status;
665 }
666
667 return LinkRdNode (MemNode, NameOpNode, NewMemNode);
668 }
669
670 /** Code generation for the "WordSpace ()" ASL function.
671
672 The Resource Data effectively created is a Word Address Space Resource
673 Data. Cf ACPI 6.4:
674 - s6.4.3.5.3 "Word Address Space Descriptor".
675 - s19.6.151 "WordSpace".
676
677 The created resource data node can be:
678 - appended to the list of resource data elements of the NameOpNode.
679 In such case NameOpNode must be defined by a the "Name ()" ASL statement
680 and initially contain a "ResourceTemplate ()".
681 - returned through the NewRdNode parameter.
682
683 See ACPI 6.4 spec, s19.6.151 for more.
684
685 @param [in] ResourceType Resource type.
686 Possible values are:
687 0: Memory range
688 1: I/O range
689 2: Bus number range
690 3-191: Reserved
691 192-255: Hardware Vendor Defined
692 See ACPI 6.4 spec, s6.4.3.5.3 for more.
693 @param [in] IsResourceConsumer ResourceUsage parameter.
694 @param [in] IsPosDecode Decode parameter
695 @param [in] IsMinFixed Minimum address is fixed.
696 @param [in] IsMaxFixed Maximum address is fixed.
697 @param [in] TypeSpecificFlags Type specific flags.
698 See ACPI 6.4 spec, s6.4.3.5.5
699 "Resource Type Specific Flags".
700 @param [in] AddressGranularity Address granularity.
701 @param [in] AddressMinimum Minimum address.
702 @param [in] AddressMaximum Maximum address.
703 @param [in] AddressTranslation Address translation.
704 @param [in] RangeLength Range length.
705 @param [in] ResourceSourceIndex Resource Source index.
706 Unused. Must be 0.
707 @param [in] ResourceSource Resource Source.
708 Unused. Must be NULL.
709 @param [in] NameOpNode NameOp object node defining a named object.
710 If provided, append the new resource data
711 node to the list of resource data elements
712 of this node.
713 @param [out] NewRdNode If provided and success,
714 contain the created node.
715
716 @retval EFI_SUCCESS The function completed successfully.
717 @retval EFI_INVALID_PARAMETER Invalid parameter.
718 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
719 **/
720 STATIC
721 EFI_STATUS
722 EFIAPI
723 AmlCodeGenRdWordSpace (
724 IN UINT8 ResourceType,
725 IN BOOLEAN IsResourceConsumer,
726 IN BOOLEAN IsPosDecode,
727 IN BOOLEAN IsMinFixed,
728 IN BOOLEAN IsMaxFixed,
729 IN UINT8 TypeSpecificFlags,
730 IN UINT16 AddressGranularity,
731 IN UINT16 AddressMinimum,
732 IN UINT16 AddressMaximum,
733 IN UINT16 AddressTranslation,
734 IN UINT16 RangeLength,
735 IN UINT8 ResourceSourceIndex,
736 IN CONST CHAR8 *ResourceSource,
737 IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
738 OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
739 )
740 {
741 EFI_STATUS Status;
742 AML_DATA_NODE *RdNode;
743 EFI_ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR Rdword;
744
745 // ResourceSource and ResourceSourceIndex are unused.
746 if ((TypeSpecificFlags == MAX_UINT8) ||
747 (ResourceSourceIndex != 0) ||
748 (ResourceSource != NULL) ||
749 ((NameOpNode == NULL) && (NewRdNode == NULL)))
750 {
751 ASSERT (0);
752 return EFI_INVALID_PARAMETER;
753 }
754
755 Status = CheckAddressSpaceFields (
756 IsMinFixed,
757 IsMaxFixed,
758 AddressGranularity,
759 AddressMinimum,
760 AddressMaximum,
761 AddressTranslation,
762 RangeLength
763 );
764 if (EFI_ERROR (Status)) {
765 ASSERT (0);
766 return Status;
767 }
768
769 // Header
770 Rdword.Header.Header.Bits.Name =
771 ACPI_LARGE_WORD_ADDRESS_SPACE_DESCRIPTOR_NAME;
772 Rdword.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
773 Rdword.Header.Length = sizeof (EFI_ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR) -
774 sizeof (ACPI_LARGE_RESOURCE_HEADER);
775
776 // Body
777 Rdword.ResType = ResourceType;
778 Rdword.GenFlag = AddressSpaceGeneralFlags (
779 IsPosDecode,
780 IsMinFixed,
781 IsMaxFixed
782 );
783 Rdword.SpecificFlag = TypeSpecificFlags;
784 Rdword.AddrSpaceGranularity = AddressGranularity;
785 Rdword.AddrRangeMin = AddressMinimum;
786 Rdword.AddrRangeMax = AddressMaximum;
787 Rdword.AddrTranslationOffset = AddressTranslation;
788 Rdword.AddrLen = RangeLength;
789
790 Status = AmlCreateDataNode (
791 EAmlNodeDataTypeResourceData,
792 (UINT8 *)&Rdword,
793 sizeof (EFI_ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR),
794 &RdNode
795 );
796 if (EFI_ERROR (Status)) {
797 ASSERT (0);
798 return Status;
799 }
800
801 return LinkRdNode (RdNode, NameOpNode, NewRdNode);
802 }
803
804 /** Code generation for the "WordBusNumber ()" ASL function.
805
806 The Resource Data effectively created is a Word Address Space Resource
807 Data. Cf ACPI 6.4:
808 - s6.4.3.5.3 "Word Address Space Descriptor".
809 - s19.6.149 "WordBusNumber".
810
811 The created resource data node can be:
812 - appended to the list of resource data elements of the NameOpNode.
813 In such case NameOpNode must be defined by a the "Name ()" ASL statement
814 and initially contain a "ResourceTemplate ()".
815 - returned through the NewRdNode parameter.
816
817 See ACPI 6.4 spec, s19.6.149 for more.
818
819 @param [in] IsResourceConsumer ResourceUsage parameter.
820 @param [in] IsMinFixed Minimum address is fixed.
821 @param [in] IsMaxFixed Maximum address is fixed.
822 @param [in] IsPosDecode Decode parameter
823 @param [in] AddressGranularity Address granularity.
824 @param [in] AddressMinimum Minimum address.
825 @param [in] AddressMaximum Maximum address.
826 @param [in] AddressTranslation Address translation.
827 @param [in] RangeLength Range length.
828 @param [in] ResourceSourceIndex Resource Source index.
829 Unused. Must be 0.
830 @param [in] ResourceSource Resource Source.
831 Unused. Must be NULL.
832 @param [in] NameOpNode NameOp object node defining a named object.
833 If provided, append the new resource data
834 node to the list of resource data elements
835 of this node.
836 @param [out] NewRdNode If provided and success,
837 contain the created node.
838
839 @retval EFI_SUCCESS The function completed successfully.
840 @retval EFI_INVALID_PARAMETER Invalid parameter.
841 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
842 **/
843 EFI_STATUS
844 EFIAPI
845 AmlCodeGenRdWordBusNumber (
846 IN BOOLEAN IsResourceConsumer,
847 IN BOOLEAN IsMinFixed,
848 IN BOOLEAN IsMaxFixed,
849 IN BOOLEAN IsPosDecode,
850 IN UINT32 AddressGranularity,
851 IN UINT32 AddressMinimum,
852 IN UINT32 AddressMaximum,
853 IN UINT32 AddressTranslation,
854 IN UINT32 RangeLength,
855 IN UINT8 ResourceSourceIndex,
856 IN CONST CHAR8 *ResourceSource,
857 IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
858 OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
859 )
860 {
861 // There is no Type Specific Flags for buses.
862 return AmlCodeGenRdWordSpace (
863 ACPI_ADDRESS_SPACE_TYPE_BUS,
864 IsResourceConsumer,
865 IsPosDecode,
866 IsMinFixed,
867 IsMaxFixed,
868 0,
869 AddressGranularity,
870 AddressMinimum,
871 AddressMaximum,
872 AddressTranslation,
873 RangeLength,
874 ResourceSourceIndex,
875 ResourceSource,
876 NameOpNode,
877 NewRdNode
878 );
879 }
880
881 /** Code generation for the "QWordSpace ()" ASL function.
882
883 The Resource Data effectively created is a QWord Address Space Resource
884 Data. Cf ACPI 6.4:
885 - s6.4.3.5.1 "QWord Address Space Descriptor".
886 - s19.6.111 "QWordSpace".
887
888 The created resource data node can be:
889 - appended to the list of resource data elements of the NameOpNode.
890 In such case NameOpNode must be defined by a the "Name ()" ASL statement
891 and initially contain a "ResourceTemplate ()".
892 - returned through the NewRdNode parameter.
893
894 See ACPI 6.4 spec, s19.6.111 for more.
895
896 @param [in] ResourceType Resource type.
897 Possible values are:
898 0: Memory range
899 1: I/O range
900 2: Bus number range
901 3-191: Reserved
902 192-255: Hardware Vendor Defined
903 See ACPI 6.4 spec, s6.4.3.5.1 for more.
904 @param [in] IsResourceConsumer ResourceUsage parameter.
905 @param [in] IsPosDecode Decode parameter
906 @param [in] IsMinFixed Minimum address is fixed.
907 @param [in] IsMaxFixed Maximum address is fixed.
908 @param [in] TypeSpecificFlags Type specific flags.
909 See ACPI 6.4 spec, s6.4.3.5.5
910 "Resource Type Specific Flags".
911 @param [in] AddressGranularity Address granularity.
912 @param [in] AddressMinimum Minimum address.
913 @param [in] AddressMaximum Maximum address.
914 @param [in] AddressTranslation Address translation.
915 @param [in] RangeLength Range length.
916 @param [in] ResourceSourceIndex Resource Source index.
917 Unused. Must be 0.
918 @param [in] ResourceSource Resource Source.
919 Unused. Must be NULL.
920 @param [in] NameOpNode NameOp object node defining a named object.
921 If provided, append the new resource data
922 node to the list of resource data elements
923 of this node.
924 @param [out] NewRdNode If provided and success,
925 contain the created node.
926
927 @retval EFI_SUCCESS The function completed successfully.
928 @retval EFI_INVALID_PARAMETER Invalid parameter.
929 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
930 **/
931 STATIC
932 EFI_STATUS
933 EFIAPI
934 AmlCodeGenRdQWordSpace (
935 IN UINT8 ResourceType,
936 IN BOOLEAN IsResourceConsumer,
937 IN BOOLEAN IsPosDecode,
938 IN BOOLEAN IsMinFixed,
939 IN BOOLEAN IsMaxFixed,
940 IN UINT8 TypeSpecificFlags,
941 IN UINT64 AddressGranularity,
942 IN UINT64 AddressMinimum,
943 IN UINT64 AddressMaximum,
944 IN UINT64 AddressTranslation,
945 IN UINT64 RangeLength,
946 IN UINT8 ResourceSourceIndex,
947 IN CONST CHAR8 *ResourceSource,
948 IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
949 OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
950 )
951 {
952 EFI_STATUS Status;
953 AML_DATA_NODE *RdNode;
954 EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR RdQword;
955
956 // ResourceSource and ResourceSourceIndex are unused.
957 if ((TypeSpecificFlags == MAX_UINT8) ||
958 (ResourceSourceIndex != 0) ||
959 (ResourceSource != NULL) ||
960 ((NameOpNode == NULL) && (NewRdNode == NULL)))
961 {
962 ASSERT (0);
963 return EFI_INVALID_PARAMETER;
964 }
965
966 Status = CheckAddressSpaceFields (
967 IsMinFixed,
968 IsMaxFixed,
969 AddressGranularity,
970 AddressMinimum,
971 AddressMaximum,
972 AddressTranslation,
973 RangeLength
974 );
975 if (EFI_ERROR (Status)) {
976 ASSERT (0);
977 return Status;
978 }
979
980 // Header
981 RdQword.Header.Header.Bits.Name =
982 ACPI_LARGE_QWORD_ADDRESS_SPACE_DESCRIPTOR_NAME;
983 RdQword.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
984 RdQword.Header.Length = sizeof (EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR) -
985 sizeof (ACPI_LARGE_RESOURCE_HEADER);
986
987 // Body
988 RdQword.ResType = ResourceType;
989 RdQword.GenFlag = AddressSpaceGeneralFlags (
990 IsPosDecode,
991 IsMinFixed,
992 IsMaxFixed
993 );
994 RdQword.SpecificFlag = TypeSpecificFlags;
995 RdQword.AddrSpaceGranularity = AddressGranularity;
996 RdQword.AddrRangeMin = AddressMinimum;
997 RdQword.AddrRangeMax = AddressMaximum;
998 RdQword.AddrTranslationOffset = AddressTranslation;
999 RdQword.AddrLen = RangeLength;
1000
1001 Status = AmlCreateDataNode (
1002 EAmlNodeDataTypeResourceData,
1003 (UINT8 *)&RdQword,
1004 sizeof (EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR),
1005 &RdNode
1006 );
1007 if (EFI_ERROR (Status)) {
1008 ASSERT (0);
1009 return Status;
1010 }
1011
1012 return LinkRdNode (RdNode, NameOpNode, NewRdNode);
1013 }
1014
1015 /** Code generation for the "QWordMemory ()" ASL function.
1016
1017 The Resource Data effectively created is a QWord Address Space Resource
1018 Data. Cf ACPI 6.4:
1019 - s6.4.3.5.1 "QWord Address Space Descriptor".
1020 - s19.6.110 "QWordMemory".
1021
1022 The created resource data node can be:
1023 - appended to the list of resource data elements of the NameOpNode.
1024 In such case NameOpNode must be defined by a the "Name ()" ASL statement
1025 and initially contain a "ResourceTemplate ()".
1026 - returned through the NewRdNode parameter.
1027
1028 See ACPI 6.4 spec, s19.6.110 for more.
1029
1030 @param [in] IsResourceConsumer ResourceUsage parameter.
1031 @param [in] IsPosDecode Decode parameter.
1032 @param [in] IsMinFixed Minimum address is fixed.
1033 @param [in] IsMaxFixed Maximum address is fixed.
1034 @param [in] Cacheable Possible values are:
1035 0-The memory is non-cacheable
1036 1-The memory is cacheable
1037 2-The memory is cacheable and supports
1038 write combining
1039 3-The memory is cacheable and prefetchable
1040 @param [in] IsReadWrite ReadAndWrite parameter.
1041 @param [in] AddressGranularity Address granularity.
1042 @param [in] AddressMinimum Minimum address.
1043 @param [in] AddressMaximum Maximum address.
1044 @param [in] AddressTranslation Address translation.
1045 @param [in] RangeLength Range length.
1046 @param [in] ResourceSourceIndex Resource Source index.
1047 Unused. Must be 0.
1048 @param [in] ResourceSource Resource Source.
1049 Unused. Must be NULL.
1050 @param [in] MemoryRangeType Possible values are:
1051 0-AddressRangeMemory
1052 1-AddressRangeReserved
1053 2-AddressRangeACPI
1054 3-AddressRangeNVS
1055 @param [in] IsTypeStatic TranslationType parameter.
1056 @param [in] NameOpNode NameOp object node defining a named object.
1057 If provided, append the new resource data
1058 node to the list of resource data elements
1059 of this node.
1060 @param [out] NewRdNode If provided and success,
1061 contain the created node.
1062
1063 @retval EFI_SUCCESS The function completed successfully.
1064 @retval EFI_INVALID_PARAMETER Invalid parameter.
1065 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
1066 **/
1067 EFI_STATUS
1068 EFIAPI
1069 AmlCodeGenRdQWordMemory (
1070 IN BOOLEAN IsResourceConsumer,
1071 IN BOOLEAN IsPosDecode,
1072 IN BOOLEAN IsMinFixed,
1073 IN BOOLEAN IsMaxFixed,
1074 IN UINT8 Cacheable,
1075 IN BOOLEAN IsReadWrite,
1076 IN UINT64 AddressGranularity,
1077 IN UINT64 AddressMinimum,
1078 IN UINT64 AddressMaximum,
1079 IN UINT64 AddressTranslation,
1080 IN UINT64 RangeLength,
1081 IN UINT8 ResourceSourceIndex,
1082 IN CONST CHAR8 *ResourceSource,
1083 IN UINT8 MemoryRangeType,
1084 IN BOOLEAN IsTypeStatic,
1085 IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
1086 OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
1087 )
1088 {
1089 return AmlCodeGenRdQWordSpace (
1090 ACPI_ADDRESS_SPACE_TYPE_MEM,
1091 IsResourceConsumer,
1092 IsPosDecode,
1093 IsMinFixed,
1094 IsMaxFixed,
1095 MemoryRangeSpecificFlags (
1096 Cacheable,
1097 IsReadWrite,
1098 MemoryRangeType,
1099 IsTypeStatic
1100 ),
1101 AddressGranularity,
1102 AddressMinimum,
1103 AddressMaximum,
1104 AddressTranslation,
1105 RangeLength,
1106 ResourceSourceIndex,
1107 ResourceSource,
1108 NameOpNode,
1109 NewRdNode
1110 );
1111 }
1112
1113 /** Code generation for the "Interrupt ()" ASL function.
1114
1115 The Resource Data effectively created is an Extended Interrupt Resource
1116 Data. Cf ACPI 6.4:
1117 - s6.4.3.6 "Extended Interrupt Descriptor"
1118 - s19.6.64 "Interrupt (Interrupt Resource Descriptor Macro)"
1119
1120 The created resource data node can be:
1121 - appended to the list of resource data elements of the NameOpNode.
1122 In such case NameOpNode must be defined by a the "Name ()" ASL statement
1123 and initially contain a "ResourceTemplate ()".
1124 - returned through the NewRdNode parameter.
1125
1126 @param [in] ResourceConsumer The device consumes the specified interrupt
1127 or produces it for use by a child device.
1128 @param [in] EdgeTriggered The interrupt is edge triggered or
1129 level triggered.
1130 @param [in] ActiveLow The interrupt is active-high or active-low.
1131 @param [in] Shared The interrupt can be shared with other
1132 devices or not (Exclusive).
1133 @param [in] IrqList Interrupt list. Must be non-NULL.
1134 @param [in] IrqCount Interrupt count. Must be non-zero.
1135 @param [in] NameOpNode NameOp object node defining a named object.
1136 If provided, append the new resource data node
1137 to the list of resource data elements of this
1138 node.
1139 @param [out] NewRdNode If provided and success,
1140 contain the created node.
1141
1142 @retval EFI_SUCCESS The function completed successfully.
1143 @retval EFI_INVALID_PARAMETER Invalid parameter.
1144 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
1145 **/
1146 EFI_STATUS
1147 EFIAPI
1148 AmlCodeGenRdInterrupt (
1149 IN BOOLEAN ResourceConsumer,
1150 IN BOOLEAN EdgeTriggered,
1151 IN BOOLEAN ActiveLow,
1152 IN BOOLEAN Shared,
1153 IN UINT32 *IrqList,
1154 IN UINT8 IrqCount,
1155 IN AML_OBJECT_NODE_HANDLE NameOpNode OPTIONAL,
1156 OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
1157 )
1158 {
1159 EFI_STATUS Status;
1160
1161 AML_DATA_NODE *RdNode;
1162 EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR RdInterrupt;
1163 UINT32 *FirstInterrupt;
1164
1165 if ((IrqList == NULL) ||
1166 (IrqCount == 0) ||
1167 ((NameOpNode == NULL) && (NewRdNode == NULL)))
1168 {
1169 ASSERT (0);
1170 return EFI_INVALID_PARAMETER;
1171 }
1172
1173 // Header
1174 RdInterrupt.Header.Header.Bits.Name =
1175 ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME;
1176 RdInterrupt.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
1177 RdInterrupt.Header.Length = sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR) -
1178 sizeof (ACPI_LARGE_RESOURCE_HEADER);
1179
1180 // Body
1181 RdInterrupt.InterruptVectorFlags = (ResourceConsumer ? BIT0 : 0) |
1182 (EdgeTriggered ? BIT1 : 0) |
1183 (ActiveLow ? BIT2 : 0) |
1184 (Shared ? BIT3 : 0);
1185 RdInterrupt.InterruptTableLength = IrqCount;
1186
1187 // Get the address of the first interrupt field.
1188 FirstInterrupt = RdInterrupt.InterruptNumber;
1189
1190 // Copy the list of interrupts.
1191 CopyMem (FirstInterrupt, IrqList, (sizeof (UINT32) * IrqCount));
1192
1193 Status = AmlCreateDataNode (
1194 EAmlNodeDataTypeResourceData,
1195 (UINT8 *)&RdInterrupt,
1196 sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR),
1197 &RdNode
1198 );
1199 if (EFI_ERROR (Status)) {
1200 ASSERT (0);
1201 return Status;
1202 }
1203
1204 return LinkRdNode (RdNode, NameOpNode, NewRdNode);
1205 }
1206
1207 /** Code generation for the "Register ()" ASL function.
1208
1209 The Resource Data effectively created is a Generic Register Descriptor.
1210 Data. Cf ACPI 6.4:
1211 - s6.4.3.7 "Generic Register Descriptor".
1212 - s19.6.114 "Register".
1213
1214 The created resource data node can be:
1215 - appended to the list of resource data elements of the NameOpNode.
1216 In such case NameOpNode must be defined by a the "Name ()" ASL statement
1217 and initially contain a "ResourceTemplate ()".
1218 - returned through the NewRdNode parameter.
1219
1220 @param [in] AddressSpace Address space where the register exists.
1221 Can be one of I/O space, System Memory, etc.
1222 @param [in] BitWidth Number of bits in the register.
1223 @param [in] BitOffset Offset in bits from the start of the register
1224 indicated by the Address.
1225 @param [in] Address Register address.
1226 @param [in] AccessSize Size of data values used when accessing the
1227 address space. Can be one of:
1228 0 - Undefined, legacy (EFI_ACPI_6_4_UNDEFINED)
1229 1 - Byte access (EFI_ACPI_6_4_BYTE)
1230 2 - Word access (EFI_ACPI_6_4_WORD)
1231 3 - DWord access (EFI_ACPI_6_4_DWORD)
1232 4 - QWord access (EFI_ACPI_6_4_QWORD)
1233 @param [in] NameOpNode NameOp object node defining a named object.
1234 If provided, append the new resource data node
1235 to the list of resource data elements of this
1236 node.
1237 @param [out] NewRdNode If provided and success,
1238 contain the created node.
1239
1240 @retval EFI_SUCCESS The function completed successfully.
1241 @retval EFI_INVALID_PARAMETER Invalid parameter.
1242 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
1243 **/
1244 EFI_STATUS
1245 EFIAPI
1246 AmlCodeGenRdRegister (
1247 IN UINT8 AddressSpace,
1248 IN UINT8 BitWidth,
1249 IN UINT8 BitOffset,
1250 IN UINT64 Address,
1251 IN UINT8 AccessSize,
1252 IN AML_OBJECT_NODE_HANDLE NameOpNode OPTIONAL,
1253 OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
1254 )
1255 {
1256 EFI_STATUS Status;
1257 AML_DATA_NODE *RdNode;
1258 EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR RdRegister;
1259
1260 // Cf. ACPI 6.4, s14.7 Referencing the PCC address space
1261 // The AccessSize represents the Subspace Id for the PCC address space.
1262 if (((AddressSpace == EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL) &&
1263 (AccessSize > 256)) ||
1264 ((AddressSpace != EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL) &&
1265 (AccessSize > EFI_ACPI_6_4_QWORD)) ||
1266 ((NameOpNode == NULL) && (NewRdNode == NULL)))
1267 {
1268 ASSERT (0);
1269 return EFI_INVALID_PARAMETER;
1270 }
1271
1272 // Header
1273 RdRegister.Header.Header.Bits.Name =
1274 ACPI_LARGE_GENERIC_REGISTER_DESCRIPTOR_NAME;
1275 RdRegister.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
1276 RdRegister.Header.Length = sizeof (EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR) -
1277 sizeof (ACPI_LARGE_RESOURCE_HEADER);
1278
1279 // Body
1280 RdRegister.AddressSpaceId = AddressSpace;
1281 RdRegister.RegisterBitWidth = BitWidth;
1282 RdRegister.RegisterBitOffset = BitOffset;
1283 RdRegister.AddressSize = AccessSize;
1284 RdRegister.RegisterAddress = Address;
1285
1286 Status = AmlCreateDataNode (
1287 EAmlNodeDataTypeResourceData,
1288 (UINT8 *)&RdRegister,
1289 sizeof (EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR),
1290 &RdNode
1291 );
1292 if (EFI_ERROR (Status)) {
1293 ASSERT (0);
1294 return Status;
1295 }
1296
1297 return LinkRdNode (RdNode, NameOpNode, NewRdNode);
1298 }
1299
1300 /** Code generation for the EndTag resource data.
1301
1302 The EndTag resource data is automatically generated by the ASL compiler
1303 at the end of a list of resource data elements. Thus, it doesn't have
1304 a corresponding ASL function.
1305
1306 This function allocates memory to create a data node. It is the caller's
1307 responsibility to either:
1308 - attach this node to an AML tree;
1309 - delete this node.
1310
1311 ACPI 6.4, s6.4.2.9 "End Tag":
1312 "This checksum is generated such that adding it to the sum of all the data
1313 bytes will produce a zero sum."
1314 "If the checksum field is zero, the resource data is treated as if the
1315 checksum operation succeeded. Configuration proceeds normally."
1316
1317 To avoid re-computing checksums, if a new resource data elements is
1318 added/removed/modified in a list of resource data elements, the AmlLib
1319 resets the checksum to 0.
1320
1321 @param [in] CheckSum CheckSum to store in the EndTag.
1322 To ignore/avoid computing the checksum,
1323 give 0.
1324 @param [in] ParentNode If not NULL, add the generated node
1325 to the end of the variable list of
1326 argument of the ParentNode.
1327 The ParentNode must not initially contain
1328 an EndTag resource data element.
1329 @param [out] NewRdNode If success, contains the generated node.
1330
1331 @retval EFI_SUCCESS The function completed successfully.
1332 @retval EFI_INVALID_PARAMETER Invalid parameter.
1333 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
1334 **/
1335 EFI_STATUS
1336 EFIAPI
1337 AmlCodeGenEndTag (
1338 IN UINT8 CheckSum OPTIONAL,
1339 IN AML_OBJECT_NODE *ParentNode OPTIONAL,
1340 OUT AML_DATA_NODE **NewRdNode OPTIONAL
1341 )
1342 {
1343 EFI_STATUS Status;
1344 AML_DATA_NODE *RdNode;
1345 EFI_ACPI_END_TAG_DESCRIPTOR EndTag;
1346 ACPI_SMALL_RESOURCE_HEADER SmallResHdr;
1347
1348 if ((ParentNode == NULL) && (NewRdNode == NULL)) {
1349 ASSERT (0);
1350 return EFI_INVALID_PARAMETER;
1351 }
1352
1353 RdNode = NULL;
1354
1355 // Header
1356 SmallResHdr.Bits.Length = sizeof (EFI_ACPI_END_TAG_DESCRIPTOR) -
1357 sizeof (ACPI_SMALL_RESOURCE_HEADER);
1358 SmallResHdr.Bits.Name = ACPI_SMALL_END_TAG_DESCRIPTOR_NAME;
1359 SmallResHdr.Bits.Type = ACPI_SMALL_ITEM_FLAG;
1360
1361 // Body
1362 EndTag.Desc = SmallResHdr.Byte;
1363 EndTag.Checksum = CheckSum;
1364
1365 Status = AmlCreateDataNode (
1366 EAmlNodeDataTypeResourceData,
1367 (UINT8 *)&EndTag,
1368 sizeof (EFI_ACPI_END_TAG_DESCRIPTOR),
1369 &RdNode
1370 );
1371 if (EFI_ERROR (Status)) {
1372 ASSERT (0);
1373 return Status;
1374 }
1375
1376 if (NewRdNode != NULL) {
1377 *NewRdNode = RdNode;
1378 }
1379
1380 if (ParentNode != NULL) {
1381 // Check the BufferOp doesn't contain any resource data yet.
1382 // This is a hard check: do not allow to add an EndTag if the BufferNode
1383 // already has resource data elements attached. Indeed, the EndTag should
1384 // have already been added.
1385 if (AmlGetNextVariableArgument ((AML_NODE_HEADER *)ParentNode, NULL) !=
1386 NULL)
1387 {
1388 ASSERT (0);
1389 Status = EFI_INVALID_PARAMETER;
1390 goto error_handler;
1391 }
1392
1393 // Add the EndTag RdNode. Indeed, the AmlAppendRdNode function
1394 // is looking for an EndTag, which we are adding here.
1395 Status = AmlVarListAddTail (
1396 (AML_NODE_HEADER *)ParentNode,
1397 (AML_NODE_HEADER *)RdNode
1398 );
1399 if (EFI_ERROR (Status)) {
1400 ASSERT (0);
1401 goto error_handler;
1402 }
1403 }
1404
1405 return Status;
1406
1407 error_handler:
1408 if (RdNode != NULL) {
1409 AmlDeleteTree ((AML_NODE_HEADER *)RdNode);
1410 }
1411
1412 return Status;
1413 }