]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
ShellPkg/UefiShellAcpiViewCommandLib: Fix VS tool chain build failure
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Pptt / PpttParser.c
CommitLineData
d4d2fdf2
KK
1/** @file\r
2 PPTT table parser\r
3\r
4 Copyright (c) 2019, 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 <Library/PrintLib.h>\r
18#include <Library/UefiLib.h>\r
19#include "AcpiParser.h"\r
20\r
21// Local variables\r
22STATIC CONST UINT8* ProcessorTopologyStructureType;\r
23STATIC CONST UINT8* ProcessorTopologyStructureLength;\r
24STATIC CONST UINT32* NumberOfPrivateResources;\r
25STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
26\r
27/**\r
28 An ACPI_PARSER array describing the ACPI PPTT Table.\r
29**/\r
30STATIC CONST ACPI_PARSER PpttParser[] = {\r
31 PARSE_ACPI_HEADER (&AcpiHdrInfo)\r
32};\r
33\r
34/**\r
35 This function validates the Cache Type Structure (Type 1) Line size field.\r
36\r
37 @param [in] Ptr Pointer to the start of the field data.\r
38 @param [in] Context Pointer to context specific information e.g. this\r
39 could be a pointer to the ACPI table header.\r
40**/\r
41STATIC\r
42VOID\r
43EFIAPI\r
44ValidateCacheLineSize (\r
45 IN UINT8* Ptr,\r
46 IN VOID* Context\r
47 )\r
48{\r
49#if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)\r
50 // Reference: ARM Architecture Reference Manual ARMv8 (D.a)\r
51 // Section D12.2.25: CCSIDR_EL1, Current Cache Size ID Register\r
52 // LineSize, bits [2:0]\r
53 // (Log2(Number of bytes in cache line)) - 4.\r
54\r
55 UINT16 LineSize;\r
56 LineSize = *(UINT16*)Ptr;\r
57\r
58 if ((LineSize < 16) || (LineSize > 2048)) {\r
59 IncrementErrorCount ();\r
60 Print (\r
61 L"\nERROR: The cache line size must be between 16 and 2048 bytes"\r
62 L" on ARM Platforms."\r
63 );\r
64 return;\r
65 }\r
66\r
67 if ((LineSize & (LineSize - 1)) != 0) {\r
68 IncrementErrorCount ();\r
69 Print (L"\nERROR: The cache line size is not a power of 2.");\r
70 }\r
71#endif\r
72}\r
73\r
74/**\r
75 This function validates the Cache Type Structure (Type 1) Attributes field.\r
76\r
77 @param [in] Ptr Pointer to the start of the field data.\r
78 @param [in] Context Pointer to context specific information e.g. this\r
79 could be a pointer to the ACPI table header.\r
80**/\r
81STATIC\r
82VOID\r
83EFIAPI\r
84ValidateCacheAttributes (\r
85 IN UINT8* Ptr,\r
86 IN VOID* Context\r
87 )\r
88{\r
89#if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)\r
90 // Reference: Advanced Configuration and Power Interface (ACPI) Specification\r
91 // Version 6.2 Errata A, September 2017\r
92 // Table 5-153: Cache Type Structure\r
93\r
94 UINT8 Attributes;\r
95 Attributes = *(UINT8*)Ptr;\r
96\r
97 if ((Attributes & 0xE0) != 0) {\r
98 IncrementErrorCount ();\r
99 Print (\r
100 L"\nERROR: Attributes bits [7:5] are reserved and must be zero.",\r
101 Attributes\r
102 );\r
103 return;\r
104 }\r
105#endif\r
106}\r
107\r
108/**\r
109 An ACPI_PARSER array describing the processor topology structure header.\r
110**/\r
111STATIC CONST ACPI_PARSER ProcessorTopologyStructureHeaderParser[] = {\r
112 {L"Type", 1, 0, NULL, NULL, (VOID**)&ProcessorTopologyStructureType,\r
113 NULL, NULL},\r
114 {L"Length", 1, 1, NULL, NULL, (VOID**)&ProcessorTopologyStructureLength,\r
115 NULL, NULL},\r
116 {L"Reserved", 2, 2, NULL, NULL, NULL, NULL, NULL}\r
117};\r
118\r
119/**\r
120 An ACPI_PARSER array describing the Processor Hierarchy Node Structure - Type 0.\r
121**/\r
122STATIC CONST ACPI_PARSER ProcessorHierarchyNodeStructureParser[] = {\r
123 {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
124 {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},\r
125 {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
126\r
127 {L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},\r
128 {L"Parent", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},\r
129 {L"ACPI Processor ID", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},\r
130 {L"Number of private resources", 4, 16, L"%d", NULL,\r
131 (VOID**)&NumberOfPrivateResources, NULL, NULL}\r
132};\r
133\r
134/**\r
135 An ACPI_PARSER array describing the Cache Type Structure - Type 1.\r
136**/\r
137STATIC CONST ACPI_PARSER CacheTypeStructureParser[] = {\r
138 {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
139 {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},\r
140 {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
141\r
142 {L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},\r
143 {L"Next Level of Cache", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},\r
144 {L"Size", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},\r
145 {L"Number of sets", 4, 16, L"%d", NULL, NULL, NULL, NULL},\r
146 {L"Associativity", 1, 20, L"%d", NULL, NULL, NULL, NULL},\r
147 {L"Attributes", 1, 21, L"0x%x", NULL, NULL, ValidateCacheAttributes, NULL},\r
148 {L"Line size", 2, 22, L"%d", NULL, NULL, ValidateCacheLineSize, NULL}\r
149};\r
150\r
151/**\r
152 An ACPI_PARSER array describing the ID Type Structure - Type 2.\r
153**/\r
154STATIC CONST ACPI_PARSER IdStructureParser[] = {\r
155 {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
156 {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},\r
157 {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
158\r
159 {L"VENDOR_ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},\r
160 {L"LEVEL_1_ID", 8, 8, L"0x%x", NULL, NULL, NULL, NULL},\r
161 {L"LEVEL_2_ID", 8, 16, L"0x%x", NULL, NULL, NULL, NULL},\r
162 {L"MAJOR_REV", 2, 24, L"0x%x", NULL, NULL, NULL, NULL},\r
163 {L"MINOR_REV", 2, 26, L"0x%x", NULL, NULL, NULL, NULL},\r
164 {L"SPIN_REV", 2, 28, L"0x%x", NULL, NULL, NULL, NULL},\r
165};\r
166\r
167/**\r
168 This function parses the Processor Hierarchy Node Structure (Type 0).\r
169\r
170 @param [in] Ptr Pointer to the start of the Processor Hierarchy Node\r
171 Structure data.\r
172 @param [in] Length Length of the Processor Hierarchy Node Structure.\r
173**/\r
174STATIC\r
175VOID\r
176DumpProcessorHierarchyNodeStructure (\r
177 IN UINT8* Ptr,\r
178 IN UINT8 Length\r
179 )\r
180{\r
f34b38fa 181 UINT32 Offset;\r
d4d2fdf2
KK
182 UINT8* PrivateResourcePtr;\r
183 UINT32 Index;\r
184 CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH];\r
185\r
186 Offset = ParseAcpi (\r
187 TRUE,\r
188 2,\r
189 "Processor Hierarchy Node Structure",\r
190 Ptr,\r
191 Length,\r
192 PARSER_PARAMS (ProcessorHierarchyNodeStructureParser)\r
193 );\r
194\r
195 PrivateResourcePtr = Ptr + Offset;\r
196 Index = 0;\r
197 while (Index < *NumberOfPrivateResources) {\r
198 UnicodeSPrint (\r
199 Buffer,\r
200 sizeof (Buffer),\r
201 L"Private resources [%d]",\r
202 Index\r
203 );\r
204\r
205 PrintFieldName (4, Buffer);\r
206 Print (\r
207 L"0x%x\n",\r
208 *((UINT32*) PrivateResourcePtr)\r
209 );\r
210\r
211 PrivateResourcePtr += sizeof(UINT32);\r
212 Index++;\r
213 }\r
214}\r
215\r
216/**\r
217 This function parses the Cache Type Structure (Type 1).\r
218\r
219 @param [in] Ptr Pointer to the start of the Cache Type Structure data.\r
220 @param [in] Length Length of the Cache Type Structure.\r
221**/\r
222STATIC\r
223VOID\r
224DumpCacheTypeStructure (\r
225 IN UINT8* Ptr,\r
226 IN UINT8 Length\r
227 )\r
228{\r
229 ParseAcpi (\r
230 TRUE,\r
231 2,\r
232 "Cache Type Structure",\r
233 Ptr,\r
234 Length,\r
235 PARSER_PARAMS (CacheTypeStructureParser)\r
236 );\r
237}\r
238\r
239/**\r
240 This function parses the ID Structure (Type 2).\r
241\r
242 @param [in] Ptr Pointer to the start of the ID Structure data.\r
243 @param [in] Length Length of the ID Structure.\r
244**/\r
245STATIC\r
246VOID\r
247DumpIDStructure (\r
248 IN UINT8* Ptr,\r
249 IN UINT8 Length\r
250 )\r
251{\r
252 ParseAcpi (\r
253 TRUE,\r
254 2,\r
255 "ID Structure",\r
256 Ptr,\r
257 Length,\r
258 PARSER_PARAMS (IdStructureParser)\r
259 );\r
260}\r
261\r
262/**\r
263 This function parses the ACPI PPTT table.\r
264 When trace is enabled this function parses the PPTT table and\r
265 traces the ACPI table fields.\r
266\r
267 This function parses the following processor topology structures:\r
268 - Processor hierarchy node structure (Type 0)\r
269 - Cache Type Structure (Type 1)\r
270 - ID structure (Type 2)\r
271\r
272 This function also performs validation of the ACPI table fields.\r
273\r
274 @param [in] Trace If TRUE, trace the ACPI fields.\r
275 @param [in] Ptr Pointer to the start of the buffer.\r
276 @param [in] AcpiTableLength Length of the ACPI table.\r
277 @param [in] AcpiTableRevision Revision of the ACPI table.\r
278**/\r
279VOID\r
280EFIAPI\r
281ParseAcpiPptt (\r
282 IN BOOLEAN Trace,\r
283 IN UINT8* Ptr,\r
284 IN UINT32 AcpiTableLength,\r
285 IN UINT8 AcpiTableRevision\r
286 )\r
287{\r
288 UINT32 Offset;\r
289 UINT8* ProcessorTopologyStructurePtr;\r
290\r
291 if (!Trace) {\r
292 return;\r
293 }\r
294\r
295 Offset = ParseAcpi (\r
296 TRUE,\r
297 0,\r
298 "PPTT",\r
299 Ptr,\r
300 AcpiTableLength,\r
301 PARSER_PARAMS (PpttParser)\r
302 );\r
303 ProcessorTopologyStructurePtr = Ptr + Offset;\r
304\r
305 while (Offset < AcpiTableLength) {\r
306 // Parse Processor Hierarchy Node Structure to obtain Type and Length.\r
307 ParseAcpi (\r
308 FALSE,\r
309 0,\r
310 NULL,\r
311 ProcessorTopologyStructurePtr,\r
312 4, // Length of the processor topology structure header is 4 bytes\r
313 PARSER_PARAMS (ProcessorTopologyStructureHeaderParser)\r
314 );\r
315\r
316 if ((Offset + (*ProcessorTopologyStructureLength)) > AcpiTableLength) {\r
317 IncrementErrorCount ();\r
318 Print (\r
319 L"ERROR: Invalid processor topology structure length:"\r
320 L" Type = %d, Length = %d\n",\r
321 *ProcessorTopologyStructureType,\r
322 *ProcessorTopologyStructureLength\r
323 );\r
324 break;\r
325 }\r
326\r
327 PrintFieldName (2, L"* Structure Offset *");\r
328 Print (L"0x%x\n", Offset);\r
329\r
330 switch (*ProcessorTopologyStructureType) {\r
331 case EFI_ACPI_6_2_PPTT_TYPE_PROCESSOR:\r
332 DumpProcessorHierarchyNodeStructure (\r
333 ProcessorTopologyStructurePtr,\r
334 *ProcessorTopologyStructureLength\r
335 );\r
336 break;\r
337 case EFI_ACPI_6_2_PPTT_TYPE_CACHE:\r
338 DumpCacheTypeStructure (\r
339 ProcessorTopologyStructurePtr,\r
340 *ProcessorTopologyStructureLength\r
341 );\r
342 break;\r
343 case EFI_ACPI_6_2_PPTT_TYPE_ID:\r
344 DumpIDStructure (\r
345 ProcessorTopologyStructurePtr,\r
346 *ProcessorTopologyStructureLength\r
347 );\r
348 break;\r
349 default:\r
350 IncrementErrorCount ();\r
351 Print (\r
352 L"ERROR: Unknown processor topology structure:"\r
353 L" Type = %d, Length = %d\n",\r
354 *ProcessorTopologyStructureType,\r
355 *ProcessorTopologyStructureLength\r
356 );\r
357 }\r
358\r
359 ProcessorTopologyStructurePtr += *ProcessorTopologyStructureLength;\r
360 Offset += *ProcessorTopologyStructureLength;\r
361 } // while\r
362}\r