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