]> git.proxmox.com Git - mirror_edk2.git/blame - DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
DynamicTablesPkg: AML code generation to Return a NameString
[mirror_edk2.git] / DynamicTablesPkg / Library / Common / AmlLib / CodeGen / AmlCodeGen.c
CommitLineData
3a681567
PG
1/** @file\r
2 AML Code Generation.\r
3\r
1e33479b 4 Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>\r
3a681567
PG
5\r
6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
7**/\r
8\r
9#include <AmlNodeDefines.h>\r
10\r
11#include <AcpiTableGenerator.h>\r
12\r
13#include <AmlCoreInterface.h>\r
14#include <AmlEncoding/Aml.h>\r
ce15936f 15#include <CodeGen/AmlResourceDataCodeGen.h>\r
3a681567
PG
16#include <Tree/AmlNode.h>\r
17#include <Tree/AmlTree.h>\r
18#include <String/AmlString.h>\r
19#include <Utils/AmlUtility.h>\r
20\r
21/** Utility function to link a node when returning from a CodeGen function.\r
22\r
23 @param [in] Node Newly created node.\r
24 @param [in] ParentNode If provided, set ParentNode as the parent\r
25 of the node created.\r
2dd7dd39
PG
26 @param [out] NewObjectNode If not NULL:\r
27 - and Success, contains the created Node.\r
28 - and Error, reset to NULL.\r
3a681567
PG
29\r
30 @retval EFI_SUCCESS The function completed successfully.\r
31 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
32**/\r
33STATIC\r
34EFI_STATUS\r
35EFIAPI\r
36LinkNode (\r
37 IN AML_OBJECT_NODE * Node,\r
38 IN AML_NODE_HEADER * ParentNode,\r
5e0b708f 39 OUT AML_OBJECT_NODE ** NewObjectNode\r
3a681567
PG
40 )\r
41{\r
42 EFI_STATUS Status;\r
43\r
44 if (NewObjectNode != NULL) {\r
2dd7dd39 45 *NewObjectNode = NULL;\r
3a681567
PG
46 }\r
47\r
48 // Add RdNode as the last element.\r
49 if (ParentNode != NULL) {\r
50 Status = AmlVarListAddTail (ParentNode, (AML_NODE_HEADER*)Node);\r
51 if (EFI_ERROR (Status)) {\r
52 ASSERT (0);\r
53 return Status;\r
54 }\r
55 }\r
56\r
2dd7dd39
PG
57 if (NewObjectNode != NULL) {\r
58 *NewObjectNode = Node;\r
59 }\r
60\r
3a681567
PG
61 return EFI_SUCCESS;\r
62}\r
63\r
64/** AML code generation for DefinitionBlock.\r
65\r
66 Create a Root Node handle.\r
67 It is the caller's responsibility to free the allocated memory\r
68 with the AmlDeleteTree function.\r
69\r
70 AmlCodeGenDefinitionBlock (TableSignature, OemID, TableID, OEMRevision) is\r
71 equivalent to the following ASL code:\r
72 DefinitionBlock (AMLFileName, TableSignature, ComplianceRevision,\r
73 OemID, TableID, OEMRevision) {}\r
74 with the ComplianceRevision set to 2 and the AMLFileName is ignored.\r
75\r
76 @param[in] TableSignature 4-character ACPI signature.\r
77 Must be 'DSDT' or 'SSDT'.\r
78 @param[in] OemId 6-character string OEM identifier.\r
79 @param[in] OemTableId 8-character string OEM table identifier.\r
80 @param[in] OemRevision OEM revision number.\r
5e0b708f 81 @param[out] NewRootNode Pointer to the root node representing a\r
3a681567
PG
82 Definition Block.\r
83\r
84 @retval EFI_SUCCESS Success.\r
85 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
86 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
87**/\r
88EFI_STATUS\r
89EFIAPI\r
90AmlCodeGenDefinitionBlock (\r
91 IN CONST CHAR8 * TableSignature,\r
92 IN CONST CHAR8 * OemId,\r
93 IN CONST CHAR8 * OemTableId,\r
94 IN UINT32 OemRevision,\r
95 OUT AML_ROOT_NODE ** NewRootNode\r
96 )\r
97{\r
98 EFI_STATUS Status;\r
99 EFI_ACPI_DESCRIPTION_HEADER AcpiHeader;\r
100\r
101 if ((TableSignature == NULL) ||\r
102 (OemId == NULL) ||\r
103 (OemTableId == NULL) ||\r
104 (NewRootNode == NULL)) {\r
105 ASSERT (0);\r
106 return EFI_INVALID_PARAMETER;\r
107 }\r
108\r
109 CopyMem (&AcpiHeader.Signature, TableSignature, 4);\r
110 AcpiHeader.Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);\r
111 AcpiHeader.Revision = 2;\r
112 CopyMem (&AcpiHeader.OemId, OemId, 6);\r
113 CopyMem (&AcpiHeader.OemTableId, OemTableId, 8);\r
114 AcpiHeader.OemRevision = OemRevision;\r
115 AcpiHeader.CreatorId = TABLE_GENERATOR_CREATOR_ID_ARM;\r
116 AcpiHeader.CreatorRevision = CREATE_REVISION (1, 0);\r
117\r
118 Status = AmlCreateRootNode (&AcpiHeader, NewRootNode);\r
119 ASSERT_EFI_ERROR (Status);\r
120\r
121 return Status;\r
122}\r
123\r
124/** AML code generation for a String object node.\r
125\r
126 @param [in] String Pointer to a NULL terminated string.\r
127 @param [out] NewObjectNode If success, contains the created\r
128 String object node.\r
129\r
130 @retval EFI_SUCCESS Success.\r
131 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
132 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
133**/\r
134STATIC\r
135EFI_STATUS\r
136EFIAPI\r
137AmlCodeGenString (\r
138 IN CHAR8 * String,\r
139 OUT AML_OBJECT_NODE ** NewObjectNode\r
140 )\r
141{\r
142 EFI_STATUS Status;\r
143 AML_OBJECT_NODE * ObjectNode;\r
144 AML_DATA_NODE * DataNode;\r
145\r
146 if ((String == NULL) ||\r
147 (NewObjectNode == NULL)) {\r
148 ASSERT (0);\r
149 return EFI_INVALID_PARAMETER;\r
150 }\r
151\r
3a681567
PG
152 DataNode = NULL;\r
153\r
154 Status = AmlCreateObjectNode (\r
155 AmlGetByteEncodingByOpCode (AML_STRING_PREFIX, 0),\r
156 0,\r
157 &ObjectNode\r
158 );\r
159 if (EFI_ERROR (Status)) {\r
160 ASSERT (0);\r
161 return Status;\r
162 }\r
163\r
164 Status = AmlCreateDataNode (\r
165 EAmlNodeDataTypeString,\r
166 (UINT8*)String,\r
167 (UINT32)AsciiStrLen (String) + 1,\r
168 &DataNode\r
169 );\r
170 if (EFI_ERROR (Status)) {\r
171 ASSERT (0);\r
172 goto error_handler;\r
173 }\r
174\r
175 Status = AmlSetFixedArgument (\r
176 ObjectNode,\r
177 EAmlParseIndexTerm0,\r
178 (AML_NODE_HEADER*)DataNode\r
179 );\r
180 if (EFI_ERROR (Status)) {\r
181 ASSERT (0);\r
182 AmlDeleteTree ((AML_NODE_HEADER*)DataNode);\r
183 goto error_handler;\r
184 }\r
185\r
186 *NewObjectNode = ObjectNode;\r
187 return Status;\r
188\r
189error_handler:\r
37bd0817 190 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
3a681567
PG
191 return Status;\r
192}\r
193\r
194/** AML code generation for an Integer object node.\r
195\r
196 @param [in] Integer Integer of the Integer object node.\r
197 @param [out] NewObjectNode If success, contains the created\r
198 Integer object node.\r
199\r
200 @retval EFI_SUCCESS Success.\r
201 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
202 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
203**/\r
204STATIC\r
205EFI_STATUS\r
206EFIAPI\r
207AmlCodeGenInteger (\r
208 IN UINT64 Integer,\r
209 OUT AML_OBJECT_NODE ** NewObjectNode\r
210 )\r
211{\r
212 EFI_STATUS Status;\r
213 INT8 ValueWidthDiff;\r
214\r
215 if (NewObjectNode == NULL) {\r
216 ASSERT (0);\r
217 return EFI_INVALID_PARAMETER;\r
218 }\r
219\r
220 // Create an object node containing Zero.\r
221 Status = AmlCreateObjectNode (\r
222 AmlGetByteEncodingByOpCode (AML_ZERO_OP, 0),\r
223 0,\r
224 NewObjectNode\r
225 );\r
226 if (EFI_ERROR (Status)) {\r
227 ASSERT (0);\r
228 return Status;\r
229 }\r
230\r
231 // Update the object node with integer value.\r
232 Status = AmlNodeSetIntegerValue (*NewObjectNode, Integer, &ValueWidthDiff);\r
233 if (EFI_ERROR (Status)) {\r
234 ASSERT (0);\r
235 AmlDeleteTree ((AML_NODE_HEADER*)*NewObjectNode);\r
236 }\r
237\r
238 return Status;\r
239}\r
240\r
1e33479b
PG
241/** AML code generation for a Package object node.\r
242\r
243 The package generated is empty. New elements can be added via its\r
244 list of variable arguments.\r
245\r
246 @param [out] NewObjectNode If success, contains the created\r
247 Package object node.\r
248\r
249 @retval EFI_SUCCESS Success.\r
250 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
251 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
252**/\r
253STATIC\r
254EFI_STATUS\r
255EFIAPI\r
256AmlCodeGenPackage (\r
257 OUT AML_OBJECT_NODE ** NewObjectNode\r
258 )\r
259{\r
260 EFI_STATUS Status;\r
261 AML_DATA_NODE * DataNode;\r
262 UINT8 NodeCount;\r
263\r
264 if (NewObjectNode == NULL) {\r
265 ASSERT (0);\r
266 return EFI_INVALID_PARAMETER;\r
267 }\r
268\r
269 NodeCount = 0;\r
270\r
271 // Create an object node.\r
272 // PkgLen is 2:\r
273 // - one byte to store the PkgLength\r
274 // - one byte for the NumElements.\r
275 // Cf ACPI6.3, s20.2.5 "Term Objects Encoding"\r
276 // DefPackage := PackageOp PkgLength NumElements PackageElementList\r
277 // NumElements := ByteData\r
278 Status = AmlCreateObjectNode (\r
279 AmlGetByteEncodingByOpCode (AML_PACKAGE_OP, 0),\r
280 2,\r
281 NewObjectNode\r
282 );\r
283 if (EFI_ERROR (Status)) {\r
284 ASSERT (0);\r
285 return Status;\r
286 }\r
287\r
288 // NumElements is a ByteData.\r
289 Status = AmlCreateDataNode (\r
290 EAmlNodeDataTypeUInt,\r
291 &NodeCount,\r
292 sizeof (NodeCount),\r
293 &DataNode\r
294 );\r
295 if (EFI_ERROR (Status)) {\r
296 ASSERT (0);\r
297 goto error_handler;\r
298 }\r
299\r
300 Status = AmlSetFixedArgument (\r
301 *NewObjectNode,\r
302 EAmlParseIndexTerm0,\r
303 (AML_NODE_HEADER*)DataNode\r
304 );\r
305 if (EFI_ERROR (Status)) {\r
306 ASSERT (0);\r
307 goto error_handler;\r
308 }\r
309\r
310 return Status;\r
311\r
312error_handler:\r
313 AmlDeleteTree ((AML_NODE_HEADER*)*NewObjectNode);\r
314 if (DataNode != NULL) {\r
315 AmlDeleteTree ((AML_NODE_HEADER*)DataNode);\r
316 }\r
317 return Status;\r
318}\r
319\r
ce15936f
PG
320/** AML code generation for a Buffer object node.\r
321\r
322 To create a Buffer object node with an empty buffer,\r
323 call the function with (Buffer=NULL, BufferSize=0).\r
324\r
325 @param [in] Buffer Buffer to set for the created Buffer\r
326 object node. The Buffer's content is copied.\r
327 NULL if there is no buffer to set for\r
328 the Buffer node.\r
329 @param [in] BufferSize Size of the Buffer.\r
330 0 if there is no buffer to set for\r
331 the Buffer node.\r
332 @param [out] NewObjectNode If success, contains the created\r
333 Buffer object node.\r
334\r
335 @retval EFI_SUCCESS Success.\r
336 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
337 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
338**/\r
339STATIC\r
340EFI_STATUS\r
341EFIAPI\r
342AmlCodeGenBuffer (\r
343 IN CONST UINT8 * Buffer, OPTIONAL\r
344 IN UINT32 BufferSize, OPTIONAL\r
345 OUT AML_OBJECT_NODE ** NewObjectNode\r
346 )\r
347{\r
348 EFI_STATUS Status;\r
349 AML_OBJECT_NODE * BufferNode;\r
350 AML_OBJECT_NODE * BufferSizeNode;\r
351 UINT32 BufferSizeNodeSize;\r
352 AML_DATA_NODE * DataNode;\r
353 UINT32 PkgLen;\r
354\r
355 // Buffer and BufferSize must be either both set, or both clear.\r
356 if ((NewObjectNode == NULL) ||\r
357 ((Buffer == NULL) != (BufferSize == 0))) {\r
358 ASSERT (0);\r
359 return EFI_INVALID_PARAMETER;\r
360 }\r
361\r
362 BufferNode = NULL;\r
363 DataNode = NULL;\r
364\r
365 // Cf ACPI 6.3 specification, s20.2.5.4 "Type 2 Opcodes Encoding"\r
366 // DefBuffer := BufferOp PkgLength BufferSize ByteList\r
367 // BufferOp := 0x11\r
368 // BufferSize := TermArg => Integer\r
369\r
370 Status = AmlCodeGenInteger (BufferSize, &BufferSizeNode);\r
371 if (EFI_ERROR (Status)) {\r
372 ASSERT (0);\r
373 return Status;\r
374 }\r
375\r
376 // Get the number of bytes required to encode the BufferSizeNode.\r
377 Status = AmlComputeSize (\r
378 (AML_NODE_HEADER*)BufferSizeNode,\r
379 &BufferSizeNodeSize\r
380 );\r
381 if (EFI_ERROR (Status)) {\r
382 ASSERT (0);\r
383 goto error_handler;\r
384 }\r
385\r
386 // Compute the size to write in the PkgLen.\r
387 Status = AmlComputePkgLength (BufferSizeNodeSize + BufferSize, &PkgLen);\r
388 if (EFI_ERROR (Status)) {\r
389 ASSERT (0);\r
390 goto error_handler;\r
391 }\r
392\r
393 // Create an object node for the buffer.\r
394 Status = AmlCreateObjectNode (\r
395 AmlGetByteEncodingByOpCode (AML_BUFFER_OP, 0),\r
396 PkgLen,\r
397 &BufferNode\r
398 );\r
399 if (EFI_ERROR (Status)) {\r
400 ASSERT (0);\r
401 goto error_handler;\r
402 }\r
403\r
404 // Set the BufferSizeNode as a fixed argument of the BufferNode.\r
405 Status = AmlSetFixedArgument (\r
406 BufferNode,\r
407 EAmlParseIndexTerm0,\r
408 (AML_NODE_HEADER*)BufferSizeNode\r
409 );\r
410 if (EFI_ERROR (Status)) {\r
411 ASSERT (0);\r
412 goto error_handler;\r
413 }\r
414\r
415 // BufferSizeNode is now attached.\r
416 BufferSizeNode = NULL;\r
417\r
418 // If there is a buffer, create a DataNode and attach it to the BufferNode.\r
419 if (Buffer != NULL) {\r
420 Status = AmlCreateDataNode (\r
421 EAmlNodeDataTypeRaw,\r
422 Buffer,\r
423 BufferSize,\r
424 &DataNode\r
425 );\r
426 if (EFI_ERROR (Status)) {\r
427 ASSERT (0);\r
428 goto error_handler;\r
429 }\r
430\r
431 Status = AmlVarListAddTail (\r
432 (AML_NODE_HEADER*)BufferNode,\r
433 (AML_NODE_HEADER*)DataNode\r
434 );\r
435 if (EFI_ERROR (Status)) {\r
436 ASSERT (0);\r
437 goto error_handler;\r
438 }\r
439 }\r
440\r
441 *NewObjectNode = BufferNode;\r
442 return Status;\r
443\r
444error_handler:\r
445 if (BufferSizeNode != NULL) {\r
446 AmlDeleteTree ((AML_NODE_HEADER*)BufferSizeNode);\r
447 }\r
448 if (BufferNode != NULL) {\r
449 AmlDeleteTree ((AML_NODE_HEADER*)BufferNode);\r
450 }\r
451 if (DataNode != NULL) {\r
452 AmlDeleteTree ((AML_NODE_HEADER*)DataNode);\r
453 }\r
454 return Status;\r
455}\r
456\r
457/** AML code generation for a ResourceTemplate.\r
458\r
459 "ResourceTemplate" is a macro defined in ACPI 6.3, s19.3.3\r
460 "ASL Resource Templates". It allows to store resource data elements.\r
461\r
462 In AML, a ResourceTemplate is implemented as a Buffer storing resource\r
463 data elements. An EndTag resource data descriptor must be at the end\r
464 of the list of resource data elements.\r
465 This function generates a Buffer node with an EndTag resource data\r
466 descriptor. It can be seen as an empty list of resource data elements.\r
467\r
468 @param [out] NewObjectNode If success, contains the created\r
469 ResourceTemplate object node.\r
470\r
471 @retval EFI_SUCCESS Success.\r
472 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
473 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
474**/\r
475STATIC\r
476EFI_STATUS\r
477EFIAPI\r
478AmlCodeGenResourceTemplate (\r
479 OUT AML_OBJECT_NODE ** NewObjectNode\r
480 )\r
481{\r
482 EFI_STATUS Status;\r
483 AML_OBJECT_NODE * BufferNode;\r
484\r
485 if (NewObjectNode == NULL) {\r
486 ASSERT (0);\r
487 return EFI_INVALID_PARAMETER;\r
488 }\r
489\r
490 // Create a BufferNode with an empty buffer.\r
491 Status = AmlCodeGenBuffer (NULL, 0, &BufferNode);\r
492 if (EFI_ERROR (Status)) {\r
493 ASSERT (0);\r
494 return Status;\r
495 }\r
496\r
497 // Create an EndTag resource data element and attach it to the Buffer.\r
498 Status = AmlCodeGenEndTag (0, BufferNode, NULL);\r
499 if (EFI_ERROR (Status)) {\r
500 ASSERT (0);\r
501 AmlDeleteTree ((AML_NODE_HEADER*)BufferNode);\r
502 return Status;\r
503 }\r
504\r
505 *NewObjectNode = BufferNode;\r
506 return Status;\r
507}\r
508\r
3a681567
PG
509/** AML code generation for a Name object node.\r
510\r
511 @param [in] NameString The new variable name.\r
512 Must be a NULL-terminated ASL NameString\r
513 e.g.: "DEV0", "DV15.DEV0", etc.\r
514 This input string is copied.\r
515 @param [in] Object Object associated to the NameString.\r
516 @param [in] ParentNode If provided, set ParentNode as the parent\r
517 of the node created.\r
518 @param [out] NewObjectNode If success, contains the created node.\r
519\r
520 @retval EFI_SUCCESS Success.\r
521 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
522 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
523**/\r
524STATIC\r
525EFI_STATUS\r
526EFIAPI\r
527AmlCodeGenName (\r
528 IN CONST CHAR8 * NameString,\r
529 IN AML_OBJECT_NODE * Object,\r
530 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
531 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
532 )\r
533{\r
534 EFI_STATUS Status;\r
535 AML_OBJECT_NODE * ObjectNode;\r
536 AML_DATA_NODE * DataNode;\r
537 CHAR8 * AmlNameString;\r
538 UINT32 AmlNameStringSize;\r
539\r
540 if ((NameString == NULL) ||\r
541 (Object == NULL) ||\r
542 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
543 ASSERT (0);\r
544 return EFI_INVALID_PARAMETER;\r
545 }\r
546\r
547 ObjectNode = NULL;\r
548 DataNode = NULL;\r
549 AmlNameString = NULL;\r
550\r
551 Status = ConvertAslNameToAmlName (NameString, &AmlNameString);\r
552 if (EFI_ERROR (Status)) {\r
553 ASSERT (0);\r
554 return Status;\r
555 }\r
556\r
557 Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);\r
558 if (EFI_ERROR (Status)) {\r
559 ASSERT (0);\r
560 goto error_handler1;\r
561 }\r
562\r
563 Status = AmlCreateObjectNode (\r
564 AmlGetByteEncodingByOpCode (AML_NAME_OP, 0),\r
565 0,\r
566 &ObjectNode\r
567 );\r
568 if (EFI_ERROR (Status)) {\r
569 ASSERT (0);\r
570 goto error_handler1;\r
571 }\r
572\r
573 Status = AmlCreateDataNode (\r
574 EAmlNodeDataTypeNameString,\r
575 (UINT8*)AmlNameString,\r
576 AmlNameStringSize,\r
577 &DataNode\r
578 );\r
579 if (EFI_ERROR (Status)) {\r
580 ASSERT (0);\r
581 goto error_handler2;\r
582 }\r
583\r
584 Status = AmlSetFixedArgument (\r
585 ObjectNode,\r
586 EAmlParseIndexTerm0,\r
587 (AML_NODE_HEADER*)DataNode\r
588 );\r
589 if (EFI_ERROR (Status)) {\r
590 ASSERT (0);\r
591 AmlDeleteTree ((AML_NODE_HEADER*)DataNode);\r
592 goto error_handler2;\r
593 }\r
594\r
595 Status = AmlSetFixedArgument (\r
596 ObjectNode,\r
597 EAmlParseIndexTerm1,\r
598 (AML_NODE_HEADER*)Object\r
599 );\r
600 if (EFI_ERROR (Status)) {\r
601 ASSERT (0);\r
602 goto error_handler2;\r
603 }\r
604\r
605 Status = LinkNode (\r
606 ObjectNode,\r
607 ParentNode,\r
608 NewObjectNode\r
609 );\r
610 if (EFI_ERROR (Status)) {\r
611 ASSERT (0);\r
612 goto error_handler2;\r
613 }\r
614\r
615 // Free AmlNameString before returning as it is copied\r
616 // in the call to AmlCreateDataNode().\r
617 goto error_handler1;\r
618\r
619error_handler2:\r
620 if (ObjectNode != NULL) {\r
621 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
622 }\r
623\r
624error_handler1:\r
625 if (AmlNameString != NULL) {\r
626 FreePool (AmlNameString);\r
627 }\r
628\r
629 return Status;\r
630}\r
631\r
632/** AML code generation for a Name object node, containing a String.\r
633\r
634 AmlCodeGenNameString ("_HID", "HID0000", ParentNode, NewObjectNode) is\r
635 equivalent of the following ASL code:\r
636 Name(_HID, "HID0000")\r
637\r
638 @param [in] NameString The new variable name.\r
639 Must be a NULL-terminated ASL NameString\r
640 e.g.: "DEV0", "DV15.DEV0", etc.\r
641 The input string is copied.\r
642 @param [in] String NULL terminated String to associate to the\r
643 NameString.\r
644 @param [in] ParentNode If provided, set ParentNode as the parent\r
645 of the node created.\r
646 @param [out] NewObjectNode If success, contains the created node.\r
647\r
648 @retval EFI_SUCCESS Success.\r
649 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
650 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
651**/\r
652EFI_STATUS\r
653EFIAPI\r
654AmlCodeGenNameString (\r
655 IN CONST CHAR8 * NameString,\r
656 IN CHAR8 * String,\r
657 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
658 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
659 )\r
660{\r
661 EFI_STATUS Status;\r
662 AML_OBJECT_NODE * ObjectNode;\r
663\r
664 if ((NameString == NULL) ||\r
665 (String == NULL) ||\r
666 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
667 ASSERT (0);\r
668 return EFI_INVALID_PARAMETER;\r
669 }\r
670\r
671 Status = AmlCodeGenString (String, &ObjectNode);\r
672 if (EFI_ERROR (Status)) {\r
673 ASSERT (0);\r
674 return Status;\r
675 }\r
676\r
677 Status = AmlCodeGenName (\r
678 NameString,\r
679 ObjectNode,\r
680 ParentNode,\r
681 NewObjectNode\r
682 );\r
683 if (EFI_ERROR (Status)) {\r
684 ASSERT (0);\r
685 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
686 }\r
687\r
688 return Status;\r
689}\r
690\r
691/** AML code generation for a Name object node, containing an Integer.\r
692\r
693 AmlCodeGenNameInteger ("_UID", 1, ParentNode, NewObjectNode) is\r
694 equivalent of the following ASL code:\r
695 Name(_UID, One)\r
696\r
697 @param [in] NameString The new variable name.\r
698 Must be a NULL-terminated ASL NameString\r
699 e.g.: "DEV0", "DV15.DEV0", etc.\r
700 The input string is copied.\r
701 @param [in] Integer Integer to associate to the NameString.\r
702 @param [in] ParentNode If provided, set ParentNode as the parent\r
703 of the node created.\r
704 @param [out] NewObjectNode If success, contains the created node.\r
705\r
706 @retval EFI_SUCCESS Success.\r
707 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
708 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
709**/\r
710EFI_STATUS\r
711EFIAPI\r
712AmlCodeGenNameInteger (\r
713 IN CONST CHAR8 * NameString,\r
714 IN UINT64 Integer,\r
715 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
716 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
717 )\r
718{\r
719 EFI_STATUS Status;\r
720 AML_OBJECT_NODE * ObjectNode;\r
721\r
722 if ((NameString == NULL) ||\r
723 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
724 ASSERT (0);\r
725 return EFI_INVALID_PARAMETER;\r
726 }\r
727\r
728 Status = AmlCodeGenInteger (Integer, &ObjectNode);\r
729 if (EFI_ERROR (Status)) {\r
730 ASSERT (0);\r
731 return Status;\r
732 }\r
733\r
734 Status = AmlCodeGenName (\r
735 NameString,\r
736 ObjectNode,\r
737 ParentNode,\r
738 NewObjectNode\r
739 );\r
740 if (EFI_ERROR (Status)) {\r
741 ASSERT (0);\r
742 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
743 }\r
744\r
745 return Status;\r
746}\r
747\r
748/** AML code generation for a Device object node.\r
749\r
750 AmlCodeGenDevice ("COM0", ParentNode, NewObjectNode) is\r
751 equivalent of the following ASL code:\r
752 Device(COM0) {}\r
753\r
754 @param [in] NameString The new Device's name.\r
755 Must be a NULL-terminated ASL NameString\r
756 e.g.: "DEV0", "DV15.DEV0", etc.\r
757 The input string is copied.\r
758 @param [in] ParentNode If provided, set ParentNode as the parent\r
759 of the node created.\r
760 @param [out] NewObjectNode If success, contains the created node.\r
761\r
762 @retval EFI_SUCCESS Success.\r
763 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
764 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
765**/\r
766EFI_STATUS\r
767EFIAPI\r
768AmlCodeGenDevice (\r
769 IN CONST CHAR8 * NameString,\r
770 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
771 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
772 )\r
773{\r
774 EFI_STATUS Status;\r
775 AML_OBJECT_NODE * ObjectNode;\r
776 AML_DATA_NODE * DataNode;\r
777 CHAR8 * AmlNameString;\r
778 UINT32 AmlNameStringSize;\r
779\r
780 if ((NameString == NULL) ||\r
781 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
782 ASSERT (0);\r
783 return EFI_INVALID_PARAMETER;\r
784 }\r
785\r
786 ObjectNode = NULL;\r
787 DataNode = NULL;\r
788 AmlNameString = NULL;\r
789\r
790 Status = ConvertAslNameToAmlName (NameString, &AmlNameString);\r
791 if (EFI_ERROR (Status)) {\r
792 ASSERT (0);\r
793 return Status;\r
794 }\r
795\r
796 Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);\r
797 if (EFI_ERROR (Status)) {\r
798 ASSERT (0);\r
799 goto error_handler1;\r
800 }\r
801\r
802 Status = AmlCreateObjectNode (\r
803 AmlGetByteEncodingByOpCode (AML_EXT_OP, AML_EXT_DEVICE_OP),\r
804 AmlNameStringSize + AmlComputePkgLengthWidth (AmlNameStringSize),\r
805 &ObjectNode\r
806 );\r
807 if (EFI_ERROR (Status)) {\r
808 ASSERT (0);\r
809 goto error_handler1;\r
810 }\r
811\r
812 Status = AmlCreateDataNode (\r
813 EAmlNodeDataTypeNameString,\r
814 (UINT8*)AmlNameString,\r
815 AmlNameStringSize,\r
816 &DataNode\r
817 );\r
818 if (EFI_ERROR (Status)) {\r
819 ASSERT (0);\r
820 goto error_handler2;\r
821 }\r
822\r
823 Status = AmlSetFixedArgument (\r
824 ObjectNode,\r
825 EAmlParseIndexTerm0,\r
826 (AML_NODE_HEADER*)DataNode\r
827 );\r
828 if (EFI_ERROR (Status)) {\r
829 ASSERT (0);\r
830 AmlDeleteTree ((AML_NODE_HEADER*)DataNode);\r
831 goto error_handler2;\r
832 }\r
833\r
834 Status = LinkNode (\r
835 ObjectNode,\r
836 ParentNode,\r
837 NewObjectNode\r
838 );\r
839 if (EFI_ERROR (Status)) {\r
840 ASSERT (0);\r
841 goto error_handler2;\r
842 }\r
843\r
844 // Free AmlNameString before returning as it is copied\r
845 // in the call to AmlCreateDataNode().\r
846 goto error_handler1;\r
847\r
848error_handler2:\r
849 if (ObjectNode != NULL) {\r
850 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
851 }\r
852\r
853error_handler1:\r
854 if (AmlNameString != NULL) {\r
855 FreePool (AmlNameString);\r
856 }\r
857\r
858 return Status;\r
859}\r
860\r
861/** AML code generation for a Scope object node.\r
862\r
863 AmlCodeGenScope ("_SB", ParentNode, NewObjectNode) is\r
864 equivalent of the following ASL code:\r
865 Scope(_SB) {}\r
866\r
867 @param [in] NameString The new Scope's name.\r
868 Must be a NULL-terminated ASL NameString\r
869 e.g.: "DEV0", "DV15.DEV0", etc.\r
870 The input string is copied.\r
871 @param [in] ParentNode If provided, set ParentNode as the parent\r
872 of the node created.\r
873 @param [out] NewObjectNode If success, contains the created node.\r
874\r
875 @retval EFI_SUCCESS Success.\r
876 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
877 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
878**/\r
879EFI_STATUS\r
880EFIAPI\r
881AmlCodeGenScope (\r
882 IN CONST CHAR8 * NameString,\r
883 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
884 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
885 )\r
886{\r
887 EFI_STATUS Status;\r
888 AML_OBJECT_NODE * ObjectNode;\r
889 AML_DATA_NODE * DataNode;\r
890 CHAR8 * AmlNameString;\r
891 UINT32 AmlNameStringSize;\r
892\r
893 if ((NameString == NULL) ||\r
894 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
895 ASSERT (0);\r
896 return EFI_INVALID_PARAMETER;\r
897 }\r
898\r
899 ObjectNode = NULL;\r
900 DataNode = NULL;\r
901 AmlNameString = NULL;\r
902\r
903 Status = ConvertAslNameToAmlName (NameString, &AmlNameString);\r
904 if (EFI_ERROR (Status)) {\r
905 ASSERT (0);\r
906 return Status;\r
907 }\r
908\r
909 Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);\r
910 if (EFI_ERROR (Status)) {\r
911 ASSERT (0);\r
912 goto error_handler1;\r
913 }\r
914\r
915 Status = AmlCreateObjectNode (\r
916 AmlGetByteEncodingByOpCode (AML_SCOPE_OP, 0),\r
917 AmlNameStringSize + AmlComputePkgLengthWidth (AmlNameStringSize),\r
918 &ObjectNode\r
919 );\r
920 if (EFI_ERROR (Status)) {\r
921 ASSERT (0);\r
922 goto error_handler1;\r
923 }\r
924\r
925 Status = AmlCreateDataNode (\r
926 EAmlNodeDataTypeNameString,\r
927 (UINT8*)AmlNameString,\r
928 AmlNameStringSize,\r
929 &DataNode\r
930 );\r
931 if (EFI_ERROR (Status)) {\r
932 ASSERT (0);\r
933 goto error_handler2;\r
934 }\r
935\r
936 Status = AmlSetFixedArgument (\r
937 ObjectNode,\r
938 EAmlParseIndexTerm0,\r
939 (AML_NODE_HEADER*)DataNode\r
940 );\r
941 if (EFI_ERROR (Status)) {\r
942 ASSERT (0);\r
943 AmlDeleteTree ((AML_NODE_HEADER*)DataNode);\r
944 goto error_handler2;\r
945 }\r
946\r
947 Status = LinkNode (\r
948 ObjectNode,\r
949 ParentNode,\r
950 NewObjectNode\r
951 );\r
952 if (EFI_ERROR (Status)) {\r
953 ASSERT (0);\r
954 goto error_handler2;\r
955 }\r
956\r
957 // Free AmlNameString before returning as it is copied\r
958 // in the call to AmlCreateDataNode().\r
959 goto error_handler1;\r
960\r
961error_handler2:\r
962 if (ObjectNode != NULL) {\r
963 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
964 }\r
965\r
966error_handler1:\r
967 if (AmlNameString != NULL) {\r
968 FreePool (AmlNameString);\r
969 }\r
970\r
971 return Status;\r
972}\r
de62ccbf
PG
973\r
974/** AML code generation for a Method object node.\r
975\r
976 AmlCodeGenMethod ("MET0", 1, TRUE, 3, ParentNode, NewObjectNode) is\r
977 equivalent of the following ASL code:\r
978 Method(MET0, 1, Serialized, 3) {}\r
979\r
980 ACPI 6.4, s20.2.5.2 "Named Objects Encoding":\r
981 DefMethod := MethodOp PkgLength NameString MethodFlags TermList\r
982 MethodOp := 0x14\r
983\r
984 The ASL parameters "ReturnType" and "ParameterTypes" are not asked\r
985 in this function. They are optional parameters in ASL.\r
986\r
987 @param [in] NameString The new Method's name.\r
988 Must be a NULL-terminated ASL NameString\r
989 e.g.: "MET0", "_SB.MET0", etc.\r
990 The input string is copied.\r
991 @param [in] NumArgs Number of arguments.\r
992 Must be 0 <= NumArgs <= 6.\r
993 @param [in] IsSerialized TRUE is equivalent to Serialized.\r
994 FALSE is equivalent to NotSerialized.\r
995 Default is NotSerialized in ASL spec.\r
996 @param [in] SyncLevel Synchronization level for the method.\r
997 Must be 0 <= SyncLevel <= 15.\r
998 Default is 0 in ASL.\r
999 @param [in] ParentNode If provided, set ParentNode as the parent\r
1000 of the node created.\r
1001 @param [out] NewObjectNode If success, contains the created node.\r
1002\r
1003 @retval EFI_SUCCESS Success.\r
1004 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
1005 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
1006**/\r
1007STATIC\r
1008EFI_STATUS\r
1009EFIAPI\r
1010AmlCodeGenMethod (\r
1011 IN CONST CHAR8 * NameString,\r
1012 IN UINT8 NumArgs,\r
1013 IN BOOLEAN IsSerialized,\r
1014 IN UINT8 SyncLevel,\r
1015 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
1016 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
1017 )\r
1018{\r
1019 EFI_STATUS Status;\r
1020 UINT32 PkgLen;\r
1021 UINT8 Flags;\r
1022 AML_OBJECT_NODE * ObjectNode;\r
1023 AML_DATA_NODE * DataNode;\r
1024 CHAR8 * AmlNameString;\r
1025 UINT32 AmlNameStringSize;\r
1026\r
1027 if ((NameString == NULL) ||\r
1028 (NumArgs > 6) ||\r
1029 (SyncLevel > 15) ||\r
1030 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
1031 ASSERT (0);\r
1032 return EFI_INVALID_PARAMETER;\r
1033 }\r
1034\r
1035 ObjectNode = NULL;\r
1036 DataNode = NULL;\r
1037\r
1038 // ACPI 6.4, s20.2.5.2 "Named Objects Encoding":\r
1039 // DefMethod := MethodOp PkgLength NameString MethodFlags TermList\r
1040 // MethodOp := 0x14\r
1041 // So:\r
1042 // 1- Create the NameString\r
1043 // 2- Compute the size to write in the PkgLen\r
1044 // 3- Create nodes for the NameString and Method object node\r
1045 // 4- Set the NameString DataNode as a fixed argument\r
1046 // 5- Create and link the MethodFlags node\r
1047\r
1048 // 1- Create the NameString\r
1049 Status = ConvertAslNameToAmlName (NameString, &AmlNameString);\r
1050 if (EFI_ERROR (Status)) {\r
1051 ASSERT (0);\r
1052 return Status;\r
1053 }\r
1054\r
1055 Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);\r
1056 if (EFI_ERROR (Status)) {\r
1057 ASSERT (0);\r
1058 goto error_handler1;\r
1059 }\r
1060\r
1061 // 2- Compute the size to write in the PkgLen\r
1062 // Add 1 byte (ByteData) for MethodFlags.\r
1063 Status = AmlComputePkgLength (AmlNameStringSize + 1, &PkgLen);\r
1064 if (EFI_ERROR (Status)) {\r
1065 ASSERT (0);\r
1066 goto error_handler1;\r
1067 }\r
1068\r
1069 // 3- Create nodes for the NameString and Method object node\r
1070 Status = AmlCreateObjectNode (\r
1071 AmlGetByteEncodingByOpCode (AML_METHOD_OP, 0),\r
1072 PkgLen,\r
1073 &ObjectNode\r
1074 );\r
1075 if (EFI_ERROR (Status)) {\r
1076 ASSERT (0);\r
1077 goto error_handler1;\r
1078 }\r
1079\r
1080 Status = AmlCreateDataNode (\r
1081 EAmlNodeDataTypeNameString,\r
1082 (UINT8*)AmlNameString,\r
1083 AmlNameStringSize,\r
1084 &DataNode\r
1085 );\r
1086 if (EFI_ERROR (Status)) {\r
1087 ASSERT (0);\r
1088 goto error_handler2;\r
1089 }\r
1090\r
1091 // 4- Set the NameString DataNode as a fixed argument\r
1092 Status = AmlSetFixedArgument (\r
1093 ObjectNode,\r
1094 EAmlParseIndexTerm0,\r
1095 (AML_NODE_HEADER*)DataNode\r
1096 );\r
1097 if (EFI_ERROR (Status)) {\r
1098 ASSERT (0);\r
1099 goto error_handler2;\r
1100 }\r
1101\r
1102 DataNode = NULL;\r
1103\r
1104 // 5- Create and link the MethodFlags node\r
1105 Flags = NumArgs |\r
1106 (IsSerialized ? BIT3 : 0) |\r
1107 (SyncLevel << 4);\r
1108\r
1109 Status = AmlCreateDataNode (EAmlNodeDataTypeUInt, &Flags, 1, &DataNode);\r
1110 if (EFI_ERROR (Status)) {\r
1111 ASSERT (0);\r
1112 goto error_handler2;\r
1113 }\r
1114\r
1115 Status = AmlSetFixedArgument (\r
1116 ObjectNode,\r
1117 EAmlParseIndexTerm1,\r
1118 (AML_NODE_HEADER*)DataNode\r
1119 );\r
1120 if (EFI_ERROR (Status)) {\r
1121 ASSERT (0);\r
1122 goto error_handler2;\r
1123 }\r
1124\r
1125 // Data node is attached so set the pointer to\r
1126 // NULL to ensure correct error handling.\r
1127 DataNode = NULL;\r
1128\r
1129 Status = LinkNode (\r
1130 ObjectNode,\r
1131 ParentNode,\r
1132 NewObjectNode\r
1133 );\r
1134 if (EFI_ERROR (Status)) {\r
1135 ASSERT (0);\r
1136 goto error_handler2;\r
1137 }\r
1138\r
1139 // Free AmlNameString before returning as it is copied\r
1140 // in the call to AmlCreateDataNode().\r
1141 goto error_handler1;\r
1142\r
1143error_handler2:\r
1144 if (ObjectNode != NULL) {\r
1145 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
1146 }\r
1147 if (DataNode != NULL) {\r
1148 AmlDeleteTree ((AML_NODE_HEADER*)DataNode);\r
1149 }\r
1150\r
1151error_handler1:\r
1152 if (AmlNameString != NULL) {\r
1153 FreePool (AmlNameString);\r
1154 }\r
1155 return Status;\r
1156}\r
e2d7b495
PG
1157\r
1158/** AML code generation for a Return object node.\r
1159\r
1160 AmlCodeGenReturn (ReturnNode, ParentNode, NewObjectNode) is\r
1161 equivalent of the following ASL code:\r
1162 Return([Content of the ReturnNode])\r
1163\r
1164 The ACPI 6.3 specification, s20.2.5.3 "Type 1 Opcodes Encoding" states:\r
1165 DefReturn := ReturnOp ArgObject\r
1166 ReturnOp := 0xA4\r
1167 ArgObject := TermArg => DataRefObject\r
1168\r
1169 Thus, the ReturnNode must be evaluated as a DataRefObject. It can\r
1170 be a NameString referencing an object. As this CodeGen Api doesn't\r
1171 do semantic checking, it is strongly advised to check the AML bytecode\r
1172 generated by this function against an ASL compiler.\r
1173\r
1174 The ReturnNode must be generated inside a Method body scope.\r
1175\r
1176 @param [in] ReturnNode The object returned by the Return ASL statement.\r
1177 This node is deleted if an error occurs.\r
1178 @param [in] ParentNode If provided, set ParentNode as the parent\r
1179 of the node created.\r
1180 Must be a MethodOp node.\r
1181 @param [out] NewObjectNode If success, contains the created node.\r
1182\r
1183 @retval EFI_SUCCESS Success.\r
1184 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
1185 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
1186**/\r
1187STATIC\r
1188EFI_STATUS\r
1189EFIAPI\r
1190AmlCodeGenReturn (\r
1191 IN AML_NODE_HEADER * ReturnNode,\r
1192 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
1193 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
1194 )\r
1195{\r
1196 EFI_STATUS Status;\r
1197 AML_OBJECT_NODE * ObjectNode;\r
1198\r
1199 if ((ReturnNode == NULL) ||\r
1200 ((ParentNode == NULL) && (NewObjectNode == NULL)) ||\r
1201 ((ParentNode != NULL) &&\r
1202 !AmlNodeCompareOpCode (\r
1203 (AML_OBJECT_NODE*)ParentNode, AML_METHOD_OP, 0))) {\r
1204 ASSERT (0);\r
1205 return EFI_INVALID_PARAMETER;\r
1206 }\r
1207\r
1208 Status = AmlCreateObjectNode (\r
1209 AmlGetByteEncodingByOpCode (AML_RETURN_OP, 0),\r
1210 0,\r
1211 &ObjectNode\r
1212 );\r
1213 if (EFI_ERROR (Status)) {\r
1214 ASSERT (0);\r
1215 goto error_handler;\r
1216 }\r
1217\r
1218 Status = AmlSetFixedArgument (\r
1219 ObjectNode,\r
1220 EAmlParseIndexTerm0,\r
1221 (AML_NODE_HEADER*)ReturnNode\r
1222 );\r
1223 if (EFI_ERROR (Status)) {\r
1224 ASSERT (0);\r
1225 goto error_handler;\r
1226 }\r
1227\r
1228 ReturnNode = NULL;\r
1229\r
1230 Status = LinkNode (\r
1231 ObjectNode,\r
1232 ParentNode,\r
1233 NewObjectNode\r
1234 );\r
1235 if (EFI_ERROR (Status)) {\r
1236 ASSERT (0);\r
1237 goto error_handler;\r
1238 }\r
1239\r
1240 return Status;\r
1241\r
1242error_handler:\r
1243 if (ReturnNode != NULL) {\r
1244 AmlDeleteTree (ReturnNode);\r
1245 }\r
1246 if (ObjectNode != NULL) {\r
1247 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
1248 }\r
1249 return Status;\r
1250}\r
1251\r
1252/** AML code generation for a Return object node,\r
1253 returning the object as an input NameString.\r
1254\r
1255 AmlCodeGenReturn ("NAM1", ParentNode, NewObjectNode) is\r
1256 equivalent of the following ASL code:\r
1257 Return(NAM1)\r
1258\r
1259 The ACPI 6.3 specification, s20.2.5.3 "Type 1 Opcodes Encoding" states:\r
1260 DefReturn := ReturnOp ArgObject\r
1261 ReturnOp := 0xA4\r
1262 ArgObject := TermArg => DataRefObject\r
1263\r
1264 Thus, the ReturnNode must be evaluated as a DataRefObject. It can\r
1265 be a NameString referencing an object. As this CodeGen Api doesn't\r
1266 do semantic checking, it is strongly advised to check the AML bytecode\r
1267 generated by this function against an ASL compiler.\r
1268\r
1269 The ReturnNode must be generated inside a Method body scope.\r
1270\r
1271 @param [in] NameString The object referenced by this NameString\r
1272 is returned by the Return ASL statement.\r
1273 Must be a NULL-terminated ASL NameString\r
1274 e.g.: "NAM1", "_SB.NAM1", etc.\r
1275 The input string is copied.\r
1276 @param [in] ParentNode If provided, set ParentNode as the parent\r
1277 of the node created.\r
1278 Must be a MethodOp node.\r
1279 @param [out] NewObjectNode If success, contains the created node.\r
1280\r
1281 @retval EFI_SUCCESS Success.\r
1282 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
1283 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
1284**/\r
1285STATIC\r
1286EFI_STATUS\r
1287EFIAPI\r
1288AmlCodeGenReturnNameString (\r
1289 IN CONST CHAR8 * NameString,\r
1290 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
1291 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
1292 )\r
1293{\r
1294 EFI_STATUS Status;\r
1295 AML_DATA_NODE * DataNode;\r
1296 CHAR8 * AmlNameString;\r
1297 UINT32 AmlNameStringSize;\r
1298\r
1299 DataNode = NULL;\r
1300\r
1301 Status = ConvertAslNameToAmlName (NameString, &AmlNameString);\r
1302 if (EFI_ERROR (Status)) {\r
1303 ASSERT (0);\r
1304 return Status;\r
1305 }\r
1306\r
1307 Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);\r
1308 if (EFI_ERROR (Status)) {\r
1309 ASSERT (0);\r
1310 goto exit_handler;\r
1311 }\r
1312\r
1313 Status = AmlCreateDataNode (\r
1314 EAmlNodeDataTypeNameString,\r
1315 (UINT8*)AmlNameString,\r
1316 AmlNameStringSize,\r
1317 &DataNode\r
1318 );\r
1319 if (EFI_ERROR (Status)) {\r
1320 ASSERT (0);\r
1321 goto exit_handler;\r
1322 }\r
1323\r
1324 // AmlCodeGenReturn() deletes DataNode if error.\r
1325 Status = AmlCodeGenReturn (\r
1326 (AML_NODE_HEADER*)DataNode,\r
1327 ParentNode,\r
1328 NewObjectNode\r
1329 );\r
1330 ASSERT_EFI_ERROR (Status);\r
1331\r
1332exit_handler:\r
1333 if (AmlNameString != NULL) {\r
1334 FreePool (AmlNameString);\r
1335 }\r
1336 return Status;\r
1337}\r