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