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