diff options
Diffstat (limited to 'roms/edk2/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2')
-rw-r--r-- | roms/edk2/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/roms/edk2/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c b/roms/edk2/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c new file mode 100644 index 000000000..9df111eca --- /dev/null +++ b/roms/edk2/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c @@ -0,0 +1,302 @@ +/** @file
+ DBG2 table parser
+
+ Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.
+**/
+
+#include <IndustryStandard/DebugPort2Table.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+
+// Local variables pointing to the table fields
+STATIC CONST UINT32* OffsetDbgDeviceInfo;
+STATIC CONST UINT32* NumberDbgDeviceInfo;
+STATIC CONST UINT16* DbgDevInfoLen;
+STATIC CONST UINT8* GasCount;
+STATIC CONST UINT16* NameSpaceStringLength;
+STATIC CONST UINT16* NameSpaceStringOffset;
+STATIC CONST UINT16* OEMDataLength;
+STATIC CONST UINT16* OEMDataOffset;
+STATIC CONST UINT16* BaseAddrRegOffset;
+STATIC CONST UINT16* AddrSizeOffset;
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+/**
+ This function validates the NameSpace string length.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateNameSpaceStrLen (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ )
+{
+ UINT16 NameSpaceStrLen;
+
+ NameSpaceStrLen = *(UINT16*)Ptr;
+
+ if (NameSpaceStrLen < 2) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: NamespaceString Length = %d. If no Namespace device exists, " \
+ L"NamespaceString[] must contain a period '.'",
+ NameSpaceStrLen
+ );
+ }
+}
+
+/// An ACPI_PARSER array describing the ACPI DBG2 table.
+STATIC CONST ACPI_PARSER Dbg2Parser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo),
+ {L"OffsetDbgDeviceInfo", 4, 36, L"0x%x", NULL,
+ (VOID**)&OffsetDbgDeviceInfo, NULL, NULL},
+ {L"NumberDbgDeviceInfo", 4, 40, L"%d", NULL,
+ (VOID**)&NumberDbgDeviceInfo, NULL, NULL}
+};
+
+/// An ACPI_PARSER array describing the debug device information structure
+/// header.
+STATIC CONST ACPI_PARSER DbgDevInfoHeaderParser[] = {
+ {L"Revision", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 2, 1, L"%d", NULL, (VOID**)&DbgDevInfoLen, NULL, NULL}
+};
+
+/// An ACPI_PARSER array describing the debug device information.
+STATIC CONST ACPI_PARSER DbgDevInfoParser[] = {
+ {L"Revision", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 2, 1, L"%d", NULL, NULL, NULL, NULL},
+
+ {L"Generic Address Registers Count", 1, 3, L"0x%x", NULL,
+ (VOID**)&GasCount, NULL, NULL},
+ {L"NameSpace String Length", 2, 4, L"%d", NULL,
+ (VOID**)&NameSpaceStringLength, ValidateNameSpaceStrLen, NULL},
+ {L"NameSpace String Offset", 2, 6, L"0x%x", NULL,
+ (VOID**)&NameSpaceStringOffset, NULL, NULL},
+ {L"OEM Data Length", 2, 8, L"%d", NULL, (VOID**)&OEMDataLength,
+ NULL, NULL},
+ {L"OEM Data Offset", 2, 10, L"0x%x", NULL, (VOID**)&OEMDataOffset,
+ NULL, NULL},
+
+ {L"Port Type", 2, 12, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Port SubType", 2, 14, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 2, 16, L"%x", NULL, NULL, NULL, NULL},
+
+ {L"Base Address Register Offset", 2, 18, L"0x%x", NULL,
+ (VOID**)&BaseAddrRegOffset, NULL, NULL},
+ {L"Address Size Offset", 2, 20, L"0x%x", NULL,
+ (VOID**)&AddrSizeOffset, NULL, NULL}
+};
+
+/**
+ This function parses the debug device information structure.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the debug device information structure.
+**/
+STATIC
+VOID
+EFIAPI
+DumpDbgDeviceInfo (
+ IN UINT8* Ptr,
+ IN UINT16 Length
+ )
+{
+ UINT16 Index;
+ UINT16 Offset;
+
+ ParseAcpi (
+ TRUE,
+ 2,
+ "Debug Device Info",
+ Ptr,
+ Length,
+ PARSER_PARAMS (DbgDevInfoParser)
+ );
+
+ // Check if the values used to control the parsing logic have been
+ // successfully read.
+ if ((GasCount == NULL) ||
+ (NameSpaceStringLength == NULL) ||
+ (NameSpaceStringOffset == NULL) ||
+ (OEMDataLength == NULL) ||
+ (OEMDataOffset == NULL) ||
+ (BaseAddrRegOffset == NULL) ||
+ (AddrSizeOffset == NULL)) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Insufficient Debug Device Information Structure length. " \
+ L"Length = %d.\n",
+ Length
+ );
+ return;
+ }
+
+ // GAS
+ Index = 0;
+ Offset = *BaseAddrRegOffset;
+ while ((Index++ < *GasCount) &&
+ (Offset < Length)) {
+ PrintFieldName (4, L"BaseAddressRegister");
+ Offset += (UINT16)DumpGasStruct (
+ Ptr + Offset,
+ 4,
+ Length - Offset
+ );
+ }
+
+ // Make sure the array of address sizes corresponding to each GAS fit in the
+ // Debug Device Information structure
+ if ((*AddrSizeOffset + (*GasCount * sizeof (UINT32))) > Length) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Invalid GAS count. GasCount = %d. RemainingBufferLength = %d. " \
+ L"Parsing of the Debug Device Information structure aborted.\n",
+ *GasCount,
+ Length - *AddrSizeOffset
+ );
+ return;
+ }
+
+ // Address Size
+ Index = 0;
+ Offset = *AddrSizeOffset;
+ while ((Index++ < *GasCount) &&
+ (Offset < Length)) {
+ PrintFieldName (4, L"Address Size");
+ Print (L"0x%x\n", *((UINT32*)(Ptr + Offset)));
+ Offset += sizeof (UINT32);
+ }
+
+ // NameSpace String
+ Index = 0;
+ Offset = *NameSpaceStringOffset;
+ PrintFieldName (4, L"NameSpace String");
+ while ((Index++ < *NameSpaceStringLength) &&
+ (Offset < Length)) {
+ Print (L"%c", *(Ptr + Offset));
+ Offset++;
+ }
+ Print (L"\n");
+
+ // OEM Data
+ if (*OEMDataOffset != 0) {
+ Index = 0;
+ Offset = *OEMDataOffset;
+ PrintFieldName (4, L"OEM Data");
+ while ((Index++ < *OEMDataLength) &&
+ (Offset < Length)) {
+ Print (L"%x ", *(Ptr + Offset));
+ if ((Index & 7) == 0) {
+ Print (L"\n%-*s ", OUTPUT_FIELD_COLUMN_WIDTH, L"");
+ }
+ Offset++;
+ }
+ Print (L"\n");
+ }
+}
+
+/**
+ This function parses the ACPI DBG2 table.
+ When trace is enabled this function parses the DBG2 table and
+ traces the ACPI table fields.
+
+ This function also performs validation of the ACPI table fields.
+
+ @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
+ParseAcpiDbg2 (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ UINT32 Offset;
+ UINT32 Index;
+
+ if (!Trace) {
+ return;
+ }
+
+ Offset = ParseAcpi (
+ TRUE,
+ 0,
+ "DBG2",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (Dbg2Parser)
+ );
+
+ // Check if the values used to control the parsing logic have been
+ // successfully read.
+ if ((OffsetDbgDeviceInfo == NULL) ||
+ (NumberDbgDeviceInfo == NULL)) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Insufficient table length. AcpiTableLength = %d\n",
+ AcpiTableLength
+ );
+ return;
+ }
+
+ Offset = *OffsetDbgDeviceInfo;
+ Index = 0;
+
+ while (Index++ < *NumberDbgDeviceInfo) {
+
+ // Parse the Debug Device Information Structure header to obtain Length
+ ParseAcpi (
+ FALSE,
+ 0,
+ NULL,
+ Ptr + Offset,
+ AcpiTableLength - Offset,
+ PARSER_PARAMS (DbgDevInfoHeaderParser)
+ );
+
+ // Check if the values used to control the parsing logic have been
+ // successfully read.
+ if (DbgDevInfoLen == NULL) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Insufficient remaining table buffer length to read the " \
+ L"Debug Device Information structure's 'Length' field. " \
+ L"RemainingTableBufferLength = %d.\n",
+ AcpiTableLength - Offset
+ );
+ return;
+ }
+
+ // Validate Debug Device Information Structure length
+ if ((*DbgDevInfoLen == 0) ||
+ ((Offset + (*DbgDevInfoLen)) > AcpiTableLength)) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Invalid Debug Device Information Structure length. " \
+ L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
+ *DbgDevInfoLen,
+ Offset,
+ AcpiTableLength
+ );
+ return;
+ }
+
+ DumpDbgDeviceInfo (Ptr + Offset, (*DbgDevInfoLen));
+ Offset += (*DbgDevInfoLen);
+ }
+}
|