ShellPkg/UefiShellAcpiViewCommandLib: Fix GCC build failure
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Srat / SratParser.c
1 /** @file\r
2   SRAT table parser\r
3 \r
4   Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.\r
5   This program and the accompanying materials\r
6   are licensed and made available under the terms and conditions of the BSD License\r
7   which accompanies this distribution.  The full text of the license may be found at\r
8   http://opensource.org/licenses/bsd-license.php\r
9 \r
10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12 \r
13   @par Reference(s):\r
14     - ACPI 6.2 Specification - Errata A, September 2017\r
15 **/\r
16 \r
17 #include <IndustryStandard/Acpi.h>\r
18 #include <Library/PrintLib.h>\r
19 #include <Library/UefiLib.h>\r
20 #include "AcpiParser.h"\r
21 #include "AcpiTableParser.h"\r
22 \r
23 // Local Variables\r
24 STATIC CONST UINT8* SratRAType;\r
25 STATIC CONST UINT8* SratRALength;\r
26 STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
27 \r
28 /**\r
29   This function validates the Reserved field in the SRAT table header.\r
30 \r
31   @param [in] Ptr     Pointer to the start of the field data.\r
32   @param [in] Context Pointer to context specific information e.g. this\r
33                       could be a pointer to the ACPI table header.\r
34 **/\r
35 STATIC\r
36 VOID\r
37 EFIAPI\r
38 ValidateSratReserved (\r
39   IN UINT8* Ptr,\r
40   IN VOID*  Context\r
41   );\r
42 \r
43 /**\r
44   This function traces the APIC Proximity Domain field.\r
45 \r
46   @param [in] Format  Format string for tracing the data.\r
47   @param [in] Ptr     Pointer to the start of the buffer.\r
48 **/\r
49 STATIC\r
50 VOID\r
51 EFIAPI\r
52 DumpSratApicProximity (\r
53   IN  CONST CHAR16*  Format,\r
54   IN  UINT8*         Ptr\r
55   );\r
56 \r
57 /**\r
58   An ACPI_PARSER array describing the SRAT Table.\r
59 **/\r
60 STATIC CONST ACPI_PARSER SratParser[] = {\r
61   PARSE_ACPI_HEADER (&AcpiHdrInfo),\r
62   {L"Reserved", 4, 36, L"0x%x", NULL, NULL, ValidateSratReserved, NULL},\r
63   {L"Reserved", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL}\r
64 };\r
65 \r
66 /**\r
67   An ACPI_PARSER array describing the Resource Allocation structure header.\r
68 **/\r
69 STATIC CONST ACPI_PARSER SratResourceAllocationParser[] = {\r
70   {L"Type", 1, 0, NULL, NULL, (VOID**)&SratRAType, NULL, NULL},\r
71   {L"Length", 1, 1, NULL, NULL, (VOID**)&SratRALength, NULL, NULL}\r
72 };\r
73 \r
74 /**\r
75   An ACPI_PARSER array describing the GICC Affinity structure.\r
76 **/\r
77 STATIC CONST ACPI_PARSER SratGicCAffinityParser[] = {\r
78   {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
79   {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},\r
80 \r
81   {L"Proximity Domain", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
82   {L"ACPI Processor UID", 4, 6, L"0x%x", NULL, NULL, NULL, NULL},\r
83   {L"Flags", 4, 10, L"0x%x", NULL, NULL, NULL, NULL},\r
84   {L"Clock Domain", 4, 14, L"0x%x", NULL, NULL, NULL, NULL}\r
85 };\r
86 \r
87 /**\r
88   An ACPI_PARSER array describing the GIC ITS Affinity structure.\r
89 **/\r
90 STATIC CONST ACPI_PARSER SratGicITSAffinityParser[] = {\r
91   {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
92   {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},\r
93 \r
94   {L"Proximity Domain", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
95   {L"Reserved", 2, 6, L"0x%x", NULL, NULL, NULL, NULL},\r
96   {L"ITS Id", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},\r
97 };\r
98 \r
99 /**\r
100   An ACPI_PARSER array describing the Memory Affinity structure.\r
101 **/\r
102 STATIC CONST ACPI_PARSER SratMemAffinityParser[] = {\r
103   {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
104   {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},\r
105 \r
106   {L"Proximity Domain", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
107   {L"Reserved", 2, 6, L"0x%x", NULL, NULL, NULL, NULL},\r
108   {L"Base Address Low", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},\r
109   {L"Base Address High", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},\r
110   {L"Length Low", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},\r
111   {L"Length High", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},\r
112   {L"Reserved", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},\r
113   {L"Flags", 4, 28, L"0x%x", NULL, NULL, NULL, NULL},\r
114   {L"Reserved", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL}\r
115 };\r
116 \r
117 /**\r
118   An ACPI_PARSER array describing the APIC/SAPIC Affinity structure.\r
119 **/\r
120 STATIC CONST ACPI_PARSER SratApciSapicAffinityParser[] = {\r
121   {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
122   {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},\r
123 \r
124   {L"Proximity Domain [7:0]", 1, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
125   {L"APIC ID", 1, 3, L"0x%x", NULL, NULL, NULL, NULL},\r
126   {L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},\r
127   {L"Local SAPIC EID", 1, 8, L"0x%x", NULL, NULL, NULL, NULL},\r
128   {L"Proximity Domain [31:8]", 3, 9, L"0x%x", DumpSratApicProximity,\r
129    NULL, NULL, NULL},\r
130   {L"Clock Domain", 4, 12, L"0x%x", NULL, NULL, NULL, NULL}\r
131 };\r
132 \r
133 /**\r
134   An ACPI_PARSER array describing the Processor Local x2APIC Affinity structure.\r
135 **/\r
136 STATIC CONST ACPI_PARSER SratX2ApciAffinityParser[] = {\r
137   {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
138   {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},\r
139 \r
140   {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
141   {L"Proximity Domain", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},\r
142   {L"X2APIC ID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},\r
143   {L"Flags", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},\r
144   {L"Clock Domain", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},\r
145   {L"Reserved", 4, 20, L"0x%x", NULL, NULL, NULL, NULL}\r
146 };\r
147 \r
148 /** This function validates the Reserved field in the SRAT table header.\r
149 \r
150   @param [in] Ptr     Pointer to the start of the field data.\r
151   @param [in] Context Pointer to context specific information e.g. this\r
152                       could be a pointer to the ACPI table header.\r
153 **/\r
154 STATIC\r
155 VOID\r
156 EFIAPI\r
157 ValidateSratReserved (\r
158   IN UINT8* Ptr,\r
159   IN VOID*  Context\r
160   )\r
161 {\r
162   if (*(UINT32*)Ptr != 1) {\r
163     IncrementErrorCount ();\r
164     Print (L"\nERROR: Reserved should be 1 for backward compatibility.\n");\r
165   }\r
166 }\r
167 \r
168 /**\r
169   This function traces the APIC Proximity Domain field.\r
170 \r
171   @param [in] Format  Format string for tracing the data.\r
172   @param [in] Ptr     Pointer to the start of the buffer.\r
173 **/\r
174 STATIC\r
175 VOID\r
176 EFIAPI\r
177 DumpSratApicProximity (\r
178  IN CONST CHAR16* Format,\r
179  IN UINT8*        Ptr\r
180  )\r
181 {\r
182   UINT32 ProximityDomain;\r
183 \r
184   ProximityDomain = Ptr[0] | (Ptr[1] << 8) | (Ptr[2] << 16);\r
185 \r
186   Print (Format, ProximityDomain);\r
187 }\r
188 \r
189 /**\r
190   This function parses the ACPI SRAT table.\r
191   When trace is enabled this function parses the SRAT table and\r
192   traces the ACPI table fields.\r
193 \r
194   This function parses the following Resource Allocation Structures:\r
195     - Processor Local APIC/SAPIC Affinity Structure\r
196     - Memory Affinity Structure\r
197     - Processor Local x2APIC Affinity Structure\r
198     - GICC Affinity Structure\r
199 \r
200   This function also performs validation of the ACPI table fields.\r
201 \r
202   @param [in] Trace              If TRUE, trace the ACPI fields.\r
203   @param [in] Ptr                Pointer to the start of the buffer.\r
204   @param [in] AcpiTableLength    Length of the ACPI table.\r
205   @param [in] AcpiTableRevision  Revision of the ACPI table.\r
206 **/\r
207 VOID\r
208 EFIAPI\r
209 ParseAcpiSrat (\r
210   IN BOOLEAN Trace,\r
211   IN UINT8*  Ptr,\r
212   IN UINT32  AcpiTableLength,\r
213   IN UINT8   AcpiTableRevision\r
214   )\r
215 {\r
216   UINT32 Offset;\r
217   UINT8* ResourcePtr;\r
218   UINT32 GicCAffinityIndex;\r
219   UINT32 GicITSAffinityIndex;\r
220   UINT32 MemoryAffinityIndex;\r
221   UINT32 ApicSapicAffinityIndex;\r
222   UINT32 X2ApicAffinityIndex;\r
223   CHAR8  Buffer[80];  // Used for AsciiName param of ParseAcpi\r
224 \r
225   GicCAffinityIndex = 0;\r
226   GicITSAffinityIndex = 0;\r
227   MemoryAffinityIndex = 0;\r
228   ApicSapicAffinityIndex = 0;\r
229   X2ApicAffinityIndex = 0;\r
230 \r
231   if (!Trace) {\r
232     return;\r
233   }\r
234 \r
235   Offset = ParseAcpi (\r
236              TRUE,\r
237              0,\r
238              "SRAT",\r
239              Ptr,\r
240              AcpiTableLength,\r
241              PARSER_PARAMS (SratParser)\r
242              );\r
243   ResourcePtr = Ptr + Offset;\r
244 \r
245   while (Offset < AcpiTableLength) {\r
246     ParseAcpi (\r
247       FALSE,\r
248       0,\r
249       NULL,\r
250       ResourcePtr,\r
251       2,  // The length is 1 byte at offset 1\r
252       PARSER_PARAMS (SratResourceAllocationParser)\r
253       );\r
254 \r
255     switch (*SratRAType) {\r
256       case EFI_ACPI_6_2_GICC_AFFINITY:\r
257         AsciiSPrint (\r
258           Buffer,\r
259           sizeof (Buffer),\r
260           "GICC Affinity Structure [%d]",\r
261           GicCAffinityIndex++\r
262           );\r
263         ParseAcpi (\r
264           TRUE,\r
265           2,\r
266           Buffer,\r
267           ResourcePtr,\r
268           *SratRALength,\r
269           PARSER_PARAMS (SratGicCAffinityParser)\r
270           );\r
271         break;\r
272 \r
273       case EFI_ACPI_6_2_GIC_ITS_AFFINITY:\r
274         AsciiSPrint (\r
275           Buffer,\r
276           sizeof (Buffer),\r
277           "GIC ITS Affinity Structure [%d]",\r
278           GicITSAffinityIndex++\r
279         );\r
280         ParseAcpi (\r
281           TRUE,\r
282           2,\r
283           Buffer,\r
284           ResourcePtr,\r
285           *SratRALength,\r
286           PARSER_PARAMS (SratGicITSAffinityParser)\r
287         );\r
288         break;\r
289 \r
290       case EFI_ACPI_6_2_MEMORY_AFFINITY:\r
291         AsciiSPrint (\r
292           Buffer,\r
293           sizeof (Buffer),\r
294           "Memory Affinity Structure [%d]",\r
295           MemoryAffinityIndex++\r
296           );\r
297         ParseAcpi (\r
298           TRUE,\r
299           2,\r
300           Buffer,\r
301           ResourcePtr,\r
302           *SratRALength,\r
303           PARSER_PARAMS (SratMemAffinityParser)\r
304           );\r
305         break;\r
306 \r
307       case EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY:\r
308         AsciiSPrint (\r
309           Buffer,\r
310           sizeof (Buffer),\r
311           "APIC/SAPIC Affinity Structure [%d]",\r
312           ApicSapicAffinityIndex++\r
313           );\r
314         ParseAcpi (\r
315           TRUE,\r
316           2,\r
317           Buffer,\r
318           ResourcePtr,\r
319           *SratRALength,\r
320           PARSER_PARAMS (SratApciSapicAffinityParser)\r
321           );\r
322         break;\r
323 \r
324       case EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY:\r
325         AsciiSPrint (\r
326           Buffer,\r
327           sizeof (Buffer),\r
328           "X2APIC Affinity Structure [%d]",\r
329           X2ApicAffinityIndex++\r
330           );\r
331         ParseAcpi (\r
332           TRUE,\r
333           2,\r
334           Buffer,\r
335           ResourcePtr,\r
336           *SratRALength,\r
337           PARSER_PARAMS (SratX2ApciAffinityParser)\r
338           );\r
339         break;\r
340 \r
341       default:\r
342         IncrementErrorCount ();\r
343         Print (L"ERROR: Unknown SRAT Affinity type = 0x%x\n", *SratRAType);\r
344         break;\r
345     }\r
346 \r
347     ResourcePtr += (*SratRALength);\r
348     Offset += (*SratRALength);\r
349   }\r
350 }\r