123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- /** @file
- SLIT table parser
- Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
- @par Reference(s):
- - ACPI 6.2 Specification - Errata A, September 2017
- **/
- #include <IndustryStandard/Acpi.h>
- #include <Library/PrintLib.h>
- #include <Library/UefiLib.h>
- #include "AcpiParser.h"
- #include "AcpiTableParser.h"
- // Local Variables
- STATIC CONST UINT64 *SlitSystemLocalityCount;
- STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
- /**
- An ACPI_PARSER array describing the ACPI SLIT table.
- **/
- STATIC CONST ACPI_PARSER SlitParser[] = {
- PARSE_ACPI_HEADER (&AcpiHdrInfo),
- { L"Number of System Localities", 8, 36, L"0x%lx", NULL,
- (VOID **)&SlitSystemLocalityCount,NULL, NULL }
- };
- /**
- Macro to get the value of a System Locality
- **/
- #define SLIT_ELEMENT(Ptr, i, j) *(Ptr + (i * LocalityCount) + j)
- /**
- This function parses the ACPI SLIT table.
- When trace is enabled this function parses the SLIT table and
- traces the ACPI table fields.
- This function also validates System Localities for the following:
- - Diagonal elements have a normalized value of 10
- - Relative distance from System Locality at i*N+j is same as
- j*N+i
- @param [in] Trace If TRUE, trace the ACPI fields.
- @param [in] Ptr Pointer to the start of the buffer.
- @param [in] AcpiTableLength Length of the ACPI table.
- @param [in] AcpiTableRevision Revision of the ACPI table.
- **/
- VOID
- EFIAPI
- ParseAcpiSlit (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
- {
- UINT32 Offset;
- UINT32 Count;
- UINT32 Index;
- UINT32 LocalityCount;
- UINT8 *LocalityPtr;
- CHAR16 Buffer[80]; // Used for AsciiName param of ParseAcpi
- if (!Trace) {
- return;
- }
- Offset = ParseAcpi (
- TRUE,
- 0,
- "SLIT",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (SlitParser)
- );
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if (SlitSystemLocalityCount == NULL) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient table length. AcpiTableLength = %d.\n",
- AcpiTableLength
- );
- return;
- }
- /*
- Despite the 'Number of System Localities' being a 64-bit field in SLIT,
- the maximum number of localities that can be represented in SLIT is limited
- by the 'Length' field of the ACPI table.
- Since the ACPI table length field is 32-bit wide. The maximum number of
- localities that can be represented in SLIT can be calculated as:
- MaxLocality = sqrt (MAX_UINT32 - sizeof (EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER))
- = 65535
- = MAX_UINT16
- */
- if (*SlitSystemLocalityCount > MAX_UINT16) {
- IncrementErrorCount ();
- Print (
- L"ERROR: The Number of System Localities provided can't be represented " \
- L"in the SLIT table. SlitSystemLocalityCount = %ld. " \
- L"MaxLocalityCountAllowed = %d.\n",
- *SlitSystemLocalityCount,
- MAX_UINT16
- );
- return;
- }
- LocalityCount = (UINT32)*SlitSystemLocalityCount;
- // Make sure system localities fit in the table buffer provided
- if (Offset + (LocalityCount * LocalityCount) > AcpiTableLength) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Number of System Localities. " \
- L"SlitSystemLocalityCount = %ld. AcpiTableLength = %d.\n",
- *SlitSystemLocalityCount,
- AcpiTableLength
- );
- return;
- }
- LocalityPtr = Ptr + Offset;
- // We only print the Localities if the count is less than 16
- // If the locality count is more than 16 then refer to the
- // raw data dump.
- if (LocalityCount < 16) {
- UnicodeSPrint (
- Buffer,
- sizeof (Buffer),
- L"Entry[0x%lx][0x%lx]",
- LocalityCount,
- LocalityCount
- );
- PrintFieldName (0, Buffer);
- Print (L"\n");
- Print (L" ");
- for (Index = 0; Index < LocalityCount; Index++) {
- Print (L" (%3d) ", Index);
- }
- Print (L"\n");
- for (Count = 0; Count < LocalityCount; Count++) {
- Print (L" (%3d) ", Count);
- for (Index = 0; Index < LocalityCount; Index++) {
- Print (L" %3d ", SLIT_ELEMENT (LocalityPtr, Count, Index));
- }
- Print (L"\n");
- }
- }
- // Validate
- for (Count = 0; Count < LocalityCount; Count++) {
- for (Index = 0; Index < LocalityCount; Index++) {
- // Element[x][x] must be equal to 10
- if ((Count == Index) && (SLIT_ELEMENT (LocalityPtr, Count, Index) != 10)) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Diagonal Element[0x%lx][0x%lx] (%3d)."
- L" Normalized Value is not 10\n",
- Count,
- Index,
- SLIT_ELEMENT (LocalityPtr, Count, Index)
- );
- }
- // Element[i][j] must be equal to Element[j][i]
- if (SLIT_ELEMENT (LocalityPtr, Count, Index) !=
- SLIT_ELEMENT (LocalityPtr, Index, Count))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Relative distances for Element[0x%lx][0x%lx] (%3d) and \n"
- L"Element[0x%lx][0x%lx] (%3d) do not match.\n",
- Count,
- Index,
- SLIT_ELEMENT (LocalityPtr, Count, Index),
- Index,
- Count,
- SLIT_ELEMENT (LocalityPtr, Index, Count)
- );
- }
- }
- }
- }
|