]> git.proxmox.com Git - mirror_edk2.git/blame - DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
DynamicTablesPkg: Clear pointer in node creation fcts
[mirror_edk2.git] / DynamicTablesPkg / Library / Common / AmlLib / CodeGen / AmlCodeGen.c
CommitLineData
3a681567
PG
1/** @file\r
2 AML Code Generation.\r
3\r
4 Copyright (c) 2020, Arm Limited. All rights reserved.<BR>\r
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
15#include <Tree/AmlNode.h>\r
16#include <Tree/AmlTree.h>\r
17#include <String/AmlString.h>\r
18#include <Utils/AmlUtility.h>\r
19\r
20/** Utility function to link a node when returning from a CodeGen function.\r
21\r
22 @param [in] Node Newly created node.\r
23 @param [in] ParentNode If provided, set ParentNode as the parent\r
24 of the node created.\r
2dd7dd39
PG
25 @param [out] NewObjectNode If not NULL:\r
26 - and Success, contains the created Node.\r
27 - and Error, reset to NULL.\r
3a681567
PG
28\r
29 @retval EFI_SUCCESS The function completed successfully.\r
30 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
31**/\r
32STATIC\r
33EFI_STATUS\r
34EFIAPI\r
35LinkNode (\r
36 IN AML_OBJECT_NODE * Node,\r
37 IN AML_NODE_HEADER * ParentNode,\r
5e0b708f 38 OUT AML_OBJECT_NODE ** NewObjectNode\r
3a681567
PG
39 )\r
40{\r
41 EFI_STATUS Status;\r
42\r
43 if (NewObjectNode != NULL) {\r
2dd7dd39 44 *NewObjectNode = NULL;\r
3a681567
PG
45 }\r
46\r
47 // Add RdNode as the last element.\r
48 if (ParentNode != NULL) {\r
49 Status = AmlVarListAddTail (ParentNode, (AML_NODE_HEADER*)Node);\r
50 if (EFI_ERROR (Status)) {\r
51 ASSERT (0);\r
52 return Status;\r
53 }\r
54 }\r
55\r
2dd7dd39
PG
56 if (NewObjectNode != NULL) {\r
57 *NewObjectNode = Node;\r
58 }\r
59\r
3a681567
PG
60 return EFI_SUCCESS;\r
61}\r
62\r
63/** AML code generation for DefinitionBlock.\r
64\r
65 Create a Root Node handle.\r
66 It is the caller's responsibility to free the allocated memory\r
67 with the AmlDeleteTree function.\r
68\r
69 AmlCodeGenDefinitionBlock (TableSignature, OemID, TableID, OEMRevision) is\r
70 equivalent to the following ASL code:\r
71 DefinitionBlock (AMLFileName, TableSignature, ComplianceRevision,\r
72 OemID, TableID, OEMRevision) {}\r
73 with the ComplianceRevision set to 2 and the AMLFileName is ignored.\r
74\r
75 @param[in] TableSignature 4-character ACPI signature.\r
76 Must be 'DSDT' or 'SSDT'.\r
77 @param[in] OemId 6-character string OEM identifier.\r
78 @param[in] OemTableId 8-character string OEM table identifier.\r
79 @param[in] OemRevision OEM revision number.\r
5e0b708f 80 @param[out] NewRootNode Pointer to the root node representing a\r
3a681567
PG
81 Definition Block.\r
82\r
83 @retval EFI_SUCCESS Success.\r
84 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
85 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
86**/\r
87EFI_STATUS\r
88EFIAPI\r
89AmlCodeGenDefinitionBlock (\r
90 IN CONST CHAR8 * TableSignature,\r
91 IN CONST CHAR8 * OemId,\r
92 IN CONST CHAR8 * OemTableId,\r
93 IN UINT32 OemRevision,\r
94 OUT AML_ROOT_NODE ** NewRootNode\r
95 )\r
96{\r
97 EFI_STATUS Status;\r
98 EFI_ACPI_DESCRIPTION_HEADER AcpiHeader;\r
99\r
100 if ((TableSignature == NULL) ||\r
101 (OemId == NULL) ||\r
102 (OemTableId == NULL) ||\r
103 (NewRootNode == NULL)) {\r
104 ASSERT (0);\r
105 return EFI_INVALID_PARAMETER;\r
106 }\r
107\r
108 CopyMem (&AcpiHeader.Signature, TableSignature, 4);\r
109 AcpiHeader.Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);\r
110 AcpiHeader.Revision = 2;\r
111 CopyMem (&AcpiHeader.OemId, OemId, 6);\r
112 CopyMem (&AcpiHeader.OemTableId, OemTableId, 8);\r
113 AcpiHeader.OemRevision = OemRevision;\r
114 AcpiHeader.CreatorId = TABLE_GENERATOR_CREATOR_ID_ARM;\r
115 AcpiHeader.CreatorRevision = CREATE_REVISION (1, 0);\r
116\r
117 Status = AmlCreateRootNode (&AcpiHeader, NewRootNode);\r
118 ASSERT_EFI_ERROR (Status);\r
119\r
120 return Status;\r
121}\r
122\r
123/** AML code generation for a String object node.\r
124\r
125 @param [in] String Pointer to a NULL terminated string.\r
126 @param [out] NewObjectNode If success, contains the created\r
127 String object node.\r
128\r
129 @retval EFI_SUCCESS Success.\r
130 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
131 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
132**/\r
133STATIC\r
134EFI_STATUS\r
135EFIAPI\r
136AmlCodeGenString (\r
137 IN CHAR8 * String,\r
138 OUT AML_OBJECT_NODE ** NewObjectNode\r
139 )\r
140{\r
141 EFI_STATUS Status;\r
142 AML_OBJECT_NODE * ObjectNode;\r
143 AML_DATA_NODE * DataNode;\r
144\r
145 if ((String == NULL) ||\r
146 (NewObjectNode == NULL)) {\r
147 ASSERT (0);\r
148 return EFI_INVALID_PARAMETER;\r
149 }\r
150\r
151 ObjectNode = NULL;\r
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
190 if (ObjectNode != NULL) {\r
191 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
192 }\r
193\r
194 return Status;\r
195}\r
196\r
197/** AML code generation for an Integer object node.\r
198\r
199 @param [in] Integer Integer of the Integer object node.\r
200 @param [out] NewObjectNode If success, contains the created\r
201 Integer object node.\r
202\r
203 @retval EFI_SUCCESS Success.\r
204 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
205 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
206**/\r
207STATIC\r
208EFI_STATUS\r
209EFIAPI\r
210AmlCodeGenInteger (\r
211 IN UINT64 Integer,\r
212 OUT AML_OBJECT_NODE ** NewObjectNode\r
213 )\r
214{\r
215 EFI_STATUS Status;\r
216 INT8 ValueWidthDiff;\r
217\r
218 if (NewObjectNode == NULL) {\r
219 ASSERT (0);\r
220 return EFI_INVALID_PARAMETER;\r
221 }\r
222\r
223 // Create an object node containing Zero.\r
224 Status = AmlCreateObjectNode (\r
225 AmlGetByteEncodingByOpCode (AML_ZERO_OP, 0),\r
226 0,\r
227 NewObjectNode\r
228 );\r
229 if (EFI_ERROR (Status)) {\r
230 ASSERT (0);\r
231 return Status;\r
232 }\r
233\r
234 // Update the object node with integer value.\r
235 Status = AmlNodeSetIntegerValue (*NewObjectNode, Integer, &ValueWidthDiff);\r
236 if (EFI_ERROR (Status)) {\r
237 ASSERT (0);\r
238 AmlDeleteTree ((AML_NODE_HEADER*)*NewObjectNode);\r
239 }\r
240\r
241 return Status;\r
242}\r
243\r
244/** AML code generation for a Name object node.\r
245\r
246 @param [in] NameString The new variable name.\r
247 Must be a NULL-terminated ASL NameString\r
248 e.g.: "DEV0", "DV15.DEV0", etc.\r
249 This input string is copied.\r
250 @param [in] Object Object associated to the NameString.\r
251 @param [in] ParentNode If provided, set ParentNode as the parent\r
252 of the node created.\r
253 @param [out] NewObjectNode If success, contains the created node.\r
254\r
255 @retval EFI_SUCCESS Success.\r
256 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
257 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
258**/\r
259STATIC\r
260EFI_STATUS\r
261EFIAPI\r
262AmlCodeGenName (\r
263 IN CONST CHAR8 * NameString,\r
264 IN AML_OBJECT_NODE * Object,\r
265 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
266 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
267 )\r
268{\r
269 EFI_STATUS Status;\r
270 AML_OBJECT_NODE * ObjectNode;\r
271 AML_DATA_NODE * DataNode;\r
272 CHAR8 * AmlNameString;\r
273 UINT32 AmlNameStringSize;\r
274\r
275 if ((NameString == NULL) ||\r
276 (Object == NULL) ||\r
277 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
278 ASSERT (0);\r
279 return EFI_INVALID_PARAMETER;\r
280 }\r
281\r
282 ObjectNode = NULL;\r
283 DataNode = NULL;\r
284 AmlNameString = NULL;\r
285\r
286 Status = ConvertAslNameToAmlName (NameString, &AmlNameString);\r
287 if (EFI_ERROR (Status)) {\r
288 ASSERT (0);\r
289 return Status;\r
290 }\r
291\r
292 Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);\r
293 if (EFI_ERROR (Status)) {\r
294 ASSERT (0);\r
295 goto error_handler1;\r
296 }\r
297\r
298 Status = AmlCreateObjectNode (\r
299 AmlGetByteEncodingByOpCode (AML_NAME_OP, 0),\r
300 0,\r
301 &ObjectNode\r
302 );\r
303 if (EFI_ERROR (Status)) {\r
304 ASSERT (0);\r
305 goto error_handler1;\r
306 }\r
307\r
308 Status = AmlCreateDataNode (\r
309 EAmlNodeDataTypeNameString,\r
310 (UINT8*)AmlNameString,\r
311 AmlNameStringSize,\r
312 &DataNode\r
313 );\r
314 if (EFI_ERROR (Status)) {\r
315 ASSERT (0);\r
316 goto error_handler2;\r
317 }\r
318\r
319 Status = AmlSetFixedArgument (\r
320 ObjectNode,\r
321 EAmlParseIndexTerm0,\r
322 (AML_NODE_HEADER*)DataNode\r
323 );\r
324 if (EFI_ERROR (Status)) {\r
325 ASSERT (0);\r
326 AmlDeleteTree ((AML_NODE_HEADER*)DataNode);\r
327 goto error_handler2;\r
328 }\r
329\r
330 Status = AmlSetFixedArgument (\r
331 ObjectNode,\r
332 EAmlParseIndexTerm1,\r
333 (AML_NODE_HEADER*)Object\r
334 );\r
335 if (EFI_ERROR (Status)) {\r
336 ASSERT (0);\r
337 goto error_handler2;\r
338 }\r
339\r
340 Status = LinkNode (\r
341 ObjectNode,\r
342 ParentNode,\r
343 NewObjectNode\r
344 );\r
345 if (EFI_ERROR (Status)) {\r
346 ASSERT (0);\r
347 goto error_handler2;\r
348 }\r
349\r
350 // Free AmlNameString before returning as it is copied\r
351 // in the call to AmlCreateDataNode().\r
352 goto error_handler1;\r
353\r
354error_handler2:\r
355 if (ObjectNode != NULL) {\r
356 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
357 }\r
358\r
359error_handler1:\r
360 if (AmlNameString != NULL) {\r
361 FreePool (AmlNameString);\r
362 }\r
363\r
364 return Status;\r
365}\r
366\r
367/** AML code generation for a Name object node, containing a String.\r
368\r
369 AmlCodeGenNameString ("_HID", "HID0000", ParentNode, NewObjectNode) is\r
370 equivalent of the following ASL code:\r
371 Name(_HID, "HID0000")\r
372\r
373 @param [in] NameString The new variable name.\r
374 Must be a NULL-terminated ASL NameString\r
375 e.g.: "DEV0", "DV15.DEV0", etc.\r
376 The input string is copied.\r
377 @param [in] String NULL terminated String to associate to the\r
378 NameString.\r
379 @param [in] ParentNode If provided, set ParentNode as the parent\r
380 of the node created.\r
381 @param [out] NewObjectNode If success, contains the created node.\r
382\r
383 @retval EFI_SUCCESS Success.\r
384 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
385 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
386**/\r
387EFI_STATUS\r
388EFIAPI\r
389AmlCodeGenNameString (\r
390 IN CONST CHAR8 * NameString,\r
391 IN CHAR8 * String,\r
392 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
393 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
394 )\r
395{\r
396 EFI_STATUS Status;\r
397 AML_OBJECT_NODE * ObjectNode;\r
398\r
399 if ((NameString == NULL) ||\r
400 (String == NULL) ||\r
401 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
402 ASSERT (0);\r
403 return EFI_INVALID_PARAMETER;\r
404 }\r
405\r
406 Status = AmlCodeGenString (String, &ObjectNode);\r
407 if (EFI_ERROR (Status)) {\r
408 ASSERT (0);\r
409 return Status;\r
410 }\r
411\r
412 Status = AmlCodeGenName (\r
413 NameString,\r
414 ObjectNode,\r
415 ParentNode,\r
416 NewObjectNode\r
417 );\r
418 if (EFI_ERROR (Status)) {\r
419 ASSERT (0);\r
420 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
421 }\r
422\r
423 return Status;\r
424}\r
425\r
426/** AML code generation for a Name object node, containing an Integer.\r
427\r
428 AmlCodeGenNameInteger ("_UID", 1, ParentNode, NewObjectNode) is\r
429 equivalent of the following ASL code:\r
430 Name(_UID, One)\r
431\r
432 @param [in] NameString The new variable name.\r
433 Must be a NULL-terminated ASL NameString\r
434 e.g.: "DEV0", "DV15.DEV0", etc.\r
435 The input string is copied.\r
436 @param [in] Integer Integer to associate to the NameString.\r
437 @param [in] ParentNode If provided, set ParentNode as the parent\r
438 of the node created.\r
439 @param [out] NewObjectNode If success, contains the created node.\r
440\r
441 @retval EFI_SUCCESS Success.\r
442 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
443 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
444**/\r
445EFI_STATUS\r
446EFIAPI\r
447AmlCodeGenNameInteger (\r
448 IN CONST CHAR8 * NameString,\r
449 IN UINT64 Integer,\r
450 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
451 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
452 )\r
453{\r
454 EFI_STATUS Status;\r
455 AML_OBJECT_NODE * ObjectNode;\r
456\r
457 if ((NameString == NULL) ||\r
458 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
459 ASSERT (0);\r
460 return EFI_INVALID_PARAMETER;\r
461 }\r
462\r
463 Status = AmlCodeGenInteger (Integer, &ObjectNode);\r
464 if (EFI_ERROR (Status)) {\r
465 ASSERT (0);\r
466 return Status;\r
467 }\r
468\r
469 Status = AmlCodeGenName (\r
470 NameString,\r
471 ObjectNode,\r
472 ParentNode,\r
473 NewObjectNode\r
474 );\r
475 if (EFI_ERROR (Status)) {\r
476 ASSERT (0);\r
477 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
478 }\r
479\r
480 return Status;\r
481}\r
482\r
483/** AML code generation for a Device object node.\r
484\r
485 AmlCodeGenDevice ("COM0", ParentNode, NewObjectNode) is\r
486 equivalent of the following ASL code:\r
487 Device(COM0) {}\r
488\r
489 @param [in] NameString The new Device's name.\r
490 Must be a NULL-terminated ASL NameString\r
491 e.g.: "DEV0", "DV15.DEV0", etc.\r
492 The input string is copied.\r
493 @param [in] ParentNode If provided, set ParentNode as the parent\r
494 of the node created.\r
495 @param [out] NewObjectNode If success, contains the created node.\r
496\r
497 @retval EFI_SUCCESS Success.\r
498 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
499 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
500**/\r
501EFI_STATUS\r
502EFIAPI\r
503AmlCodeGenDevice (\r
504 IN CONST CHAR8 * NameString,\r
505 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
506 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
507 )\r
508{\r
509 EFI_STATUS Status;\r
510 AML_OBJECT_NODE * ObjectNode;\r
511 AML_DATA_NODE * DataNode;\r
512 CHAR8 * AmlNameString;\r
513 UINT32 AmlNameStringSize;\r
514\r
515 if ((NameString == NULL) ||\r
516 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
517 ASSERT (0);\r
518 return EFI_INVALID_PARAMETER;\r
519 }\r
520\r
521 ObjectNode = NULL;\r
522 DataNode = NULL;\r
523 AmlNameString = NULL;\r
524\r
525 Status = ConvertAslNameToAmlName (NameString, &AmlNameString);\r
526 if (EFI_ERROR (Status)) {\r
527 ASSERT (0);\r
528 return Status;\r
529 }\r
530\r
531 Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);\r
532 if (EFI_ERROR (Status)) {\r
533 ASSERT (0);\r
534 goto error_handler1;\r
535 }\r
536\r
537 Status = AmlCreateObjectNode (\r
538 AmlGetByteEncodingByOpCode (AML_EXT_OP, AML_EXT_DEVICE_OP),\r
539 AmlNameStringSize + AmlComputePkgLengthWidth (AmlNameStringSize),\r
540 &ObjectNode\r
541 );\r
542 if (EFI_ERROR (Status)) {\r
543 ASSERT (0);\r
544 goto error_handler1;\r
545 }\r
546\r
547 Status = AmlCreateDataNode (\r
548 EAmlNodeDataTypeNameString,\r
549 (UINT8*)AmlNameString,\r
550 AmlNameStringSize,\r
551 &DataNode\r
552 );\r
553 if (EFI_ERROR (Status)) {\r
554 ASSERT (0);\r
555 goto error_handler2;\r
556 }\r
557\r
558 Status = AmlSetFixedArgument (\r
559 ObjectNode,\r
560 EAmlParseIndexTerm0,\r
561 (AML_NODE_HEADER*)DataNode\r
562 );\r
563 if (EFI_ERROR (Status)) {\r
564 ASSERT (0);\r
565 AmlDeleteTree ((AML_NODE_HEADER*)DataNode);\r
566 goto error_handler2;\r
567 }\r
568\r
569 Status = LinkNode (\r
570 ObjectNode,\r
571 ParentNode,\r
572 NewObjectNode\r
573 );\r
574 if (EFI_ERROR (Status)) {\r
575 ASSERT (0);\r
576 goto error_handler2;\r
577 }\r
578\r
579 // Free AmlNameString before returning as it is copied\r
580 // in the call to AmlCreateDataNode().\r
581 goto error_handler1;\r
582\r
583error_handler2:\r
584 if (ObjectNode != NULL) {\r
585 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
586 }\r
587\r
588error_handler1:\r
589 if (AmlNameString != NULL) {\r
590 FreePool (AmlNameString);\r
591 }\r
592\r
593 return Status;\r
594}\r
595\r
596/** AML code generation for a Scope object node.\r
597\r
598 AmlCodeGenScope ("_SB", ParentNode, NewObjectNode) is\r
599 equivalent of the following ASL code:\r
600 Scope(_SB) {}\r
601\r
602 @param [in] NameString The new Scope's name.\r
603 Must be a NULL-terminated ASL NameString\r
604 e.g.: "DEV0", "DV15.DEV0", etc.\r
605 The input string is copied.\r
606 @param [in] ParentNode If provided, set ParentNode as the parent\r
607 of the node created.\r
608 @param [out] NewObjectNode If success, contains the created node.\r
609\r
610 @retval EFI_SUCCESS Success.\r
611 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
612 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
613**/\r
614EFI_STATUS\r
615EFIAPI\r
616AmlCodeGenScope (\r
617 IN CONST CHAR8 * NameString,\r
618 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
619 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
620 )\r
621{\r
622 EFI_STATUS Status;\r
623 AML_OBJECT_NODE * ObjectNode;\r
624 AML_DATA_NODE * DataNode;\r
625 CHAR8 * AmlNameString;\r
626 UINT32 AmlNameStringSize;\r
627\r
628 if ((NameString == NULL) ||\r
629 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
630 ASSERT (0);\r
631 return EFI_INVALID_PARAMETER;\r
632 }\r
633\r
634 ObjectNode = NULL;\r
635 DataNode = NULL;\r
636 AmlNameString = NULL;\r
637\r
638 Status = ConvertAslNameToAmlName (NameString, &AmlNameString);\r
639 if (EFI_ERROR (Status)) {\r
640 ASSERT (0);\r
641 return Status;\r
642 }\r
643\r
644 Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);\r
645 if (EFI_ERROR (Status)) {\r
646 ASSERT (0);\r
647 goto error_handler1;\r
648 }\r
649\r
650 Status = AmlCreateObjectNode (\r
651 AmlGetByteEncodingByOpCode (AML_SCOPE_OP, 0),\r
652 AmlNameStringSize + AmlComputePkgLengthWidth (AmlNameStringSize),\r
653 &ObjectNode\r
654 );\r
655 if (EFI_ERROR (Status)) {\r
656 ASSERT (0);\r
657 goto error_handler1;\r
658 }\r
659\r
660 Status = AmlCreateDataNode (\r
661 EAmlNodeDataTypeNameString,\r
662 (UINT8*)AmlNameString,\r
663 AmlNameStringSize,\r
664 &DataNode\r
665 );\r
666 if (EFI_ERROR (Status)) {\r
667 ASSERT (0);\r
668 goto error_handler2;\r
669 }\r
670\r
671 Status = AmlSetFixedArgument (\r
672 ObjectNode,\r
673 EAmlParseIndexTerm0,\r
674 (AML_NODE_HEADER*)DataNode\r
675 );\r
676 if (EFI_ERROR (Status)) {\r
677 ASSERT (0);\r
678 AmlDeleteTree ((AML_NODE_HEADER*)DataNode);\r
679 goto error_handler2;\r
680 }\r
681\r
682 Status = LinkNode (\r
683 ObjectNode,\r
684 ParentNode,\r
685 NewObjectNode\r
686 );\r
687 if (EFI_ERROR (Status)) {\r
688 ASSERT (0);\r
689 goto error_handler2;\r
690 }\r
691\r
692 // Free AmlNameString before returning as it is copied\r
693 // in the call to AmlCreateDataNode().\r
694 goto error_handler1;\r
695\r
696error_handler2:\r
697 if (ObjectNode != NULL) {\r
698 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
699 }\r
700\r
701error_handler1:\r
702 if (AmlNameString != NULL) {\r
703 FreePool (AmlNameString);\r
704 }\r
705\r
706 return Status;\r
707}\r