TianoCore EDK2 master
Loading...
Searching...
No Matches
HmatParser.c
Go to the documentation of this file.
1
17#include <Library/PrintLib.h>
18#include <Library/BaseLib.h>
19#include <Library/UefiLib.h>
20#include "AcpiParser.h"
21#include "AcpiView.h"
22
23// Maximum Memory Domain matrix print size.
24#define MAX_MEMORY_DOMAIN_TARGET_PRINT_MATRIX 10
25
26// Local variables
27STATIC CONST UINT16 *HmatStructureType;
28STATIC CONST UINT32 *HmatStructureLength;
29
30STATIC CONST UINT32 *NumberInitiatorProximityDomain;
31STATIC CONST UINT32 *NumberTargetProximityDomain;
34 SllbiFlags;
35
36STATIC CONST UINT8 *SllbiDataType;
37STATIC CONST UINT16 *NumberSMBIOSHandles;
38
40
44STATIC CONST CHAR16 *SllbiNames[] = {
45 L"Access %sLatency%s",
46 L"Read %sLatency%s",
47 L"Write %sLatency%s",
48 L"Access %sBandwidth%s",
49 L"Read %sBandwidth%s",
50 L"Write %sBandwidth%s"
51};
52
62VOID
63EFIAPI
65 IN UINT8 *Ptr,
66 IN UINT32 Length,
67 IN VOID *Context
68 )
69{
71 Attributes;
72
73 Attributes =
75
76 if (Attributes->TotalCacheLevels > 0x3) {
78 Print (
79 L"\nERROR: Attributes bits [3:0] have invalid value: 0x%x",
80 Attributes->TotalCacheLevels
81 );
82 }
83
84 if (Attributes->CacheLevel > 0x3) {
86 Print (
87 L"\nERROR: Attributes bits [7:4] have invalid value: 0x%x",
88 Attributes->CacheLevel
89 );
90 }
91
92 if (Attributes->CacheAssociativity > 0x2) {
94 Print (
95 L"\nERROR: Attributes bits [11:8] have invalid value: 0x%x",
96 Attributes->CacheAssociativity
97 );
98 }
99
100 if (Attributes->WritePolicy > 0x2) {
102 Print (
103 L"\nERROR: Attributes bits [15:12] have invalid value: 0x%x",
104 Attributes->WritePolicy
105 );
106 }
107}
108
116STATIC
117VOID
118EFIAPI
120 IN CONST CHAR16 *Format OPTIONAL,
121 IN UINT8 *Ptr,
122 IN UINT32 Length
123 )
124{
126 Attributes;
127
128 Attributes =
130
131 Print (L"\n");
132 PrintFieldName (4, L"Total Cache Levels");
133 Print (L"%d\n", Attributes->TotalCacheLevels);
134 PrintFieldName (4, L"Cache Level");
135 Print (L"%d\n", Attributes->CacheLevel);
136 PrintFieldName (4, L"Cache Associativity");
137 Print (L"%d\n", Attributes->CacheAssociativity);
138 PrintFieldName (4, L"Write Policy");
139 Print (L"%d\n", Attributes->WritePolicy);
140 PrintFieldName (4, L"Cache Line Size");
141 Print (L"%d\n", Attributes->CacheLineSize);
142}
143
148 PARSE_ACPI_HEADER (&AcpiHdrInfo),
149 { L"Reserved", 4,36, NULL, NULL, NULL, NULL, NULL }
150};
151
156 { L"Type", 2, 0, NULL, NULL, (VOID **)&HmatStructureType, NULL, NULL },
157 { L"Reserved", 2, 2, NULL, NULL, NULL, NULL, NULL },
158 { L"Length", 4, 4, NULL, NULL, (VOID **)&HmatStructureLength, NULL, NULL }
159};
160
166 { L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL },
167 { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
168 { L"Length", 4, 4, L"%d", NULL, NULL, NULL, NULL },
169 { L"Flags", 2, 8, L"0x%x", NULL, NULL, NULL, NULL },
170 { L"Reserved", 2, 10, L"0x%x", NULL, NULL, NULL, NULL },
171 { L"Proximity Dom for initiator", 4, 12, L"0x%x", NULL, NULL, NULL, NULL },
172 { L"Proximity Dom for memory", 4, 16, L"0x%x", NULL, NULL, NULL, NULL },
173 { L"Reserved", 4, 20, L"0x%x", NULL, NULL, NULL, NULL },
174 { L"Reserved", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL },
175 { L"Reserved", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL }
176};
177
183 { L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL },
184 { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
185 { L"Length", 4, 4, L"%d", NULL, NULL, NULL, NULL },
186 { L"Flags", 1, 8, L"0x%x", NULL, (VOID **)&SllbiFlags, NULL, NULL },
187 { L"Data type", 1, 9, L"0x%x", NULL, (VOID **)&SllbiDataType, NULL, NULL },
188 { L"Min Transfer Size", 1, 10, L"%d", NULL, NULL, NULL, NULL },
189 { L"Reserved", 1, 11, L"0x%x", NULL, NULL, NULL, NULL },
190 { L"Initiator Proximity Dom Count", 4, 12, L"%d", NULL,
191 (VOID **)&NumberInitiatorProximityDomain, NULL, NULL },
192 { L"Target Proximity Dom Count", 4, 16, L"%d", NULL,
193 (VOID **)&NumberTargetProximityDomain, NULL, NULL },
194 { L"Reserved", 4, 20, L"0x%x", NULL, NULL, NULL, NULL },
195 { L"Entry Base Unit", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL }
196 // initiator Proximity Domain list ...
197 // target Proximity Domain list ...
198 // Latency/Bandwidth matrix ...
199};
200
206 { L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL },
207 { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
208 { L"Length", 4, 4, L"%d", NULL, NULL, NULL, NULL },
209 { L"Proximity Dom for memory", 4, 8, L"0x%x", NULL, NULL, NULL, NULL },
210 { L"Reserved", 4, 12, L"0x%x", NULL, NULL, NULL, NULL },
211 { L"Memory Side Cache Size", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL },
212 { L"Cache Attributes", 4, 24, NULL, DumpCacheAttributes, NULL,
214 { L"Reserved", 2, 28, L"0x%x", NULL, NULL, NULL, NULL },
215 { L"SMBIOS Handle Count", 2, 30, L"%d", NULL,
216 (VOID **)&NumberSMBIOSHandles, NULL, NULL }
217 // SMBIOS handles List ...
218};
219
229STATIC
230VOID
232 IN UINT8 *Ptr,
233 IN UINT32 Length
234 )
235{
236 ParseAcpi (
237 TRUE,
238 2,
239 "Memory Proximity Domain Attributes Structure",
240 Ptr,
241 Length,
243 );
244}
245
255STATIC
256VOID
258 IN UINT8 *Ptr,
259 IN UINT32 Length
260 )
261{
262 CONST UINT32 *InitiatorProximityDomainList;
263 CONST UINT32 *TargetProximityDomainList;
264 CONST UINT16 *LatencyBandwidthMatrix;
265 UINT32 Offset;
266 CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH];
267 CHAR16 SecondBuffer[OUTPUT_FIELD_COLUMN_WIDTH];
268 UINT32 RequiredTableSize;
269 UINT32 Index;
270 UINT32 IndexInitiator;
271 UINT32 IndexTarget;
272 UINT32 TargetStartOffset;
273
274 Offset = ParseAcpi (
275 TRUE,
276 2,
277 "System Locality Latency and Bandwidth Information Structure",
278 Ptr,
279 Length,
281 );
282
283 // Check if the values used to control the parsing logic have been
284 // successfully read.
285 if ((SllbiFlags == NULL) ||
286 (SllbiDataType == NULL) ||
287 (NumberInitiatorProximityDomain == NULL) ||
288 (NumberTargetProximityDomain == NULL))
289 {
291 Print (
292 L"ERROR: Insufficient remaining table buffer length to read the " \
293 L"SLLBI structure header. Length = %d.\n",
294 Length
295 );
296 return;
297 }
298
299 RequiredTableSize = (*NumberInitiatorProximityDomain * sizeof (UINT32)) +
300 (*NumberTargetProximityDomain * sizeof (UINT32)) +
301 (*NumberInitiatorProximityDomain *
302 *NumberTargetProximityDomain * sizeof (UINT16)) +
303 Offset;
304
305 if (RequiredTableSize > Length) {
307 Print (
308 L"ERROR: Insufficient System Locality Latency and Bandwidth" \
309 L"Information Structure length. TableLength = %d. " \
310 L"RequiredTableLength = %d.\n",
311 Length,
312 RequiredTableSize
313 );
314 return;
315 }
316
317 InitiatorProximityDomainList = (UINT32 *)(Ptr + Offset);
318 TargetProximityDomainList = InitiatorProximityDomainList +
319 *NumberInitiatorProximityDomain;
320 LatencyBandwidthMatrix = (UINT16 *)(TargetProximityDomainList +
321 *NumberTargetProximityDomain);
322
323 // Display each element of the Initiator Proximity Domain list
324 for (Index = 0; Index < *NumberInitiatorProximityDomain; Index++) {
326 Buffer,
327 sizeof (Buffer),
328 L"Initiator Proximity Dom [%d]",
329 Index
330 );
331
332 PrintFieldName (4, Buffer);
333 Print (
334 L"0x%x\n",
335 InitiatorProximityDomainList[Index]
336 );
337 }
338
339 // Display each element of the Target Proximity Domain list
340 for (Index = 0; Index < *NumberTargetProximityDomain; Index++) {
342 Buffer,
343 sizeof (Buffer),
344 L"Target Proximity Dom [%d]",
345 Index
346 );
347
348 PrintFieldName (4, Buffer);
349 Print (
350 L"0x%x\n",
351 TargetProximityDomainList[Index]
352 );
353 }
354
355 // Create base name depending on Data Type in this Structure
356 if (*SllbiDataType >= ARRAY_SIZE (SllbiNames)) {
358 Print (L"Error: Unkown Data Type. DataType = 0x%x.\n", *SllbiDataType);
359 return;
360 }
361
362 StrCpyS (Buffer, sizeof (Buffer), SllbiNames[*SllbiDataType]);
363
364 // Adjust base name depending on Memory Hierarchy in this Structure
365 switch (SllbiFlags->MemoryHierarchy) {
366 case 0:
368 SecondBuffer,
369 sizeof (SecondBuffer),
370 Buffer,
371 L"",
372 L"%s"
373 );
374 break;
375 case 1:
376 case 2:
377 case 3:
379 SecondBuffer,
380 sizeof (SecondBuffer),
381 Buffer,
382 L"Hit ",
383 L"%s"
384 );
385 break;
386 default:
388 Print (
389 L"Error: Invalid Memory Hierarchy. MemoryHierarchy = %d.\n",
390 SllbiFlags->MemoryHierarchy
391 );
392 return;
393 } // switch
394
395 if (*NumberTargetProximityDomain <= MAX_MEMORY_DOMAIN_TARGET_PRINT_MATRIX) {
396 // Display the latency/bandwidth matrix as a matrix
398 Buffer,
399 sizeof (Buffer),
400 SecondBuffer,
401 L""
402 );
403 PrintFieldName (4, Buffer);
404
405 Print (L"\n Target : X-axis (Horizontal)");
406 Print (L"\n Initiator : Y-axis (Vertical)");
407 Print (L"\n |");
408
409 for (IndexTarget = 0;
410 IndexTarget < *NumberTargetProximityDomain;
411 IndexTarget++)
412 {
413 Print (L" %2d", IndexTarget);
414 }
415
416 Print (L"\n ---+");
417 for (IndexTarget = 0;
418 IndexTarget < *NumberTargetProximityDomain;
419 IndexTarget++)
420 {
421 Print (L"------");
422 }
423
424 Print (L"\n");
425
426 TargetStartOffset = 0;
427 for (IndexInitiator = 0;
428 IndexInitiator < *NumberInitiatorProximityDomain;
429 IndexInitiator++)
430 {
431 Print (L" %2d |", IndexInitiator);
432 for (IndexTarget = 0;
433 IndexTarget < *NumberTargetProximityDomain;
434 IndexTarget++)
435 {
436 Print (
437 L" %5d",
438 LatencyBandwidthMatrix[TargetStartOffset + IndexTarget]
439 );
440 } // for Target
441
442 Print (L"\n");
443 TargetStartOffset += (*NumberTargetProximityDomain);
444 } // for Initiator
445
446 Print (L"\n");
447 } else {
448 // Display the latency/bandwidth matrix as a list
450 Buffer,
451 sizeof (Buffer),
452 SecondBuffer,
453 L" [%d][%d]"
454 );
455
456 TargetStartOffset = 0;
457 for (IndexInitiator = 0;
458 IndexInitiator < *NumberInitiatorProximityDomain;
459 IndexInitiator++)
460 {
461 for (IndexTarget = 0;
462 IndexTarget < *NumberTargetProximityDomain;
463 IndexTarget++)
464 {
466 SecondBuffer,
467 sizeof (SecondBuffer),
468 Buffer,
469 IndexInitiator,
470 IndexTarget
471 );
472
473 PrintFieldName (4, SecondBuffer);
474 Print (
475 L"%d\n",
476 LatencyBandwidthMatrix[TargetStartOffset + IndexTarget]
477 );
478 } // for Target
479
480 TargetStartOffset += (*NumberTargetProximityDomain);
481 } // for Initiator
482 }
483}
484
492STATIC
493VOID
495 IN UINT8 *Ptr,
496 IN UINT32 Length
497 )
498{
499 CONST UINT16 *SMBIOSHandlesList;
500 CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH];
501 UINT32 Offset;
502 UINT16 Index;
503
504 Offset = ParseAcpi (
505 TRUE,
506 2,
507 "Memory Side Cache Information Structure",
508 Ptr,
509 Length,
511 );
512
513 // Check if the values used to control the parsing logic have been
514 // successfully read.
515 if (NumberSMBIOSHandles == NULL) {
517 Print (
518 L"ERROR: Insufficient remaining table buffer length to read the " \
519 L"MSCI structure header. Length = %d.\n",
520 Length
521 );
522 return;
523 }
524
525 if ((*NumberSMBIOSHandles * sizeof (UINT16)) > (Length - Offset)) {
527 Print (
528 L"ERROR: Invalid Number of SMBIOS Handles. SMBIOSHandlesCount = %d." \
529 L"RemainingBufferLength = %d.\n",
530 *NumberSMBIOSHandles,
531 Length - Offset
532 );
533 return;
534 }
535
536 SMBIOSHandlesList = (UINT16 *)(Ptr + Offset);
537
538 for (Index = 0; Index < *NumberSMBIOSHandles; Index++) {
540 Buffer,
541 sizeof (Buffer),
542 L"SMBIOS Handles [%d]",
543 Index
544 );
545
546 PrintFieldName (4, Buffer);
547 Print (
548 L"0x%x\n",
549 SMBIOSHandlesList[Index]
550 );
551 }
552}
553
571VOID
572EFIAPI
574 IN BOOLEAN Trace,
575 IN UINT8 *Ptr,
576 IN UINT32 AcpiTableLength,
577 IN UINT8 AcpiTableRevision
578 )
579{
580 UINT32 Offset;
581 UINT8 *HmatStructurePtr;
582
583 if (!Trace) {
584 return;
585 }
586
587 Offset = ParseAcpi (
588 Trace,
589 0,
590 "HMAT",
591 Ptr,
592 AcpiTableLength,
594 );
595
596 HmatStructurePtr = Ptr + Offset;
597
598 while (Offset < AcpiTableLength) {
599 // Parse HMAT Structure Header to obtain Type and Length.
600 ParseAcpi (
601 FALSE,
602 0,
603 NULL,
604 HmatStructurePtr,
605 AcpiTableLength - Offset,
607 );
608
609 // Check if the values used to control the parsing logic have been
610 // successfully read.
611 if ((HmatStructureType == NULL) ||
612 (HmatStructureLength == NULL))
613 {
615 Print (
616 L"ERROR: Insufficient remaining table buffer length to read the " \
617 L"HMAT structure header. Length = %d.\n",
618 AcpiTableLength - Offset
619 );
620 return;
621 }
622
623 // Validate HMAT Structure length.
624 if ((*HmatStructureLength == 0) ||
625 ((Offset + (*HmatStructureLength)) > AcpiTableLength))
626 {
628 Print (
629 L"ERROR: Invalid HMAT Structure length. " \
630 L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
631 *HmatStructureLength,
632 Offset,
633 AcpiTableLength
634 );
635 return;
636 }
637
638 switch (*HmatStructureType) {
640 DumpMpda (
641 HmatStructurePtr,
642 *HmatStructureLength
643 );
644 break;
645 case EFI_ACPI_6_4_HMAT_TYPE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO:
646 DumpSllbi (
647 HmatStructurePtr,
648 *HmatStructureLength
649 );
650 break;
651 case EFI_ACPI_6_4_HMAT_TYPE_MEMORY_SIDE_CACHE_INFO:
652 DumpMsci (
653 HmatStructurePtr,
654 *HmatStructureLength
655 );
656 break;
657 default:
659 Print (
660 L"ERROR: Unknown HMAT structure:"
661 L" Type = %d, Length = %d\n",
662 *HmatStructureType,
663 *HmatStructureLength
664 );
665 break;
666 } // switch
667
668 HmatStructurePtr += *HmatStructureLength;
669 Offset += *HmatStructureLength;
670 } // while
671}
#define EFI_ACPI_6_4_HMAT_TYPE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES
Definition: Acpi64.h:2138
VOID EFIAPI PrintFieldName(IN UINT32 Indent, IN CONST CHAR16 *FieldName)
Definition: AcpiParser.c:641
VOID EFIAPI IncrementErrorCount(VOID)
Definition: AcpiParser.c:83
UINT32 EFIAPI ParseAcpi(IN BOOLEAN Trace, IN UINT32 Indent, IN CONST CHAR8 *AsciiName OPTIONAL, IN UINT8 *Ptr, IN UINT32 Length, IN CONST ACPI_PARSER *Parser, IN UINT32 ParserItems)
Definition: AcpiParser.c:683
#define PARSER_PARAMS(Parser)
Definition: AcpiParser.h:494
#define PARSE_ACPI_HEADER(Info)
Definition: AcpiParser.h:501
RETURN_STATUS EFIAPI StrCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:226
STATIC CONST CHAR16 * SllbiNames[]
Definition: HmatParser.c:44
STATIC CONST ACPI_PARSER HmatParser[]
Definition: HmatParser.c:147
STATIC CONST ACPI_PARSER SllbiParser[]
Definition: HmatParser.c:182
STATIC VOID DumpMpda(IN UINT8 *Ptr, IN UINT32 Length)
Definition: HmatParser.c:231
VOID EFIAPI ParseAcpiHmat(IN BOOLEAN Trace, IN UINT8 *Ptr, IN UINT32 AcpiTableLength, IN UINT8 AcpiTableRevision)
Definition: HmatParser.c:573
STATIC VOID EFIAPI ValidateCacheAttributes(IN UINT8 *Ptr, IN UINT32 Length, IN VOID *Context)
Definition: HmatParser.c:64
STATIC CONST ACPI_PARSER MemProximityDomainAttributeParser[]
Definition: HmatParser.c:165
STATIC CONST ACPI_PARSER MemSideCacheInfoParser[]
Definition: HmatParser.c:205
STATIC VOID EFIAPI DumpCacheAttributes(IN CONST CHAR16 *Format OPTIONAL, IN UINT8 *Ptr, IN UINT32 Length)
Definition: HmatParser.c:119
STATIC VOID DumpSllbi(IN UINT8 *Ptr, IN UINT32 Length)
Definition: HmatParser.c:257
STATIC CONST ACPI_PARSER HmatStructureHeaderParser[]
Definition: HmatParser.c:155
STATIC VOID DumpMsci(IN UINT8 *Ptr, IN UINT32 Length)
Definition: HmatParser.c:494
UINTN EFIAPI UnicodeSPrint(OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString,...)
Definition: PrintLib.c:408
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
UINTN EFIAPI Print(IN CONST CHAR16 *Format,...)
Definition: UefiLibPrint.c:113