]> git.proxmox.com Git - mirror_edk2.git/blob - DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c
DynamicTablesPkg: Apply uncrustify changes
[mirror_edk2.git] / DynamicTablesPkg / Library / Acpi / Arm / AcpiSsdtCmn600LibArm / SsdtCmn600Generator.c
1 /** @file
2 SSDT CMN-600 AML Table Generator.
3
4 Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 @par Reference(s):
9 - Arm CoreLink CMN-600 Coherent Mesh Network Technical Reference Manual r3p0
10 - Generic ACPI for Arm Components 1.0 Platform Design Document
11 **/
12
13 #include <Library/AcpiLib.h>
14 #include <Library/BaseLib.h>
15 #include <Library/BaseMemoryLib.h>
16 #include <Library/DebugLib.h>
17 #include <Library/MemoryAllocationLib.h>
18 #include <Protocol/AcpiTable.h>
19
20 // Module specific include files.
21 #include <AcpiTableGenerator.h>
22 #include <ConfigurationManagerObject.h>
23 #include <ConfigurationManagerHelper.h>
24 #include <Library/AcpiHelperLib.h>
25 #include <Library/AmlLib/AmlLib.h>
26 #include <Protocol/ConfigurationManagerProtocol.h>
27 #include "SsdtCmn600Generator.h"
28
29 /** C array containing the compiled AML template.
30 This symbol is defined in the auto generated C file
31 containing the AML bytecode array.
32 */
33 extern CHAR8 ssdtcmn600template_aml_code[];
34
35 /** SSDT CMN-600 Table Generator.
36
37 Requirements:
38 The following Configuration Manager Object(s) are required by
39 this Generator:
40 - EArmObjCmn600Info
41 */
42
43 /** This macro expands to a function that retrieves the CMN-600
44 Information from the Configuration Manager.
45 */
46 GET_OBJECT_LIST (
47 EObjNameSpaceArm,
48 EArmObjCmn600Info,
49 CM_ARM_CMN_600_INFO
50 );
51
52 /** Check the CMN-600 Information.
53
54 @param [in] Cmn600InfoList Array of CMN-600 information structure.
55 @param [in] Cmn600Count Count of CMN-600 information structure.
56
57 @retval EFI_SUCCESS The function completed successfully.
58 @retval EFI_INVALID_PARAMETER Invalid parameter.
59 **/
60 STATIC
61 EFI_STATUS
62 EFIAPI
63 ValidateCmn600Info (
64 IN CONST CM_ARM_CMN_600_INFO *Cmn600InfoList,
65 IN CONST UINT32 Cmn600Count
66 )
67 {
68 UINT32 Index;
69 UINT32 DtcIndex;
70 CONST CM_ARM_CMN_600_INFO *Cmn600Info;
71 CONST CM_ARM_GENERIC_INTERRUPT *DtcInterrupt;
72
73 if ((Cmn600InfoList == NULL) ||
74 (Cmn600Count == 0))
75 {
76 return EFI_INVALID_PARAMETER;
77 }
78
79 // Validate each Cmn600Info structure.
80 for (Index = 0; Index < Cmn600Count; Index++) {
81 Cmn600Info = &Cmn600InfoList[Index];
82
83 // At least one DTC is required.
84 if ((Cmn600Info->DtcCount == 0) ||
85 (Cmn600Info->DtcCount > MAX_DTC_COUNT))
86 {
87 DEBUG ((
88 DEBUG_ERROR,
89 "ERROR: SSDT-CMN-600: Invalid DTC configuration:\n"
90 ));
91 goto error_handler;
92 }
93
94 // Check PERIPHBASE and ROOTNODEBASE address spaces are initialized.
95 if ((Cmn600Info->PeriphBaseAddress == 0) ||
96 (Cmn600Info->RootNodeBaseAddress == 0))
97 {
98 DEBUG ((
99 DEBUG_ERROR,
100 "ERROR: SSDT-CMN-600: Invalid PERIPHBASE or ROOTNODEBASE.\n"
101 ));
102 goto error_handler;
103 }
104
105 // The PERIPHBASE address must be 64MB aligned for a (X < 4) && (Y < 4)
106 // dimension mesh, and 256MB aligned otherwise.
107 // Check it is a least 64MB aligned.
108 if ((Cmn600Info->PeriphBaseAddress &
109 (PERIPHBASE_MIN_ADDRESS_LENGTH - 1)) != 0)
110 {
111 DEBUG ((
112 DEBUG_ERROR,
113 "ERROR: SSDT-CMN-600: PERIPHBASE address must be 64MB aligned.\n"
114 ));
115 goto error_handler;
116 }
117
118 // The PERIPHBASE address is at most 64MB for a (X < 4) && (Y < 4)
119 // dimension mesh, and 256MB otherwise. Check it is not more than 256MB.
120 if (Cmn600Info->PeriphBaseAddressLength > PERIPHBASE_MAX_ADDRESS_LENGTH) {
121 DEBUG ((
122 DEBUG_ERROR,
123 "ERROR: SSDT-CMN-600: PERIPHBASE address range must be < 256MB.\n"
124 ));
125 goto error_handler;
126 }
127
128 // Check the 16 KB alignment of the ROOTNODEBASE address.
129 if ((Cmn600Info->PeriphBaseAddress &
130 (ROOTNODEBASE_ADDRESS_LENGTH - 1)) != 0)
131 {
132 DEBUG ((
133 DEBUG_ERROR,
134 "ERROR: SSDT-CMN-600: Root base address must be 16KB aligned.\n"
135 ));
136 goto error_handler;
137 }
138
139 // The ROOTNODEBASE address space should be included in the PERIPHBASE
140 // address space.
141 if ((Cmn600Info->PeriphBaseAddress > Cmn600Info->RootNodeBaseAddress) ||
142 ((Cmn600Info->PeriphBaseAddress + Cmn600Info->PeriphBaseAddressLength) <
143 (Cmn600Info->RootNodeBaseAddress + ROOTNODEBASE_ADDRESS_LENGTH)))
144 {
145 DEBUG ((
146 DEBUG_ERROR,
147 "ERROR: SSDT-CMN-600:"
148 " ROOTNODEBASE address space not in PERIPHBASE address space.\n"
149 ));
150 goto error_handler;
151 }
152
153 for (DtcIndex = 0; DtcIndex < Cmn600Info->DtcCount; DtcIndex++) {
154 DtcInterrupt = &Cmn600Info->DtcInterrupt[DtcIndex];
155 if (((DtcInterrupt->Flags &
156 EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK) == 0))
157 {
158 DEBUG ((
159 DEBUG_ERROR,
160 "ERROR: SSDT-CMN-600: DTC Interrupt must be consumer.\n"
161 ));
162 goto error_handler;
163 }
164 } // for DTC Interrupt
165 } // for Cmn600InfoList
166
167 return EFI_SUCCESS;
168
169 error_handler:
170
171 DEBUG ((
172 DEBUG_ERROR,
173 "PeriphBaseAddress = 0x%llx\n"
174 "PeriphBaseAddressLength = 0x%llx\n"
175 "RootNodeBaseAddress = 0x%llx\n"
176 "DtcCount = %u\n",
177 Cmn600Info->PeriphBaseAddress,
178 Cmn600Info->PeriphBaseAddressLength,
179 Cmn600Info->RootNodeBaseAddress,
180 Cmn600Info->DtcCount
181 ));
182
183 DEBUG_CODE_BEGIN ();
184 for (DtcIndex = 0; DtcIndex < Cmn600Info->DtcCount; DtcIndex++) {
185 DtcInterrupt = &Cmn600Info->DtcInterrupt[DtcIndex];
186 DEBUG ((
187 DEBUG_ERROR,
188 " DTC[%d]:\n",
189 DtcIndex
190 ));
191 DEBUG ((
192 DEBUG_ERROR,
193 " Interrupt = 0x%lx\n",
194 DtcInterrupt->Interrupt
195 ));
196 DEBUG ((
197 DEBUG_ERROR,
198 " Flags = 0x%lx\n",
199 DtcInterrupt->Flags
200 ));
201 } // for
202
203 DEBUG_CODE_END ();
204
205 return EFI_INVALID_PARAMETER;
206 }
207
208 /** Build a SSDT table describing the CMN-600 device.
209
210 The table created by this function must be freed by FreeSsdtCmn600Table.
211
212 @param [in] Cmn600Info Pointer to a Cmn600 structure.
213 @param [in] Name The Name to give to the Device.
214 Must be a NULL-terminated ASL NameString
215 e.g.: "DEV0", "DV15.DEV0", etc.
216 @param [in] Uid UID for the CMN600 device.
217 @param [out] Table If success, pointer to the created SSDT table.
218
219 @retval EFI_SUCCESS Table generated successfully.
220 @retval EFI_INVALID_PARAMETER A parameter is invalid.
221 @retval EFI_NOT_FOUND Could not find information.
222 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
223 **/
224 STATIC
225 EFI_STATUS
226 EFIAPI
227 FixupCmn600Info (
228 IN CONST CM_ARM_CMN_600_INFO *Cmn600Info,
229 IN CONST CHAR8 *Name,
230 IN CONST UINT64 Uid,
231 OUT EFI_ACPI_DESCRIPTION_HEADER **Table
232 )
233 {
234 EFI_STATUS Status;
235 EFI_STATUS Status1;
236 UINT8 Index;
237 CONST CM_ARM_GENERIC_INTERRUPT *DtcInt;
238
239 EFI_ACPI_DESCRIPTION_HEADER *SsdtCmn600Template;
240 AML_ROOT_NODE_HANDLE RootNodeHandle;
241 AML_OBJECT_NODE_HANDLE NameOpIdNode;
242 AML_OBJECT_NODE_HANDLE NameOpCrsNode;
243 AML_DATA_NODE_HANDLE CmnPeriphBaseRdNode;
244 AML_DATA_NODE_HANDLE CmnRootNodeBaseRdNode;
245 AML_OBJECT_NODE_HANDLE DeviceNode;
246
247 // Parse the Ssdt CMN-600 Template.
248 SsdtCmn600Template = (EFI_ACPI_DESCRIPTION_HEADER *)
249 ssdtcmn600template_aml_code;
250
251 RootNodeHandle = NULL;
252 Status = AmlParseDefinitionBlock (
253 SsdtCmn600Template,
254 &RootNodeHandle
255 );
256 if (EFI_ERROR (Status)) {
257 DEBUG ((
258 DEBUG_ERROR,
259 "ERROR: SSDT-CMN-600: Failed to parse SSDT CMN-600 Template."
260 " Status = %r\n",
261 Status
262 ));
263 return Status;
264 }
265
266 // Get the _UID NameOp object defined by the "Name ()" statement,
267 // and update its value.
268 Status = AmlFindNode (
269 RootNodeHandle,
270 "\\_SB_.CMN0._UID",
271 &NameOpIdNode
272 );
273 if (EFI_ERROR (Status)) {
274 goto error_handler;
275 }
276
277 Status = AmlNameOpUpdateInteger (NameOpIdNode, (UINT64)Uid);
278 if (EFI_ERROR (Status)) {
279 goto error_handler;
280 }
281
282 // Get the _CRS object defined by the "Name ()" statement.
283 Status = AmlFindNode (
284 RootNodeHandle,
285 "\\_SB.CMN0._CRS",
286 &NameOpCrsNode
287 );
288 if (EFI_ERROR (Status)) {
289 goto error_handler;
290 }
291
292 // Get the first Rd node in the "_CRS" object.
293 // This is the PERIPHBASE node.
294 Status = AmlNameOpGetFirstRdNode (NameOpCrsNode, &CmnPeriphBaseRdNode);
295 if (EFI_ERROR (Status)) {
296 goto error_handler;
297 }
298
299 if (CmnPeriphBaseRdNode == NULL) {
300 Status = EFI_INVALID_PARAMETER;
301 goto error_handler;
302 }
303
304 // Update the PERIPHBASE base address and length.
305 Status = AmlUpdateRdQWord (
306 CmnPeriphBaseRdNode,
307 Cmn600Info->PeriphBaseAddress,
308 Cmn600Info->PeriphBaseAddressLength
309 );
310 if (EFI_ERROR (Status)) {
311 goto error_handler;
312 }
313
314 // Get the QWord node corresponding to the ROOTNODEBASE.
315 // It is the second Resource Data element in the BufferNode's
316 // variable list of arguments.
317 Status = AmlNameOpGetNextRdNode (
318 CmnPeriphBaseRdNode,
319 &CmnRootNodeBaseRdNode
320 );
321 if (EFI_ERROR (Status)) {
322 goto error_handler;
323 }
324
325 if (CmnRootNodeBaseRdNode == NULL) {
326 Status = EFI_INVALID_PARAMETER;
327 goto error_handler;
328 }
329
330 // Update the ROOTNODEBASE base address and length.
331 Status = AmlUpdateRdQWord (
332 CmnRootNodeBaseRdNode,
333 Cmn600Info->RootNodeBaseAddress,
334 ROOTNODEBASE_ADDRESS_LENGTH
335 );
336 if (EFI_ERROR (Status)) {
337 goto error_handler;
338 }
339
340 // Add the Interrupt node(s).
341 // Generate Resource Data node(s) corresponding to the "Interrupt ()"
342 // ASL function and add it at the last position in the list of
343 // Resource Data nodes.
344 for (Index = 0; Index < Cmn600Info->DtcCount; Index++) {
345 DtcInt = &Cmn600Info->DtcInterrupt[Index];
346
347 Status = AmlCodeGenRdInterrupt (
348 ((DtcInt->Flags &
349 EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK) != 0),
350 ((DtcInt->Flags &
351 EFI_ACPI_EXTENDED_INTERRUPT_FLAG_MODE_MASK) != 0),
352 ((DtcInt->Flags &
353 EFI_ACPI_EXTENDED_INTERRUPT_FLAG_POLARITY_MASK) != 0),
354 ((DtcInt->Flags &
355 EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARABLE_MASK) != 0),
356 (UINT32 *)&DtcInt->Interrupt,
357 1,
358 NameOpCrsNode,
359 NULL
360 );
361 if (EFI_ERROR (Status)) {
362 goto error_handler;
363 }
364 } // for
365
366 // Fixup the CMN600 device name.
367 // This MUST be done at the end, otherwise AML paths won't be valid anymore.
368 // Get the CMN0 variable defined by the "Device ()" statement.
369 Status = AmlFindNode (RootNodeHandle, "\\_SB_.CMN0", &DeviceNode);
370 if (EFI_ERROR (Status)) {
371 goto error_handler;
372 }
373
374 // Update the CMN600 Device's name.
375 Status = AmlDeviceOpUpdateName (DeviceNode, (CHAR8 *)Name);
376 if (EFI_ERROR (Status)) {
377 goto error_handler;
378 }
379
380 // Serialise the definition block
381 Status = AmlSerializeDefinitionBlock (
382 RootNodeHandle,
383 Table
384 );
385 if (EFI_ERROR (Status)) {
386 DEBUG ((
387 DEBUG_ERROR,
388 "ERROR: SSDT-CMN-600: Failed to Serialize SSDT Table Data."
389 " Status = %r\n",
390 Status
391 ));
392 }
393
394 error_handler:
395 // Cleanup
396 if (RootNodeHandle != NULL) {
397 Status1 = AmlDeleteTree (RootNodeHandle);
398 if (EFI_ERROR (Status1)) {
399 DEBUG ((
400 DEBUG_ERROR,
401 "ERROR: SSDT-CMN-600: Failed to cleanup AML tree."
402 " Status = %r\n",
403 Status1
404 ));
405 // If Status was success but we failed to delete the AML Tree
406 // return Status1 else return the original error code, i.e. Status.
407 if (!EFI_ERROR (Status)) {
408 return Status1;
409 }
410 }
411 }
412
413 return Status;
414 }
415
416 /** Free any resources allocated for constructing the SSDT tables for CMN-600.
417
418 @param [in] This Pointer to the ACPI table generator.
419 @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
420 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
421 Protocol Interface.
422 @param [in, out] Table Pointer to an array of pointers
423 to ACPI Table(s).
424 @param [in] TableCount Number of ACPI table(s).
425
426 @retval EFI_SUCCESS The resources were freed successfully.
427 @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
428 **/
429 STATIC
430 EFI_STATUS
431 EFIAPI
432 FreeSsdtCmn600TableResourcesEx (
433 IN CONST ACPI_TABLE_GENERATOR *CONST This,
434 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
435 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
436 IN OUT EFI_ACPI_DESCRIPTION_HEADER ***CONST Table,
437 IN CONST UINTN TableCount
438 )
439 {
440 EFI_ACPI_DESCRIPTION_HEADER **TableList;
441 UINTN Index;
442
443 ASSERT (This != NULL);
444 ASSERT (AcpiTableInfo != NULL);
445 ASSERT (CfgMgrProtocol != NULL);
446 ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
447 ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
448
449 if ((Table == NULL) ||
450 (*Table == NULL) ||
451 (TableCount == 0))
452 {
453 DEBUG ((DEBUG_ERROR, "ERROR: SSDT-CMN-600: Invalid Table Pointer\n"));
454 return EFI_INVALID_PARAMETER;
455 }
456
457 TableList = *Table;
458
459 for (Index = 0; Index < TableCount; Index++) {
460 if ((TableList[Index] != NULL) &&
461 (TableList[Index]->Signature ==
462 EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE))
463 {
464 FreePool (TableList[Index]);
465 } else {
466 DEBUG ((
467 DEBUG_ERROR,
468 "ERROR: SSDT-CMN-600: Could not free SSDT table at index %d."
469 " Status = %r\n",
470 Index,
471 EFI_INVALID_PARAMETER
472 ));
473 return EFI_INVALID_PARAMETER;
474 }
475 } // for
476
477 // Free the table list.
478 FreePool (*Table);
479 *Table = NULL;
480 return EFI_SUCCESS;
481 }
482
483 /** Construct SSDT tables for describing CMN-600 meshes.
484
485 This function invokes the Configuration Manager protocol interface
486 to get the required hardware information for generating the ACPI
487 table.
488
489 If this function allocates any resources then they must be freed
490 in the FreeXXXXTableResourcesEx function.
491
492 @param [in] This Pointer to the ACPI table generator.
493 @param [in] AcpiTableInfo Pointer to the ACPI table information.
494 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
495 Protocol interface.
496 @param [out] Table Pointer to a list of generated ACPI table(s).
497 @param [out] TableCount Number of generated ACPI table(s).
498
499 @retval EFI_SUCCESS Table generated successfully.
500 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
501 Manager is less than the Object size for
502 the requested object.
503 @retval EFI_INVALID_PARAMETER A parameter is invalid.
504 @retval EFI_NOT_FOUND Could not find information.
505 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
506 @retval EFI_UNSUPPORTED Unsupported configuration.
507 **/
508 STATIC
509 EFI_STATUS
510 EFIAPI
511 BuildSsdtCmn600TableEx (
512 IN CONST ACPI_TABLE_GENERATOR *This,
513 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
514 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
515 OUT EFI_ACPI_DESCRIPTION_HEADER ***Table,
516 OUT UINTN *CONST TableCount
517 )
518 {
519 EFI_STATUS Status;
520 UINT64 Index;
521 CM_ARM_CMN_600_INFO *Cmn600Info;
522 UINT32 Cmn600Count;
523 CHAR8 NewName[AML_NAME_SEG_SIZE + 1];
524 EFI_ACPI_DESCRIPTION_HEADER **TableList;
525
526 ASSERT (This != NULL);
527 ASSERT (AcpiTableInfo != NULL);
528 ASSERT (CfgMgrProtocol != NULL);
529 ASSERT (Table != NULL);
530 ASSERT (TableCount != NULL);
531 ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
532 ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
533
534 *Table = NULL;
535
536 // Get CMN-600 information.
537 Status = GetEArmObjCmn600Info (
538 CfgMgrProtocol,
539 CM_NULL_TOKEN,
540 &Cmn600Info,
541 &Cmn600Count
542 );
543 if (EFI_ERROR (Status)) {
544 DEBUG ((
545 DEBUG_ERROR,
546 "ERROR: SSDT-CMN-600: Failed to get the CMN-600 information."
547 " Status = %r\n",
548 Status
549 ));
550 return Status;
551 }
552
553 if ((Cmn600Count == 0) || (Cmn600Count > MAX_CMN600_DEVICES_SUPPORTED)) {
554 DEBUG ((
555 DEBUG_ERROR,
556 "ERROR: SSDT-CMN-600: CMN600 peripheral count = %d."
557 " This must be between 1 to 16.\n",
558 Cmn600Count
559 ));
560 return EFI_INVALID_PARAMETER;
561 }
562
563 // Validate the CMN-600 Info.
564 Status = ValidateCmn600Info (Cmn600Info, Cmn600Count);
565 if (EFI_ERROR (Status)) {
566 DEBUG ((
567 DEBUG_ERROR,
568 "ERROR: SSDT-CMN-600: Invalid CMN600 information. Status = %r\n",
569 Status
570 ));
571 return Status;
572 }
573
574 // Allocate a table to store pointers to the SSDT tables.
575 TableList = (EFI_ACPI_DESCRIPTION_HEADER **)
576 AllocateZeroPool (
577 (sizeof (EFI_ACPI_DESCRIPTION_HEADER *) * Cmn600Count)
578 );
579 if (TableList == NULL) {
580 Status = EFI_OUT_OF_RESOURCES;
581 DEBUG ((
582 DEBUG_ERROR,
583 "ERROR: SSDT-CMN-600: Failed to allocate memory for Table List."
584 " Status = %r\n",
585 Status
586 ));
587 return Status;
588 }
589
590 // Setup the table list early so that that appropriate cleanup
591 // can be done in case of failure.
592 *Table = TableList;
593
594 NewName[0] = 'C';
595 NewName[1] = 'M';
596 NewName[2] = 'N';
597 NewName[4] = '\0';
598 for (Index = 0; Index < Cmn600Count; Index++) {
599 NewName[3] = AsciiFromHex ((UINT8)(Index));
600
601 // Build a SSDT table describing the CMN600 device.
602 Status = FixupCmn600Info (
603 &Cmn600Info[Index],
604 NewName,
605 Index,
606 &TableList[Index]
607 );
608 if (EFI_ERROR (Status)) {
609 DEBUG ((
610 DEBUG_ERROR,
611 "ERROR: SSDT-CMN-600: Failed to build associated SSDT table."
612 " Status = %r\n",
613 Status
614 ));
615 break;
616 }
617
618 // Increment the table count here so that appropriate clean-up
619 // can be done in case of failure.
620 *TableCount += 1;
621 } // for
622
623 // Note: Table list and CMN600 device count has been setup. The
624 // framework will invoke FreeSsdtCmn600TableResourcesEx() even
625 // on failure, so appropriate clean-up will be done.
626 return Status;
627 }
628
629 /** This macro defines the Raw Generator revision.
630 */
631 #define SSDT_CMN_600_GENERATOR_REVISION CREATE_REVISION (1, 0)
632
633 /** The interface for the Raw Table Generator.
634 */
635 STATIC
636 CONST
637 ACPI_TABLE_GENERATOR SsdtCmn600Generator = {
638 // Generator ID
639 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtCmn600),
640 // Generator Description
641 L"ACPI.STD.SSDT.CMN600.GENERATOR",
642 // ACPI Table Signature
643 EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
644 // ACPI Table Revision - Unused
645 0,
646 // Minimum ACPI Table Revision - Unused
647 0,
648 // Creator ID
649 TABLE_GENERATOR_CREATOR_ID_ARM,
650 // Creator Revision
651 SSDT_CMN_600_GENERATOR_REVISION,
652 // Build table function. Use the extended version instead.
653 NULL,
654 // Free table function. Use the extended version instead.
655 NULL,
656 // Build Table function
657 BuildSsdtCmn600TableEx,
658 // Free Resource function
659 FreeSsdtCmn600TableResourcesEx
660 };
661
662 /** Register the Generator with the ACPI Table Factory.
663
664 @param [in] ImageHandle The handle to the image.
665 @param [in] SystemTable Pointer to the System Table.
666
667 @retval EFI_SUCCESS The Generator is registered.
668 @retval EFI_INVALID_PARAMETER A parameter is invalid.
669 @retval EFI_ALREADY_STARTED The Generator for the Table ID
670 is already registered.
671 **/
672 EFI_STATUS
673 EFIAPI
674 AcpiSsdtCmn600LibConstructor (
675 IN EFI_HANDLE ImageHandle,
676 IN EFI_SYSTEM_TABLE *SystemTable
677 )
678 {
679 EFI_STATUS Status;
680
681 Status = RegisterAcpiTableGenerator (&SsdtCmn600Generator);
682 DEBUG ((
683 DEBUG_INFO,
684 "SSDT-CMN-600: Register Generator. Status = %r\n",
685 Status
686 ));
687 ASSERT_EFI_ERROR (Status);
688 return Status;
689 }
690
691 /** Deregister the Generator from the ACPI Table Factory.
692
693 @param [in] ImageHandle The handle to the image.
694 @param [in] SystemTable Pointer to the System Table.
695
696 @retval EFI_SUCCESS The Generator is deregistered.
697 @retval EFI_INVALID_PARAMETER A parameter is invalid.
698 @retval EFI_NOT_FOUND The Generator is not registered.
699 **/
700 EFI_STATUS
701 EFIAPI
702 AcpiSsdtCmn600LibDestructor (
703 IN EFI_HANDLE ImageHandle,
704 IN EFI_SYSTEM_TABLE *SystemTable
705 )
706 {
707 EFI_STATUS Status;
708
709 Status = DeregisterAcpiTableGenerator (&SsdtCmn600Generator);
710 DEBUG ((
711 DEBUG_INFO,
712 "SSDT-CMN-600: Deregister Generator. Status = %r\n",
713 Status
714 ));
715 ASSERT_EFI_ERROR (Status);
716 return Status;
717 }