]> git.proxmox.com Git - mirror_edk2.git/blame - DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
DynamicTablesPkg: AML code generation for a Package
[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
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
3a681567
PG
151 DataNode = NULL;\r
152\r
153 Status = AmlCreateObjectNode (\r
154 AmlGetByteEncodingByOpCode (AML_STRING_PREFIX, 0),\r
155 0,\r
156 &ObjectNode\r
157 );\r
158 if (EFI_ERROR (Status)) {\r
159 ASSERT (0);\r
160 return Status;\r
161 }\r
162\r
163 Status = AmlCreateDataNode (\r
164 EAmlNodeDataTypeString,\r
165 (UINT8*)String,\r
166 (UINT32)AsciiStrLen (String) + 1,\r
167 &DataNode\r
168 );\r
169 if (EFI_ERROR (Status)) {\r
170 ASSERT (0);\r
171 goto error_handler;\r
172 }\r
173\r
174 Status = AmlSetFixedArgument (\r
175 ObjectNode,\r
176 EAmlParseIndexTerm0,\r
177 (AML_NODE_HEADER*)DataNode\r
178 );\r
179 if (EFI_ERROR (Status)) {\r
180 ASSERT (0);\r
181 AmlDeleteTree ((AML_NODE_HEADER*)DataNode);\r
182 goto error_handler;\r
183 }\r
184\r
185 *NewObjectNode = ObjectNode;\r
186 return Status;\r
187\r
188error_handler:\r
37bd0817 189 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
3a681567
PG
190 return Status;\r
191}\r
192\r
193/** AML code generation for an Integer object node.\r
194\r
195 @param [in] Integer Integer of the Integer object node.\r
196 @param [out] NewObjectNode If success, contains the created\r
197 Integer object node.\r
198\r
199 @retval EFI_SUCCESS Success.\r
200 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
201 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
202**/\r
203STATIC\r
204EFI_STATUS\r
205EFIAPI\r
206AmlCodeGenInteger (\r
207 IN UINT64 Integer,\r
208 OUT AML_OBJECT_NODE ** NewObjectNode\r
209 )\r
210{\r
211 EFI_STATUS Status;\r
212 INT8 ValueWidthDiff;\r
213\r
214 if (NewObjectNode == NULL) {\r
215 ASSERT (0);\r
216 return EFI_INVALID_PARAMETER;\r
217 }\r
218\r
219 // Create an object node containing Zero.\r
220 Status = AmlCreateObjectNode (\r
221 AmlGetByteEncodingByOpCode (AML_ZERO_OP, 0),\r
222 0,\r
223 NewObjectNode\r
224 );\r
225 if (EFI_ERROR (Status)) {\r
226 ASSERT (0);\r
227 return Status;\r
228 }\r
229\r
230 // Update the object node with integer value.\r
231 Status = AmlNodeSetIntegerValue (*NewObjectNode, Integer, &ValueWidthDiff);\r
232 if (EFI_ERROR (Status)) {\r
233 ASSERT (0);\r
234 AmlDeleteTree ((AML_NODE_HEADER*)*NewObjectNode);\r
235 }\r
236\r
237 return Status;\r
238}\r
239\r
1e33479b
PG
240/** AML code generation for a Package object node.\r
241\r
242 The package generated is empty. New elements can be added via its\r
243 list of variable arguments.\r
244\r
245 @param [out] NewObjectNode If success, contains the created\r
246 Package object node.\r
247\r
248 @retval EFI_SUCCESS Success.\r
249 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
250 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
251**/\r
252STATIC\r
253EFI_STATUS\r
254EFIAPI\r
255AmlCodeGenPackage (\r
256 OUT AML_OBJECT_NODE ** NewObjectNode\r
257 )\r
258{\r
259 EFI_STATUS Status;\r
260 AML_DATA_NODE * DataNode;\r
261 UINT8 NodeCount;\r
262\r
263 if (NewObjectNode == NULL) {\r
264 ASSERT (0);\r
265 return EFI_INVALID_PARAMETER;\r
266 }\r
267\r
268 NodeCount = 0;\r
269\r
270 // Create an object node.\r
271 // PkgLen is 2:\r
272 // - one byte to store the PkgLength\r
273 // - one byte for the NumElements.\r
274 // Cf ACPI6.3, s20.2.5 "Term Objects Encoding"\r
275 // DefPackage := PackageOp PkgLength NumElements PackageElementList\r
276 // NumElements := ByteData\r
277 Status = AmlCreateObjectNode (\r
278 AmlGetByteEncodingByOpCode (AML_PACKAGE_OP, 0),\r
279 2,\r
280 NewObjectNode\r
281 );\r
282 if (EFI_ERROR (Status)) {\r
283 ASSERT (0);\r
284 return Status;\r
285 }\r
286\r
287 // NumElements is a ByteData.\r
288 Status = AmlCreateDataNode (\r
289 EAmlNodeDataTypeUInt,\r
290 &NodeCount,\r
291 sizeof (NodeCount),\r
292 &DataNode\r
293 );\r
294 if (EFI_ERROR (Status)) {\r
295 ASSERT (0);\r
296 goto error_handler;\r
297 }\r
298\r
299 Status = AmlSetFixedArgument (\r
300 *NewObjectNode,\r
301 EAmlParseIndexTerm0,\r
302 (AML_NODE_HEADER*)DataNode\r
303 );\r
304 if (EFI_ERROR (Status)) {\r
305 ASSERT (0);\r
306 goto error_handler;\r
307 }\r
308\r
309 return Status;\r
310\r
311error_handler:\r
312 AmlDeleteTree ((AML_NODE_HEADER*)*NewObjectNode);\r
313 if (DataNode != NULL) {\r
314 AmlDeleteTree ((AML_NODE_HEADER*)DataNode);\r
315 }\r
316 return Status;\r
317}\r
318\r
3a681567
PG
319/** AML code generation for a Name object node.\r
320\r
321 @param [in] NameString The new variable name.\r
322 Must be a NULL-terminated ASL NameString\r
323 e.g.: "DEV0", "DV15.DEV0", etc.\r
324 This input string is copied.\r
325 @param [in] Object Object associated to the NameString.\r
326 @param [in] ParentNode If provided, set ParentNode as the parent\r
327 of the node created.\r
328 @param [out] NewObjectNode If success, contains the created node.\r
329\r
330 @retval EFI_SUCCESS Success.\r
331 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
332 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
333**/\r
334STATIC\r
335EFI_STATUS\r
336EFIAPI\r
337AmlCodeGenName (\r
338 IN CONST CHAR8 * NameString,\r
339 IN AML_OBJECT_NODE * Object,\r
340 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
341 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
342 )\r
343{\r
344 EFI_STATUS Status;\r
345 AML_OBJECT_NODE * ObjectNode;\r
346 AML_DATA_NODE * DataNode;\r
347 CHAR8 * AmlNameString;\r
348 UINT32 AmlNameStringSize;\r
349\r
350 if ((NameString == NULL) ||\r
351 (Object == NULL) ||\r
352 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
353 ASSERT (0);\r
354 return EFI_INVALID_PARAMETER;\r
355 }\r
356\r
357 ObjectNode = NULL;\r
358 DataNode = NULL;\r
359 AmlNameString = NULL;\r
360\r
361 Status = ConvertAslNameToAmlName (NameString, &AmlNameString);\r
362 if (EFI_ERROR (Status)) {\r
363 ASSERT (0);\r
364 return Status;\r
365 }\r
366\r
367 Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);\r
368 if (EFI_ERROR (Status)) {\r
369 ASSERT (0);\r
370 goto error_handler1;\r
371 }\r
372\r
373 Status = AmlCreateObjectNode (\r
374 AmlGetByteEncodingByOpCode (AML_NAME_OP, 0),\r
375 0,\r
376 &ObjectNode\r
377 );\r
378 if (EFI_ERROR (Status)) {\r
379 ASSERT (0);\r
380 goto error_handler1;\r
381 }\r
382\r
383 Status = AmlCreateDataNode (\r
384 EAmlNodeDataTypeNameString,\r
385 (UINT8*)AmlNameString,\r
386 AmlNameStringSize,\r
387 &DataNode\r
388 );\r
389 if (EFI_ERROR (Status)) {\r
390 ASSERT (0);\r
391 goto error_handler2;\r
392 }\r
393\r
394 Status = AmlSetFixedArgument (\r
395 ObjectNode,\r
396 EAmlParseIndexTerm0,\r
397 (AML_NODE_HEADER*)DataNode\r
398 );\r
399 if (EFI_ERROR (Status)) {\r
400 ASSERT (0);\r
401 AmlDeleteTree ((AML_NODE_HEADER*)DataNode);\r
402 goto error_handler2;\r
403 }\r
404\r
405 Status = AmlSetFixedArgument (\r
406 ObjectNode,\r
407 EAmlParseIndexTerm1,\r
408 (AML_NODE_HEADER*)Object\r
409 );\r
410 if (EFI_ERROR (Status)) {\r
411 ASSERT (0);\r
412 goto error_handler2;\r
413 }\r
414\r
415 Status = LinkNode (\r
416 ObjectNode,\r
417 ParentNode,\r
418 NewObjectNode\r
419 );\r
420 if (EFI_ERROR (Status)) {\r
421 ASSERT (0);\r
422 goto error_handler2;\r
423 }\r
424\r
425 // Free AmlNameString before returning as it is copied\r
426 // in the call to AmlCreateDataNode().\r
427 goto error_handler1;\r
428\r
429error_handler2:\r
430 if (ObjectNode != NULL) {\r
431 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
432 }\r
433\r
434error_handler1:\r
435 if (AmlNameString != NULL) {\r
436 FreePool (AmlNameString);\r
437 }\r
438\r
439 return Status;\r
440}\r
441\r
442/** AML code generation for a Name object node, containing a String.\r
443\r
444 AmlCodeGenNameString ("_HID", "HID0000", ParentNode, NewObjectNode) is\r
445 equivalent of the following ASL code:\r
446 Name(_HID, "HID0000")\r
447\r
448 @param [in] NameString The new variable name.\r
449 Must be a NULL-terminated ASL NameString\r
450 e.g.: "DEV0", "DV15.DEV0", etc.\r
451 The input string is copied.\r
452 @param [in] String NULL terminated String to associate to the\r
453 NameString.\r
454 @param [in] ParentNode If provided, set ParentNode as the parent\r
455 of the node created.\r
456 @param [out] NewObjectNode If success, contains the created node.\r
457\r
458 @retval EFI_SUCCESS Success.\r
459 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
460 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
461**/\r
462EFI_STATUS\r
463EFIAPI\r
464AmlCodeGenNameString (\r
465 IN CONST CHAR8 * NameString,\r
466 IN CHAR8 * String,\r
467 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
468 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
469 )\r
470{\r
471 EFI_STATUS Status;\r
472 AML_OBJECT_NODE * ObjectNode;\r
473\r
474 if ((NameString == NULL) ||\r
475 (String == NULL) ||\r
476 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
477 ASSERT (0);\r
478 return EFI_INVALID_PARAMETER;\r
479 }\r
480\r
481 Status = AmlCodeGenString (String, &ObjectNode);\r
482 if (EFI_ERROR (Status)) {\r
483 ASSERT (0);\r
484 return Status;\r
485 }\r
486\r
487 Status = AmlCodeGenName (\r
488 NameString,\r
489 ObjectNode,\r
490 ParentNode,\r
491 NewObjectNode\r
492 );\r
493 if (EFI_ERROR (Status)) {\r
494 ASSERT (0);\r
495 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
496 }\r
497\r
498 return Status;\r
499}\r
500\r
501/** AML code generation for a Name object node, containing an Integer.\r
502\r
503 AmlCodeGenNameInteger ("_UID", 1, ParentNode, NewObjectNode) is\r
504 equivalent of the following ASL code:\r
505 Name(_UID, One)\r
506\r
507 @param [in] NameString The new variable name.\r
508 Must be a NULL-terminated ASL NameString\r
509 e.g.: "DEV0", "DV15.DEV0", etc.\r
510 The input string is copied.\r
511 @param [in] Integer Integer to associate to the NameString.\r
512 @param [in] ParentNode If provided, set ParentNode as the parent\r
513 of the node created.\r
514 @param [out] NewObjectNode If success, contains the created node.\r
515\r
516 @retval EFI_SUCCESS Success.\r
517 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
518 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
519**/\r
520EFI_STATUS\r
521EFIAPI\r
522AmlCodeGenNameInteger (\r
523 IN CONST CHAR8 * NameString,\r
524 IN UINT64 Integer,\r
525 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
526 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
527 )\r
528{\r
529 EFI_STATUS Status;\r
530 AML_OBJECT_NODE * ObjectNode;\r
531\r
532 if ((NameString == NULL) ||\r
533 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
534 ASSERT (0);\r
535 return EFI_INVALID_PARAMETER;\r
536 }\r
537\r
538 Status = AmlCodeGenInteger (Integer, &ObjectNode);\r
539 if (EFI_ERROR (Status)) {\r
540 ASSERT (0);\r
541 return Status;\r
542 }\r
543\r
544 Status = AmlCodeGenName (\r
545 NameString,\r
546 ObjectNode,\r
547 ParentNode,\r
548 NewObjectNode\r
549 );\r
550 if (EFI_ERROR (Status)) {\r
551 ASSERT (0);\r
552 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
553 }\r
554\r
555 return Status;\r
556}\r
557\r
558/** AML code generation for a Device object node.\r
559\r
560 AmlCodeGenDevice ("COM0", ParentNode, NewObjectNode) is\r
561 equivalent of the following ASL code:\r
562 Device(COM0) {}\r
563\r
564 @param [in] NameString The new Device's name.\r
565 Must be a NULL-terminated ASL NameString\r
566 e.g.: "DEV0", "DV15.DEV0", etc.\r
567 The input string is copied.\r
568 @param [in] ParentNode If provided, set ParentNode as the parent\r
569 of the node created.\r
570 @param [out] NewObjectNode If success, contains the created node.\r
571\r
572 @retval EFI_SUCCESS Success.\r
573 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
574 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
575**/\r
576EFI_STATUS\r
577EFIAPI\r
578AmlCodeGenDevice (\r
579 IN CONST CHAR8 * NameString,\r
580 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
581 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
582 )\r
583{\r
584 EFI_STATUS Status;\r
585 AML_OBJECT_NODE * ObjectNode;\r
586 AML_DATA_NODE * DataNode;\r
587 CHAR8 * AmlNameString;\r
588 UINT32 AmlNameStringSize;\r
589\r
590 if ((NameString == NULL) ||\r
591 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
592 ASSERT (0);\r
593 return EFI_INVALID_PARAMETER;\r
594 }\r
595\r
596 ObjectNode = NULL;\r
597 DataNode = NULL;\r
598 AmlNameString = NULL;\r
599\r
600 Status = ConvertAslNameToAmlName (NameString, &AmlNameString);\r
601 if (EFI_ERROR (Status)) {\r
602 ASSERT (0);\r
603 return Status;\r
604 }\r
605\r
606 Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);\r
607 if (EFI_ERROR (Status)) {\r
608 ASSERT (0);\r
609 goto error_handler1;\r
610 }\r
611\r
612 Status = AmlCreateObjectNode (\r
613 AmlGetByteEncodingByOpCode (AML_EXT_OP, AML_EXT_DEVICE_OP),\r
614 AmlNameStringSize + AmlComputePkgLengthWidth (AmlNameStringSize),\r
615 &ObjectNode\r
616 );\r
617 if (EFI_ERROR (Status)) {\r
618 ASSERT (0);\r
619 goto error_handler1;\r
620 }\r
621\r
622 Status = AmlCreateDataNode (\r
623 EAmlNodeDataTypeNameString,\r
624 (UINT8*)AmlNameString,\r
625 AmlNameStringSize,\r
626 &DataNode\r
627 );\r
628 if (EFI_ERROR (Status)) {\r
629 ASSERT (0);\r
630 goto error_handler2;\r
631 }\r
632\r
633 Status = AmlSetFixedArgument (\r
634 ObjectNode,\r
635 EAmlParseIndexTerm0,\r
636 (AML_NODE_HEADER*)DataNode\r
637 );\r
638 if (EFI_ERROR (Status)) {\r
639 ASSERT (0);\r
640 AmlDeleteTree ((AML_NODE_HEADER*)DataNode);\r
641 goto error_handler2;\r
642 }\r
643\r
644 Status = LinkNode (\r
645 ObjectNode,\r
646 ParentNode,\r
647 NewObjectNode\r
648 );\r
649 if (EFI_ERROR (Status)) {\r
650 ASSERT (0);\r
651 goto error_handler2;\r
652 }\r
653\r
654 // Free AmlNameString before returning as it is copied\r
655 // in the call to AmlCreateDataNode().\r
656 goto error_handler1;\r
657\r
658error_handler2:\r
659 if (ObjectNode != NULL) {\r
660 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
661 }\r
662\r
663error_handler1:\r
664 if (AmlNameString != NULL) {\r
665 FreePool (AmlNameString);\r
666 }\r
667\r
668 return Status;\r
669}\r
670\r
671/** AML code generation for a Scope object node.\r
672\r
673 AmlCodeGenScope ("_SB", ParentNode, NewObjectNode) is\r
674 equivalent of the following ASL code:\r
675 Scope(_SB) {}\r
676\r
677 @param [in] NameString The new Scope's name.\r
678 Must be a NULL-terminated ASL NameString\r
679 e.g.: "DEV0", "DV15.DEV0", etc.\r
680 The input string is copied.\r
681 @param [in] ParentNode If provided, set ParentNode as the parent\r
682 of the node created.\r
683 @param [out] NewObjectNode If success, contains the created node.\r
684\r
685 @retval EFI_SUCCESS Success.\r
686 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
687 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
688**/\r
689EFI_STATUS\r
690EFIAPI\r
691AmlCodeGenScope (\r
692 IN CONST CHAR8 * NameString,\r
693 IN AML_NODE_HEADER * ParentNode, OPTIONAL\r
694 OUT AML_OBJECT_NODE ** NewObjectNode OPTIONAL\r
695 )\r
696{\r
697 EFI_STATUS Status;\r
698 AML_OBJECT_NODE * ObjectNode;\r
699 AML_DATA_NODE * DataNode;\r
700 CHAR8 * AmlNameString;\r
701 UINT32 AmlNameStringSize;\r
702\r
703 if ((NameString == NULL) ||\r
704 ((ParentNode == NULL) && (NewObjectNode == NULL))) {\r
705 ASSERT (0);\r
706 return EFI_INVALID_PARAMETER;\r
707 }\r
708\r
709 ObjectNode = NULL;\r
710 DataNode = NULL;\r
711 AmlNameString = NULL;\r
712\r
713 Status = ConvertAslNameToAmlName (NameString, &AmlNameString);\r
714 if (EFI_ERROR (Status)) {\r
715 ASSERT (0);\r
716 return Status;\r
717 }\r
718\r
719 Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);\r
720 if (EFI_ERROR (Status)) {\r
721 ASSERT (0);\r
722 goto error_handler1;\r
723 }\r
724\r
725 Status = AmlCreateObjectNode (\r
726 AmlGetByteEncodingByOpCode (AML_SCOPE_OP, 0),\r
727 AmlNameStringSize + AmlComputePkgLengthWidth (AmlNameStringSize),\r
728 &ObjectNode\r
729 );\r
730 if (EFI_ERROR (Status)) {\r
731 ASSERT (0);\r
732 goto error_handler1;\r
733 }\r
734\r
735 Status = AmlCreateDataNode (\r
736 EAmlNodeDataTypeNameString,\r
737 (UINT8*)AmlNameString,\r
738 AmlNameStringSize,\r
739 &DataNode\r
740 );\r
741 if (EFI_ERROR (Status)) {\r
742 ASSERT (0);\r
743 goto error_handler2;\r
744 }\r
745\r
746 Status = AmlSetFixedArgument (\r
747 ObjectNode,\r
748 EAmlParseIndexTerm0,\r
749 (AML_NODE_HEADER*)DataNode\r
750 );\r
751 if (EFI_ERROR (Status)) {\r
752 ASSERT (0);\r
753 AmlDeleteTree ((AML_NODE_HEADER*)DataNode);\r
754 goto error_handler2;\r
755 }\r
756\r
757 Status = LinkNode (\r
758 ObjectNode,\r
759 ParentNode,\r
760 NewObjectNode\r
761 );\r
762 if (EFI_ERROR (Status)) {\r
763 ASSERT (0);\r
764 goto error_handler2;\r
765 }\r
766\r
767 // Free AmlNameString before returning as it is copied\r
768 // in the call to AmlCreateDataNode().\r
769 goto error_handler1;\r
770\r
771error_handler2:\r
772 if (ObjectNode != NULL) {\r
773 AmlDeleteTree ((AML_NODE_HEADER*)ObjectNode);\r
774 }\r
775\r
776error_handler1:\r
777 if (AmlNameString != NULL) {\r
778 FreePool (AmlNameString);\r
779 }\r
780\r
781 return Status;\r
782}\r