]> git.proxmox.com Git - mirror_edk2.git/blame - DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c
DynamicTablesPkg: Apply uncrustify changes
[mirror_edk2.git] / DynamicTablesPkg / Library / Acpi / Arm / AcpiSsdtCpuTopologyLibArm / SsdtCpuTopologyGenerator.c
CommitLineData
769e6399
PG
1/** @file\r
2 SSDT Cpu Topology Table Generator.\r
3\r
4 Copyright (c) 2021, Arm Limited. All rights reserved.<BR>\r
5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7 @par Reference(s):\r
8 - ACPI 6.3 Specification - January 2019 - s8.4 Declaring Processors\r
9**/\r
10\r
11#include <Library/AcpiLib.h>\r
12#include <Library/BaseLib.h>\r
13#include <Library/BaseMemoryLib.h>\r
14#include <Library/DebugLib.h>\r
15#include <Library/MemoryAllocationLib.h>\r
16#include <Protocol/AcpiTable.h>\r
17\r
18// Module specific include files.\r
19#include <AcpiTableGenerator.h>\r
20#include <ConfigurationManagerObject.h>\r
21#include <ConfigurationManagerHelper.h>\r
22#include <Library/AcpiHelperLib.h>\r
23#include <Library/TableHelperLib.h>\r
24#include <Library/AmlLib/AmlLib.h>\r
25#include <Protocol/ConfigurationManagerProtocol.h>\r
26\r
27#include "SsdtCpuTopologyGenerator.h"\r
28\r
29/** ARM standard SSDT Cpu Topology Table Generator.\r
30\r
31Requirements:\r
32 The following Configuration Manager Object(s) are required by\r
33 this Generator:\r
34 - EArmObjGicCInfo\r
35 - EArmObjProcHierarchyInfo (OPTIONAL) along with\r
36 - EArmObjCmRef (OPTIONAL)\r
37 - EArmObjLpiInfo (OPTIONAL)\r
38*/\r
39\r
40/** This macro expands to a function that retrieves the GIC\r
41 CPU interface Information from the Configuration Manager.\r
42*/\r
43GET_OBJECT_LIST (\r
44 EObjNameSpaceArm,\r
45 EArmObjGicCInfo,\r
46 CM_ARM_GICC_INFO\r
47 );\r
48\r
49/**\r
50 This macro expands to a function that retrieves the Processor Hierarchy\r
51 information from the Configuration Manager.\r
52*/\r
53GET_OBJECT_LIST (\r
54 EObjNameSpaceArm,\r
55 EArmObjProcHierarchyInfo,\r
56 CM_ARM_PROC_HIERARCHY_INFO\r
57 );\r
58\r
59/**\r
60 This macro expands to a function that retrieves the cross-CM-object-\r
61 reference information from the Configuration Manager.\r
62*/\r
63GET_OBJECT_LIST (\r
64 EObjNameSpaceArm,\r
65 EArmObjCmRef,\r
66 CM_ARM_OBJ_REF\r
67 );\r
68\r
69/**\r
70 This macro expands to a function that retrieves the Lpi\r
71 information from the Configuration Manager.\r
72*/\r
73GET_OBJECT_LIST (\r
74 EObjNameSpaceArm,\r
75 EArmObjLpiInfo,\r
76 CM_ARM_LPI_INFO\r
77 );\r
78\r
79/** Initialize the TokenTable.\r
80\r
81 One entry should be allocated for each CM_ARM_PROC_HIERARCHY_INFO\r
82 structure of the platform. The TokenTable allows to have a mapping:\r
83 Index <-> CM_OBJECT_TOKEN (to CM_ARM_LPI_INFO structures).\r
84\r
85 There will always be less sets of Lpi states (CM_ARM_OBJ_REF)\r
86 than the number of cpus/clusters (CM_ARM_PROC_HIERARCHY_INFO).\r
87\r
88 @param [in] Generator The SSDT Cpu Topology generator.\r
89 @param [in] Count Number of entries to allocate in the TokenTable.\r
90\r
91 @retval EFI_SUCCESS Success.\r
92 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
93 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
94**/\r
95STATIC\r
96EFI_STATUS\r
97EFIAPI\r
98TokenTableInitialize (\r
731c67e1
MK
99 IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,\r
100 IN UINT32 Count\r
769e6399
PG
101 )\r
102{\r
731c67e1 103 CM_OBJECT_TOKEN *Table;\r
769e6399
PG
104\r
105 if ((Generator == NULL) ||\r
106 (Count == 0) ||\r
731c67e1
MK
107 (Count >= MAX_NODE_COUNT))\r
108 {\r
769e6399
PG
109 ASSERT (0);\r
110 return EFI_INVALID_PARAMETER;\r
111 }\r
112\r
113 Table = AllocateZeroPool (sizeof (CM_OBJECT_TOKEN) * Count);\r
114 if (Table == NULL) {\r
115 ASSERT (0);\r
116 return EFI_OUT_OF_RESOURCES;\r
117 }\r
118\r
119 Generator->TokenTable.Table = Table;\r
120\r
121 return EFI_SUCCESS;\r
122}\r
123\r
124/** Free the TokenTable.\r
125\r
126 @param [in] Generator The SSDT Cpu Topology generator.\r
127**/\r
128STATIC\r
129VOID\r
130EFIAPI\r
131TokenTableFree (\r
731c67e1 132 IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator\r
769e6399
PG
133 )\r
134{\r
135 ASSERT (Generator != NULL);\r
136 ASSERT (Generator->TokenTable.Table != NULL);\r
137\r
138 if (Generator->TokenTable.Table != NULL) {\r
139 FreePool (Generator->TokenTable.Table);\r
140 }\r
141}\r
142\r
143/** Add a new entry to the TokenTable and return its index.\r
144\r
145 If an entry with Token is already available in the table,\r
146 return its index without adding a new entry.\r
147\r
148 @param [in] Generator The SSDT Cpu Topology generator.\r
149 @param [in] Token New Token entry to add.\r
150\r
151 @retval The index of the token entry in the TokenTable.\r
152**/\r
153STATIC\r
154UINT32\r
155EFIAPI\r
156TokenTableAdd (\r
731c67e1
MK
157 IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,\r
158 IN CM_OBJECT_TOKEN Token\r
769e6399
PG
159 )\r
160{\r
731c67e1
MK
161 CM_OBJECT_TOKEN *Table;\r
162 UINT32 Index;\r
163 UINT32 LastIndex;\r
769e6399
PG
164\r
165 ASSERT (Generator != NULL);\r
166 ASSERT (Generator->TokenTable.Table != NULL);\r
167\r
731c67e1 168 Table = Generator->TokenTable.Table;\r
769e6399
PG
169 LastIndex = Generator->TokenTable.LastIndex;\r
170\r
171 // Search if there is already an entry with this Token.\r
172 for (Index = 0; Index < LastIndex; Index++) {\r
173 if (Table[Index] == Token) {\r
174 return Index;\r
175 }\r
176 }\r
177\r
178 ASSERT (LastIndex < MAX_NODE_COUNT);\r
179 ASSERT (LastIndex < Generator->ProcNodeCount);\r
180\r
181 // If no, create a new entry.\r
182 Table[LastIndex] = Token;\r
183\r
184 return Generator->TokenTable.LastIndex++;\r
185}\r
186\r
187/** Write a string 'Xxxx\0' in AslName (5 bytes long),\r
188 with 'X' being the leading char of the name, and\r
189 with 'xxx' being Value in hexadecimal.\r
190\r
191 As 'xxx' in hexadecimal represents a number on 12 bits,\r
192 we have Value < (1 << 12).\r
193\r
194 @param [in] LeadChar Leading char of the name.\r
195 @param [in] Value Hex value of the name.\r
196 Must be lower than (2 << 12).\r
197 @param [in, out] AslName Pointer to write the 'Xxxx' string to.\r
198 Must be at least 5 bytes long.\r
199\r
200 @retval EFI_SUCCESS Success.\r
201 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
202**/\r
203STATIC\r
204EFI_STATUS\r
205EFIAPI\r
206WriteAslName (\r
731c67e1
MK
207 IN CHAR8 LeadChar,\r
208 IN UINT32 Value,\r
209 IN OUT CHAR8 *AslName\r
769e6399
PG
210 )\r
211{\r
731c67e1 212 UINT8 Index;\r
769e6399
PG
213\r
214 if ((Value >= MAX_NODE_COUNT) ||\r
731c67e1
MK
215 (AslName == NULL))\r
216 {\r
769e6399
PG
217 ASSERT (0);\r
218 return EFI_INVALID_PARAMETER;\r
219 }\r
220\r
731c67e1 221 AslName[0] = LeadChar;\r
769e6399
PG
222 AslName[AML_NAME_SEG_SIZE] = '\0';\r
223\r
224 for (Index = 0; Index < AML_NAME_SEG_SIZE - 1; Index++) {\r
225 AslName[AML_NAME_SEG_SIZE - Index - 1] =\r
226 AsciiFromHex (((Value >> (4 * Index)) & 0xF));\r
227 }\r
228\r
229 return EFI_SUCCESS;\r
230}\r
231\r
232/** Create and add an _LPI method to Cpu/Cluster Node.\r
233\r
234 For instance, transform an AML node from:\r
235 Device (C002)\r
236 {\r
237 Name (_UID, 2)\r
238 Name (_HID, "ACPI0007")\r
239 }\r
240\r
241 To:\r
242 Device (C002)\r
243 {\r
244 Name (_UID, 2)\r
245 Name (_HID, "ACPI0007")\r
246 Method (_LPI, 0, NotSerialized)\r
247 {\r
248 Return (\_SB.L003)\r
249 }\r
250 }\r
251\r
252 @param [in] Generator The SSDT Cpu Topology generator.\r
253 @param [in] ProcHierarchyNodeInfo CM_ARM_PROC_HIERARCHY_INFO describing\r
254 the Cpu.\r
255 @param [in] Node Node to which the _LPI method is\r
256 attached. Can represent a Cpu or a\r
257 Cluster.\r
258\r
259 @retval EFI_SUCCESS The function completed successfully.\r
260 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
261 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
262**/\r
263STATIC\r
264EFI_STATUS\r
265EFIAPI\r
266CreateAmlLpiMethod (\r
731c67e1
MK
267 IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,\r
268 IN CM_ARM_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo,\r
269 IN AML_OBJECT_NODE_HANDLE *Node\r
769e6399
PG
270 )\r
271{\r
731c67e1
MK
272 EFI_STATUS Status;\r
273 UINT32 TokenIndex;\r
274 CHAR8 AslName[SB_SCOPE_PREFIX_SIZE + AML_NAME_SEG_SIZE];\r
769e6399
PG
275\r
276 ASSERT (Generator != NULL);\r
277 ASSERT (ProcHierarchyNodeInfo != NULL);\r
278 ASSERT (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN);\r
279 ASSERT (Node != NULL);\r
280\r
281 TokenIndex = TokenTableAdd (Generator, ProcHierarchyNodeInfo->LpiToken);\r
282\r
283 CopyMem (AslName, SB_SCOPE_PREFIX, SB_SCOPE_PREFIX_SIZE);\r
284\r
285 Status = WriteAslName (\r
286 'L',\r
287 TokenIndex,\r
288 AslName + SB_SCOPE_PREFIX_SIZE - 1\r
289 );\r
290 if (EFI_ERROR (Status)) {\r
291 ASSERT (0);\r
292 return Status;\r
293 }\r
294\r
295 // ASL:\r
296 // Method (_LPI, 0) {\r
297 // Return ([AslName])\r
298 // }\r
299 Status = AmlCodeGenMethodRetNameString (\r
300 "_LPI",\r
301 AslName,\r
302 0,\r
303 FALSE,\r
304 0,\r
305 Node,\r
306 NULL\r
307 );\r
308 if (EFI_ERROR (Status)) {\r
309 ASSERT (0);\r
310 }\r
311\r
312 return Status;\r
313}\r
314\r
315/** Generate all the Lpi states under the '_SB' scope.\r
316\r
317 This function generates the following ASL code:\r
318 Scope (\_SB) {\r
319 Name (L000, Package() {\r
320 0, // Version\r
321 0, // Level Index\r
322 X, // Count\r
323 Package() {\r
324 [An Lpi state]\r
325 },\r
326 Package() {\r
327 [Another Lpi state]\r
328 },\r
329 } // Name L000\r
330\r
331 Name (L001, Package() {\r
332 ...\r
333 } // Name L001\r
334\r
335 ...\r
336 } // Scope /_SB\r
337\r
338 The Lpi states are fetched from the Configuration Manager.\r
339 The names of the Lpi states are generated from the TokenTable.\r
340\r
341 @param [in] Generator The SSDT Cpu Topology generator.\r
342 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
343 Protocol Interface.\r
344 @param [in] ScopeNode Scope node handle ('\_SB' scope).\r
345\r
346 @retval EFI_SUCCESS Success.\r
347 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
348 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
349**/\r
350STATIC\r
351EFI_STATUS\r
352EFIAPI\r
353GenerateLpiStates (\r
731c67e1
MK
354 IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,\r
355 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
769e6399
PG
356 IN AML_OBJECT_NODE_HANDLE ScopeNode\r
357 )\r
358{\r
731c67e1 359 EFI_STATUS Status;\r
769e6399 360\r
731c67e1
MK
361 UINT32 Index;\r
362 UINT32 LastIndex;\r
769e6399 363\r
731c67e1
MK
364 AML_OBJECT_NODE_HANDLE LpiNode;\r
365 CM_ARM_OBJ_REF *LpiRefInfo;\r
366 UINT32 LpiRefInfoCount;\r
367 UINT32 LpiRefIndex;\r
368 CM_ARM_LPI_INFO *LpiInfo;\r
369 CHAR8 AslName[AML_NAME_SEG_SIZE + 1];\r
769e6399
PG
370\r
371 ASSERT (Generator != NULL);\r
372 ASSERT (Generator->TokenTable.Table != NULL);\r
373 ASSERT (CfgMgrProtocol != NULL);\r
374 ASSERT (ScopeNode != NULL);\r
375\r
376 LastIndex = Generator->TokenTable.LastIndex;\r
377\r
378 // For each entry in the TokenTable, create a name in the AML namespace\r
379 // under SB_SCOPE, to store the Lpi states associated with the LpiToken.\r
380 for (Index = 0; Index < LastIndex; Index++) {\r
381 Status = WriteAslName ('L', Index, AslName);\r
382 if (EFI_ERROR (Status)) {\r
383 ASSERT (0);\r
384 return Status;\r
385 }\r
386\r
387 // We do not support the LevelId field for now, let it to 0.\r
388 Status = AmlCreateLpiNode (AslName, 1, 0, ScopeNode, &LpiNode);\r
389 if (EFI_ERROR (Status)) {\r
390 ASSERT (0);\r
391 return Status;\r
392 }\r
393\r
394 // Fetch the LPI objects referenced by the token.\r
395 Status = GetEArmObjCmRef (\r
396 CfgMgrProtocol,\r
397 Generator->TokenTable.Table[Index],\r
398 &LpiRefInfo,\r
399 &LpiRefInfoCount\r
400 );\r
401 if (EFI_ERROR (Status)) {\r
402 ASSERT (0);\r
403 return Status;\r
404 }\r
405\r
406 for (LpiRefIndex = 0; LpiRefIndex < LpiRefInfoCount; LpiRefIndex++) {\r
407 // For each CM_ARM_LPI_INFO referenced by the token, add an Lpi state.\r
408 Status = GetEArmObjLpiInfo (\r
409 CfgMgrProtocol,\r
410 LpiRefInfo[LpiRefIndex].ReferenceToken,\r
411 &LpiInfo,\r
412 NULL\r
413 );\r
414 if (EFI_ERROR (Status)) {\r
415 ASSERT (0);\r
416 return Status;\r
417 }\r
418\r
419 Status = AmlAddLpiState (\r
420 LpiInfo->MinResidency,\r
421 LpiInfo->WorstCaseWakeLatency,\r
422 LpiInfo->Flags,\r
423 LpiInfo->ArchFlags,\r
424 LpiInfo->ResCntFreq,\r
425 LpiInfo->EnableParentState,\r
426 LpiInfo->IsInteger ?\r
731c67e1
MK
427 NULL :\r
428 &LpiInfo->RegisterEntryMethod,\r
769e6399 429 LpiInfo->IsInteger ?\r
731c67e1
MK
430 LpiInfo->IntegerEntryMethod :\r
431 0,\r
769e6399
PG
432 &LpiInfo->ResidencyCounterRegister,\r
433 &LpiInfo->UsageCounterRegister,\r
434 LpiInfo->StateName,\r
435 LpiNode\r
436 );\r
437 if (EFI_ERROR (Status)) {\r
438 ASSERT (0);\r
439 return Status;\r
440 }\r
441 } // for LpiRefIndex\r
442 } // for Index\r
443\r
444 return EFI_SUCCESS;\r
445}\r
446\r
447/** Create a Cpu in the AML namespace.\r
448\r
449 This generates the following ASL code:\r
450 Device (C002)\r
451 {\r
452 Name (_UID, 2)\r
453 Name (_HID, "ACPI0007")\r
454 }\r
455\r
456 @param [in] Generator The SSDT Cpu Topology generator.\r
457 @param [in] ParentNode Parent node to attach the Cpu node to.\r
458 @param [in] GicCInfo CM_ARM_GICC_INFO object used to create the node.\r
459 @param [in] CpuIndex Index used to generate the node name.\r
460 @param [out] CpuNodePtr If not NULL, return the created Cpu node.\r
461\r
462 @retval EFI_SUCCESS Success.\r
463 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
464 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
465**/\r
466STATIC\r
467EFI_STATUS\r
468EFIAPI\r
469CreateAmlCpu (\r
731c67e1
MK
470 IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,\r
471 IN AML_NODE_HANDLE ParentNode,\r
472 IN CM_ARM_GICC_INFO *GicCInfo,\r
473 IN UINT32 CpuIndex,\r
474 OUT AML_OBJECT_NODE_HANDLE *CpuNodePtr OPTIONAL\r
769e6399
PG
475 )\r
476{\r
731c67e1
MK
477 EFI_STATUS Status;\r
478 AML_OBJECT_NODE_HANDLE CpuNode;\r
479 CHAR8 AslName[AML_NAME_SEG_SIZE + 1];\r
769e6399
PG
480\r
481 ASSERT (Generator != NULL);\r
482 ASSERT (ParentNode != NULL);\r
483 ASSERT (GicCInfo != NULL);\r
484\r
485 Status = WriteAslName ('C', CpuIndex, AslName);\r
486 if (EFI_ERROR (Status)) {\r
487 ASSERT (0);\r
488 return Status;\r
489 }\r
490\r
491 Status = AmlCodeGenDevice (AslName, ParentNode, &CpuNode);\r
492 if (EFI_ERROR (Status)) {\r
493 ASSERT (0);\r
494 return Status;\r
495 }\r
496\r
497 Status = AmlCodeGenNameInteger (\r
498 "_UID",\r
499 GicCInfo->AcpiProcessorUid,\r
500 CpuNode,\r
501 NULL\r
502 );\r
503 if (EFI_ERROR (Status)) {\r
504 ASSERT (0);\r
505 return Status;\r
506 }\r
507\r
508 Status = AmlCodeGenNameString (\r
509 "_HID",\r
510 ACPI_HID_PROCESSOR_DEVICE,\r
511 CpuNode,\r
512 NULL\r
513 );\r
514 if (EFI_ERROR (Status)) {\r
515 ASSERT (0);\r
516 return Status;\r
517 }\r
518\r
519 // If requested, return the handle to the CpuNode.\r
520 if (CpuNodePtr != NULL) {\r
521 *CpuNodePtr = CpuNode;\r
522 }\r
523\r
524 return Status;\r
525}\r
526\r
527/** Create a Cpu in the AML namespace from a CM_ARM_PROC_HIERARCHY_INFO\r
528 CM object.\r
529\r
530 @param [in] Generator The SSDT Cpu Topology generator.\r
531 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
532 Protocol Interface.\r
533 @param [in] ParentNode Parent node to attach the Cpu node to.\r
534 @param [in] CpuIndex Index used to generate the node name.\r
535 @param [in] ProcHierarchyNodeInfo CM_ARM_PROC_HIERARCHY_INFO describing\r
536 the Cpu.\r
537\r
538 @retval EFI_SUCCESS Success.\r
539 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
540 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
541**/\r
542STATIC\r
543EFI_STATUS\r
544EFIAPI\r
545CreateAmlCpuFromProcHierarchy (\r
731c67e1
MK
546 IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,\r
547 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
769e6399
PG
548 IN AML_NODE_HANDLE ParentNode,\r
549 IN UINT32 CpuIndex,\r
731c67e1 550 IN CM_ARM_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo\r
769e6399
PG
551 )\r
552{\r
731c67e1
MK
553 EFI_STATUS Status;\r
554 CM_ARM_GICC_INFO *GicCInfo;\r
555 AML_OBJECT_NODE_HANDLE CpuNode;\r
769e6399
PG
556\r
557 ASSERT (Generator != NULL);\r
558 ASSERT (CfgMgrProtocol != NULL);\r
559 ASSERT (ParentNode != NULL);\r
560 ASSERT (ProcHierarchyNodeInfo != NULL);\r
561 ASSERT (ProcHierarchyNodeInfo->GicCToken != CM_NULL_TOKEN);\r
562\r
563 Status = GetEArmObjGicCInfo (\r
564 CfgMgrProtocol,\r
565 ProcHierarchyNodeInfo->GicCToken,\r
566 &GicCInfo,\r
567 NULL\r
568 );\r
569 if (EFI_ERROR (Status)) {\r
570 ASSERT (0);\r
571 return Status;\r
572 }\r
573\r
574 Status = CreateAmlCpu (Generator, ParentNode, GicCInfo, CpuIndex, &CpuNode);\r
575 if (EFI_ERROR (Status)) {\r
576 ASSERT (0);\r
577 return Status;\r
578 }\r
579\r
580 // If a set of Lpi states is associated with the\r
581 // CM_ARM_PROC_HIERARCHY_INFO, create an _LPI method returning them.\r
582 if (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN) {\r
583 Status = CreateAmlLpiMethod (Generator, ProcHierarchyNodeInfo, CpuNode);\r
584 ASSERT_EFI_ERROR (Status);\r
585 }\r
586\r
587 return Status;\r
588}\r
589\r
590/** Create a Cluster in the AML namespace.\r
591\r
592 Any CM_ARM_PROC_HIERARCHY_INFO object with the following flags is\r
593 assumed to be a cluster:\r
594 - EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL\r
595 - EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID\r
596 - EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF\r
597\r
598 This generates the following ASL code:\r
599 Device (C002)\r
600 {\r
601 Name (_UID, 2)\r
602 Name (_HID, "ACPI0010")\r
603 }\r
604\r
605 @param [in] Generator The SSDT Cpu Topology generator.\r
606 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
607 Protocol Interface.\r
608 @param [in] ParentNode Parent node to attach the Cluster\r
609 node to.\r
610 @param [in] ProcHierarchyNodeInfo CM_ARM_PROC_HIERARCHY_INFO object used\r
611 to create the node.\r
612 @param [in] ClusterIndex Index used to generate the node name.\r
613 @param [out] ClusterNodePtr If success, contains the created Cluster\r
614 node.\r
615\r
616 @retval EFI_SUCCESS Success.\r
617 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
618 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
619**/\r
620STATIC\r
621EFI_STATUS\r
622EFIAPI\r
623CreateAmlCluster (\r
731c67e1
MK
624 IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,\r
625 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
769e6399 626 IN AML_NODE_HANDLE ParentNode,\r
731c67e1 627 IN CM_ARM_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo,\r
769e6399 628 IN UINT32 ClusterIndex,\r
731c67e1 629 OUT AML_OBJECT_NODE_HANDLE *ClusterNodePtr\r
769e6399
PG
630 )\r
631{\r
731c67e1
MK
632 EFI_STATUS Status;\r
633 AML_OBJECT_NODE_HANDLE ClusterNode;\r
634 CHAR8 AslNameCluster[AML_NAME_SEG_SIZE + 1];\r
769e6399
PG
635\r
636 ASSERT (Generator != NULL);\r
637 ASSERT (CfgMgrProtocol != NULL);\r
638 ASSERT (ParentNode != NULL);\r
639 ASSERT (ProcHierarchyNodeInfo != NULL);\r
640 ASSERT (ClusterNodePtr != NULL);\r
641\r
642 Status = WriteAslName ('C', ClusterIndex, AslNameCluster);\r
643 if (EFI_ERROR (Status)) {\r
644 ASSERT (0);\r
645 return Status;\r
646 }\r
647\r
648 Status = AmlCodeGenDevice (AslNameCluster, ParentNode, &ClusterNode);\r
649 if (EFI_ERROR (Status)) {\r
650 ASSERT (0);\r
651 return Status;\r
652 }\r
653\r
654 // Use the ClusterIndex for the _UID value as there is no AcpiProcessorUid\r
655 // and EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID is set for non-Cpus.\r
656 Status = AmlCodeGenNameInteger (\r
657 "_UID",\r
658 ClusterIndex,\r
659 ClusterNode,\r
660 NULL\r
661 );\r
662 if (EFI_ERROR (Status)) {\r
663 ASSERT (0);\r
664 return Status;\r
665 }\r
666\r
667 Status = AmlCodeGenNameString (\r
668 "_HID",\r
669 ACPI_HID_PROCESSOR_CONTAINER_DEVICE,\r
670 ClusterNode,\r
671 NULL\r
672 );\r
673 if (EFI_ERROR (Status)) {\r
674 ASSERT (0);\r
675 return Status;\r
676 }\r
677\r
678 // If a set of Lpi states are associated with the\r
679 // CM_ARM_PROC_HIERARCHY_INFO, create an _LPI method returning them.\r
680 if (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN) {\r
681 Status = CreateAmlLpiMethod (\r
682 Generator,\r
683 ProcHierarchyNodeInfo,\r
684 ClusterNode\r
685 );\r
686 if (EFI_ERROR (Status)) {\r
687 ASSERT (0);\r
688 return Status;\r
689 }\r
690 }\r
691\r
692 *ClusterNodePtr = ClusterNode;\r
693\r
694 return Status;\r
695}\r
696\r
697/** Create an AML representation of the Cpu topology.\r
698\r
699 A cluster is by extension any non-leave device in the cpu topology.\r
700\r
701 @param [in] Generator The SSDT Cpu Topology generator.\r
702 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
703 Protocol Interface.\r
704 @param [in] NodeToken Token of the CM_ARM_PROC_HIERARCHY_INFO\r
705 currently handled.\r
706 Cannot be CM_NULL_TOKEN.\r
707 @param [in] ParentNode Parent node to attach the created\r
708 node to.\r
709\r
710 @retval EFI_SUCCESS Success.\r
711 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
712 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
713**/\r
714STATIC\r
715EFI_STATUS\r
716EFIAPI\r
717CreateAmlCpuTopologyTree (\r
731c67e1
MK
718 IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,\r
719 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
769e6399
PG
720 IN CM_OBJECT_TOKEN NodeToken,\r
721 IN AML_NODE_HANDLE ParentNode\r
722 )\r
723{\r
724 EFI_STATUS Status;\r
725 UINT32 Index;\r
726 UINT32 CpuIndex;\r
727 UINT32 ClusterIndex;\r
728 AML_OBJECT_NODE_HANDLE ClusterNode;\r
729\r
730 ASSERT (Generator != NULL);\r
731 ASSERT (Generator->ProcNodeList != NULL);\r
732 ASSERT (Generator->ProcNodeCount != 0);\r
733 ASSERT (CfgMgrProtocol != NULL);\r
734 ASSERT (NodeToken != CM_NULL_TOKEN);\r
735 ASSERT (ParentNode != NULL);\r
736\r
731c67e1 737 CpuIndex = 0;\r
769e6399
PG
738 ClusterIndex = 0;\r
739\r
740 for (Index = 0; Index < Generator->ProcNodeCount; Index++) {\r
741 // Find the children of the CM_ARM_PROC_HIERARCHY_INFO\r
742 // currently being handled (i.e. ParentToken == NodeToken).\r
743 if (Generator->ProcNodeList[Index].ParentToken == NodeToken) {\r
769e6399
PG
744 // Only Cpus (leaf nodes in this tree) have a GicCToken.\r
745 // Create a Cpu node.\r
746 if (Generator->ProcNodeList[Index].GicCToken != CM_NULL_TOKEN) {\r
747 if ((Generator->ProcNodeList[Index].Flags & PPTT_PROCESSOR_MASK) !=\r
731c67e1
MK
748 PPTT_CPU_PROCESSOR_MASK)\r
749 {\r
769e6399
PG
750 DEBUG ((\r
751 DEBUG_ERROR,\r
752 "ERROR: SSDT-CPU-TOPOLOGY: Invalid flags for cpu: 0x%x.\n",\r
753 Generator->ProcNodeList[Index].Flags\r
754 ));\r
755 ASSERT (0);\r
756 return EFI_INVALID_PARAMETER;\r
757 }\r
758\r
759 Status = CreateAmlCpuFromProcHierarchy (\r
760 Generator,\r
761 CfgMgrProtocol,\r
762 ParentNode,\r
763 CpuIndex,\r
764 &Generator->ProcNodeList[Index]\r
765 );\r
766 if (EFI_ERROR (Status)) {\r
767 ASSERT (0);\r
768 return Status;\r
769 }\r
770\r
771 CpuIndex++;\r
769e6399
PG
772 } else {\r
773 // If this is not a Cpu, then this is a cluster.\r
774\r
775 // Acpi processor Id for clusters is not handled.\r
776 if ((Generator->ProcNodeList[Index].Flags & PPTT_PROCESSOR_MASK) !=\r
731c67e1
MK
777 PPTT_CLUSTER_PROCESSOR_MASK)\r
778 {\r
769e6399
PG
779 DEBUG ((\r
780 DEBUG_ERROR,\r
781 "ERROR: SSDT-CPU-TOPOLOGY: Invalid flags for cluster: 0x%x.\n",\r
782 Generator->ProcNodeList[Index].Flags\r
783 ));\r
784 ASSERT (0);\r
785 return EFI_INVALID_PARAMETER;\r
786 }\r
787\r
788 Status = CreateAmlCluster (\r
789 Generator,\r
790 CfgMgrProtocol,\r
791 ParentNode,\r
792 &Generator->ProcNodeList[Index],\r
793 ClusterIndex,\r
794 &ClusterNode\r
795 );\r
796 if (EFI_ERROR (Status)) {\r
797 ASSERT (0);\r
798 return Status;\r
799 }\r
800\r
801 // Nodes must have a unique name in the ASL namespace.\r
802 // Reset the Cpu index whenever we create a new Cluster.\r
803 ClusterIndex++;\r
804 CpuIndex = 0;\r
805\r
806 // Recursively continue creating an AML tree.\r
807 Status = CreateAmlCpuTopologyTree (\r
808 Generator,\r
809 CfgMgrProtocol,\r
810 Generator->ProcNodeList[Index].Token,\r
811 ClusterNode\r
812 );\r
813 if (EFI_ERROR (Status)) {\r
814 ASSERT (0);\r
815 return Status;\r
816 }\r
817 }\r
818 } // if ParentToken == NodeToken\r
819 } // for\r
820\r
821 return EFI_SUCCESS;\r
822}\r
823\r
824/** Create the processor hierarchy AML tree from CM_ARM_PROC_HIERARCHY_INFO\r
825 CM objects.\r
826\r
827 @param [in] Generator The SSDT Cpu Topology generator.\r
828 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
829 Protocol Interface.\r
830 @param [in] ScopeNode Scope node handle ('\_SB' scope).\r
831\r
832 @retval EFI_SUCCESS Success.\r
833 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
834 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
835**/\r
836STATIC\r
837EFI_STATUS\r
838EFIAPI\r
839CreateTopologyFromProcHierarchy (\r
731c67e1
MK
840 IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,\r
841 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
769e6399
PG
842 IN AML_OBJECT_NODE_HANDLE ScopeNode\r
843 )\r
844{\r
845 EFI_STATUS Status;\r
846 UINT32 Index;\r
847 UINT32 TopLevelProcNodeIndex;\r
848\r
849 ASSERT (Generator != NULL);\r
850 ASSERT (Generator->ProcNodeCount != 0);\r
851 ASSERT (Generator->ProcNodeList != NULL);\r
852 ASSERT (CfgMgrProtocol != NULL);\r
853 ASSERT (ScopeNode != NULL);\r
854\r
855 TopLevelProcNodeIndex = MAX_UINT32;\r
856\r
857 Status = TokenTableInitialize (Generator, Generator->ProcNodeCount);\r
858 if (EFI_ERROR (Status)) {\r
859 ASSERT (0);\r
860 return Status;\r
861 }\r
862\r
863 // It is assumed that there is one unique CM_ARM_PROC_HIERARCHY_INFO\r
864 // structure with no ParentToken and the EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL\r
865 // flag set. All other CM_ARM_PROC_HIERARCHY_INFO are non-physical and\r
866 // have a ParentToken.\r
867 for (Index = 0; Index < Generator->ProcNodeCount; Index++) {\r
868 if ((Generator->ProcNodeList[Index].ParentToken == CM_NULL_TOKEN) &&\r
869 (Generator->ProcNodeList[Index].Flags &\r
731c67e1
MK
870 EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL))\r
871 {\r
769e6399
PG
872 if (TopLevelProcNodeIndex != MAX_UINT32) {\r
873 DEBUG ((\r
874 DEBUG_ERROR,\r
875 "ERROR: SSDT-CPU-TOPOLOGY: Top level CM_ARM_PROC_HIERARCHY_INFO "\r
876 "must be unique\n"\r
877 ));\r
878 ASSERT (0);\r
879 goto exit_handler;\r
880 }\r
731c67e1 881\r
769e6399
PG
882 TopLevelProcNodeIndex = Index;\r
883 }\r
884 } // for\r
885\r
886 Status = CreateAmlCpuTopologyTree (\r
887 Generator,\r
888 CfgMgrProtocol,\r
889 Generator->ProcNodeList[TopLevelProcNodeIndex].Token,\r
890 ScopeNode\r
891 );\r
892 if (EFI_ERROR (Status)) {\r
893 ASSERT (0);\r
894 goto exit_handler;\r
895 }\r
896\r
897 Status = GenerateLpiStates (Generator, CfgMgrProtocol, ScopeNode);\r
898 if (EFI_ERROR (Status)) {\r
899 ASSERT (0);\r
900 goto exit_handler;\r
901 }\r
902\r
903exit_handler:\r
904 TokenTableFree (Generator);\r
905 return Status;\r
906}\r
907\r
908/** Create the processor hierarchy AML tree from CM_ARM_GICC_INFO\r
909 CM objects.\r
910\r
911 A cluster is by extension any non-leave device in the cpu topology.\r
912\r
913 @param [in] Generator The SSDT Cpu Topology generator.\r
914 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
915 Protocol Interface.\r
916 @param [in] ScopeNode Scope node handle ('\_SB' scope).\r
917\r
918 @retval EFI_SUCCESS Success.\r
919 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
920 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
921**/\r
922STATIC\r
923EFI_STATUS\r
924EFIAPI\r
925CreateTopologyFromGicC (\r
731c67e1
MK
926 IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,\r
927 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
769e6399
PG
928 IN AML_OBJECT_NODE_HANDLE ScopeNode\r
929 )\r
930{\r
731c67e1
MK
931 EFI_STATUS Status;\r
932 CM_ARM_GICC_INFO *GicCInfo;\r
933 UINT32 GicCInfoCount;\r
934 UINT32 Index;\r
769e6399
PG
935\r
936 ASSERT (Generator != NULL);\r
937 ASSERT (CfgMgrProtocol != NULL);\r
938 ASSERT (ScopeNode != NULL);\r
939\r
940 Status = GetEArmObjGicCInfo (\r
941 CfgMgrProtocol,\r
942 CM_NULL_TOKEN,\r
943 &GicCInfo,\r
944 &GicCInfoCount\r
945 );\r
946 if (EFI_ERROR (Status)) {\r
947 ASSERT (0);\r
948 return Status;\r
949 }\r
950\r
951 // For each CM_ARM_GICC_INFO object, create an AML node.\r
952 for (Index = 0; Index < GicCInfoCount; Index++) {\r
953 Status = CreateAmlCpu (\r
954 Generator,\r
955 ScopeNode,\r
956 &GicCInfo[Index],\r
957 Index,\r
958 NULL\r
959 );\r
960 if (EFI_ERROR (Status)) {\r
961 ASSERT (0);\r
962 break;\r
963 }\r
964 } // for\r
965\r
966 return Status;\r
967}\r
968\r
969/** Construct the SSDT Cpu Topology ACPI table.\r
970\r
971 This function invokes the Configuration Manager protocol interface\r
972 to get the required hardware information for generating the ACPI\r
973 table.\r
974\r
975 If this function allocates any resources then they must be freed\r
976 in the FreeXXXXTableResources function.\r
977\r
978 @param [in] This Pointer to the table generator.\r
979 @param [in] AcpiTableInfo Pointer to the ACPI Table Info.\r
980 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
981 Protocol Interface.\r
982 @param [out] Table Pointer to the constructed ACPI Table.\r
983\r
984 @retval EFI_SUCCESS Table generated successfully.\r
985 @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
986 @retval EFI_NOT_FOUND The required object was not found.\r
987 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration\r
988 Manager is less than the Object size for the\r
989 requested object.\r
990**/\r
991STATIC\r
992EFI_STATUS\r
993EFIAPI\r
994BuildSsdtCpuTopologyTable (\r
731c67e1
MK
995 IN CONST ACPI_TABLE_GENERATOR *CONST This,\r
996 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,\r
997 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
998 OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table\r
769e6399
PG
999 )\r
1000{\r
731c67e1
MK
1001 EFI_STATUS Status;\r
1002 AML_ROOT_NODE_HANDLE RootNode;\r
1003 AML_OBJECT_NODE_HANDLE ScopeNode;\r
1004 CM_ARM_PROC_HIERARCHY_INFO *ProcHierarchyNodeList;\r
1005 UINT32 ProcHierarchyNodeCount;\r
1006 ACPI_CPU_TOPOLOGY_GENERATOR *Generator;\r
769e6399
PG
1007\r
1008 ASSERT (This != NULL);\r
1009 ASSERT (AcpiTableInfo != NULL);\r
1010 ASSERT (CfgMgrProtocol != NULL);\r
1011 ASSERT (Table != NULL);\r
1012 ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);\r
1013 ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);\r
1014\r
731c67e1 1015 Generator = (ACPI_CPU_TOPOLOGY_GENERATOR *)This;\r
769e6399
PG
1016\r
1017 Status = AddSsdtAcpiHeader (\r
1018 CfgMgrProtocol,\r
1019 This,\r
1020 AcpiTableInfo,\r
1021 &RootNode\r
1022 );\r
1023 if (EFI_ERROR (Status)) {\r
1024 return Status;\r
1025 }\r
1026\r
1027 Status = AmlCodeGenScope (SB_SCOPE, RootNode, &ScopeNode);\r
1028 if (EFI_ERROR (Status)) {\r
1029 goto exit_handler;\r
1030 }\r
1031\r
1032 // Get the processor hierarchy info and update the processor topology\r
1033 // structure count with Processor Hierarchy Nodes (Type 0)\r
1034 Status = GetEArmObjProcHierarchyInfo (\r
1035 CfgMgrProtocol,\r
1036 CM_NULL_TOKEN,\r
1037 &ProcHierarchyNodeList,\r
1038 &ProcHierarchyNodeCount\r
1039 );\r
1040 if (EFI_ERROR (Status) &&\r
731c67e1
MK
1041 (Status != EFI_NOT_FOUND))\r
1042 {\r
769e6399
PG
1043 goto exit_handler;\r
1044 }\r
1045\r
1046 if (Status == EFI_NOT_FOUND) {\r
1047 // If hierarchy information is not found generate a flat topology\r
1048 // using CM_ARM_GICC_INFO objects.\r
1049 Status = CreateTopologyFromGicC (\r
1050 Generator,\r
1051 CfgMgrProtocol,\r
1052 ScopeNode\r
1053 );\r
1054 if (EFI_ERROR (Status)) {\r
1055 goto exit_handler;\r
1056 }\r
1057 } else {\r
1058 // Generate the topology from CM_ARM_PROC_HIERARCHY_INFO objects.\r
731c67e1 1059 Generator->ProcNodeList = ProcHierarchyNodeList;\r
769e6399
PG
1060 Generator->ProcNodeCount = ProcHierarchyNodeCount;\r
1061\r
1062 Status = CreateTopologyFromProcHierarchy (\r
1063 Generator,\r
1064 CfgMgrProtocol,\r
1065 ScopeNode\r
1066 );\r
1067 if (EFI_ERROR (Status)) {\r
1068 goto exit_handler;\r
1069 }\r
1070 }\r
1071\r
1072 Status = AmlSerializeDefinitionBlock (\r
1073 RootNode,\r
1074 Table\r
1075 );\r
1076 if (EFI_ERROR (Status)) {\r
1077 DEBUG ((\r
1078 DEBUG_ERROR,\r
1079 "ERROR: SSDT-CPU-TOPOLOGY: Failed to Serialize SSDT Table Data."\r
1080 " Status = %r\n",\r
1081 Status\r
1082 ));\r
1083 goto exit_handler;\r
1084 }\r
1085\r
1086exit_handler:\r
1087 // Delete the RootNode and its attached children.\r
1088 return AmlDeleteTree (RootNode);\r
1089}\r
1090\r
1091/** Free any resources allocated for constructing the\r
1092 SSDT Cpu Topology ACPI table.\r
1093\r
1094 @param [in] This Pointer to the table generator.\r
1095 @param [in] AcpiTableInfo Pointer to the ACPI Table Info.\r
1096 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
1097 Protocol Interface.\r
1098 @param [in, out] Table Pointer to the ACPI Table.\r
1099\r
1100 @retval EFI_SUCCESS The resources were freed successfully.\r
1101 @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.\r
1102**/\r
1103STATIC\r
1104EFI_STATUS\r
1105FreeSsdtCpuTopologyTableResources (\r
731c67e1
MK
1106 IN CONST ACPI_TABLE_GENERATOR *CONST This,\r
1107 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,\r
1108 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
1109 IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table\r
769e6399
PG
1110 )\r
1111{\r
1112 ASSERT (This != NULL);\r
1113 ASSERT (AcpiTableInfo != NULL);\r
1114 ASSERT (CfgMgrProtocol != NULL);\r
1115 ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);\r
1116 ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);\r
1117\r
1118 if ((Table == NULL) || (*Table == NULL)) {\r
1119 DEBUG ((DEBUG_ERROR, "ERROR: SSDT-CPU-TOPOLOGY: Invalid Table Pointer\n"));\r
1120 ASSERT ((Table != NULL) && (*Table != NULL));\r
1121 return EFI_INVALID_PARAMETER;\r
1122 }\r
1123\r
1124 FreePool (*Table);\r
1125 *Table = NULL;\r
1126 return EFI_SUCCESS;\r
1127}\r
1128\r
1129/** This macro defines the SSDT Cpu Topology Table Generator revision.\r
1130*/\r
731c67e1 1131#define SSDT_CPU_TOPOLOGY_GENERATOR_REVISION CREATE_REVISION (1, 0)\r
769e6399
PG
1132\r
1133/** The interface for the SSDT Cpu Topology Table Generator.\r
1134*/\r
1135STATIC\r
731c67e1 1136ACPI_CPU_TOPOLOGY_GENERATOR SsdtCpuTopologyGenerator = {\r
769e6399
PG
1137 // ACPI table generator header\r
1138 {\r
1139 // Generator ID\r
1140 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtCpuTopology),\r
1141 // Generator Description\r
1142 L"ACPI.STD.SSDT.CPU.TOPOLOGY.GENERATOR",\r
1143 // ACPI Table Signature\r
1144 EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,\r
1145 // ACPI Table Revision - Unused\r
1146 0,\r
1147 // Minimum ACPI Table Revision - Unused\r
1148 0,\r
1149 // Creator ID\r
1150 TABLE_GENERATOR_CREATOR_ID_ARM,\r
1151 // Creator Revision\r
1152 SSDT_CPU_TOPOLOGY_GENERATOR_REVISION,\r
1153 // Build Table function\r
1154 BuildSsdtCpuTopologyTable,\r
1155 // Free Resource function\r
1156 FreeSsdtCpuTopologyTableResources,\r
1157 // Extended build function not needed\r
1158 NULL,\r
1159 // Extended build function not implemented by the generator.\r
1160 // Hence extended free resource function is not required.\r
1161 NULL\r
1162 },\r
1163\r
1164 // Private fields are defined from here.\r
1165\r
1166 // TokenTable\r
1167 {\r
731c67e1
MK
1168 // Table\r
1169 NULL,\r
1170 // LastIndex\r
1171 0\r
769e6399
PG
1172 },\r
1173 // ProcNodeList\r
1174 NULL,\r
1175 // ProcNodeCount\r
1176 0\r
1177};\r
1178\r
1179/** Register the Generator with the ACPI Table Factory.\r
1180\r
1181 @param [in] ImageHandle The handle to the image.\r
1182 @param [in] SystemTable Pointer to the System Table.\r
1183\r
1184 @retval EFI_SUCCESS The Generator is registered.\r
1185 @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
1186 @retval EFI_ALREADY_STARTED The Generator for the Table ID\r
1187 is already registered.\r
1188**/\r
1189EFI_STATUS\r
1190EFIAPI\r
1191AcpiSsdtCpuTopologyLibConstructor (\r
731c67e1
MK
1192 IN EFI_HANDLE ImageHandle,\r
1193 IN EFI_SYSTEM_TABLE *SystemTable\r
769e6399
PG
1194 )\r
1195{\r
1196 EFI_STATUS Status;\r
731c67e1 1197\r
769e6399
PG
1198 Status = RegisterAcpiTableGenerator (&SsdtCpuTopologyGenerator.Header);\r
1199 DEBUG ((\r
1200 DEBUG_INFO,\r
1201 "SSDT-CPU-TOPOLOGY: Register Generator. Status = %r\n",\r
1202 Status\r
1203 ));\r
1204 ASSERT_EFI_ERROR (Status);\r
1205\r
1206 return Status;\r
1207}\r
1208\r
1209/** Deregister the Generator from the ACPI Table Factory.\r
1210\r
1211 @param [in] ImageHandle The handle to the image.\r
1212 @param [in] SystemTable Pointer to the System Table.\r
1213\r
1214 @retval EFI_SUCCESS The Generator is deregistered.\r
1215 @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
1216 @retval EFI_NOT_FOUND The Generator is not registered.\r
1217**/\r
1218EFI_STATUS\r
1219EFIAPI\r
1220AcpiSsdtCpuTopologyLibDestructor (\r
731c67e1
MK
1221 IN EFI_HANDLE ImageHandle,\r
1222 IN EFI_SYSTEM_TABLE *SystemTable\r
769e6399
PG
1223 )\r
1224{\r
1225 EFI_STATUS Status;\r
731c67e1 1226\r
769e6399
PG
1227 Status = DeregisterAcpiTableGenerator (&SsdtCpuTopologyGenerator.Header);\r
1228 DEBUG ((\r
1229 DEBUG_INFO,\r
1230 "SSDT-CPU-TOPOLOGY: Deregister Generator. Status = %r\n",\r
1231 Status\r
1232 ));\r
1233 ASSERT_EFI_ERROR (Status);\r
1234 return Status;\r
1235}\r