4 Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
8 - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.
11 #include <IndustryStandard/DebugPort2Table.h>
12 #include <Library/UefiLib.h>
13 #include "AcpiParser.h"
14 #include "AcpiTableParser.h"
16 // Local variables pointing to the table fields
17 STATIC CONST UINT32
*OffsetDbgDeviceInfo
;
18 STATIC CONST UINT32
*NumberDbgDeviceInfo
;
19 STATIC CONST UINT16
*DbgDevInfoLen
;
20 STATIC CONST UINT8
*GasCount
;
21 STATIC CONST UINT16
*NameSpaceStringLength
;
22 STATIC CONST UINT16
*NameSpaceStringOffset
;
23 STATIC CONST UINT16
*OEMDataLength
;
24 STATIC CONST UINT16
*OEMDataOffset
;
25 STATIC CONST UINT16
*BaseAddrRegOffset
;
26 STATIC CONST UINT16
*AddrSizeOffset
;
27 STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo
;
30 This function validates the NameSpace string length.
32 @param [in] Ptr Pointer to the start of the buffer.
33 @param [in] Context Pointer to context specific information e.g. this
34 could be a pointer to the ACPI table header.
39 ValidateNameSpaceStrLen (
44 UINT16 NameSpaceStrLen
;
46 NameSpaceStrLen
= *(UINT16
*)Ptr
;
48 if (NameSpaceStrLen
< 2) {
49 IncrementErrorCount ();
51 L
"\nERROR: NamespaceString Length = %d. If no Namespace device exists, " \
52 L
"NamespaceString[] must contain a period '.'",
58 /// An ACPI_PARSER array describing the ACPI DBG2 table.
59 STATIC CONST ACPI_PARSER Dbg2Parser
[] = {
60 PARSE_ACPI_HEADER (&AcpiHdrInfo
),
61 { L
"OffsetDbgDeviceInfo", 4, 36, L
"0x%x", NULL
,
62 (VOID
**)&OffsetDbgDeviceInfo
, NULL
, NULL
},
63 { L
"NumberDbgDeviceInfo", 4, 40, L
"%d", NULL
,
64 (VOID
**)&NumberDbgDeviceInfo
, NULL
, NULL
}
67 /// An ACPI_PARSER array describing the debug device information structure
69 STATIC CONST ACPI_PARSER DbgDevInfoHeaderParser
[] = {
70 { L
"Revision", 1, 0, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
71 { L
"Length", 2, 1, L
"%d", NULL
, (VOID
**)&DbgDevInfoLen
, NULL
, NULL
}
74 /// An ACPI_PARSER array describing the debug device information.
75 STATIC CONST ACPI_PARSER DbgDevInfoParser
[] = {
76 { L
"Revision", 1, 0, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
77 { L
"Length", 2, 1, L
"%d", NULL
, NULL
, NULL
, NULL
},
79 { L
"Generic Address Registers Count", 1, 3, L
"0x%x", NULL
,
80 (VOID
**)&GasCount
, NULL
, NULL
},
81 { L
"NameSpace String Length", 2, 4, L
"%d", NULL
,
82 (VOID
**)&NameSpaceStringLength
, ValidateNameSpaceStrLen
, NULL
},
83 { L
"NameSpace String Offset", 2, 6, L
"0x%x", NULL
,
84 (VOID
**)&NameSpaceStringOffset
, NULL
, NULL
},
85 { L
"OEM Data Length", 2, 8, L
"%d", NULL
, (VOID
**)&OEMDataLength
,
87 { L
"OEM Data Offset", 2, 10, L
"0x%x", NULL
, (VOID
**)&OEMDataOffset
,
90 { L
"Port Type", 2, 12, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
91 { L
"Port SubType", 2, 14, L
"0x%x", NULL
, NULL
, NULL
, NULL
},
92 { L
"Reserved", 2, 16, L
"%x", NULL
, NULL
, NULL
, NULL
},
94 { L
"Base Address Register Offset", 2, 18, L
"0x%x", NULL
,
95 (VOID
**)&BaseAddrRegOffset
, NULL
, NULL
},
96 { L
"Address Size Offset", 2, 20, L
"0x%x", NULL
,
97 (VOID
**)&AddrSizeOffset
, NULL
, NULL
}
101 This function parses the debug device information structure.
103 @param [in] Ptr Pointer to the start of the buffer.
104 @param [in] Length Length of the debug device information structure.
123 PARSER_PARAMS (DbgDevInfoParser
)
126 // Check if the values used to control the parsing logic have been
127 // successfully read.
128 if ((GasCount
== NULL
) ||
129 (NameSpaceStringLength
== NULL
) ||
130 (NameSpaceStringOffset
== NULL
) ||
131 (OEMDataLength
== NULL
) ||
132 (OEMDataOffset
== NULL
) ||
133 (BaseAddrRegOffset
== NULL
) ||
134 (AddrSizeOffset
== NULL
))
136 IncrementErrorCount ();
138 L
"ERROR: Insufficient Debug Device Information Structure length. " \
147 Offset
= *BaseAddrRegOffset
;
148 while ((Index
++ < *GasCount
) &&
151 PrintFieldName (4, L
"BaseAddressRegister");
152 Offset
+= (UINT16
)DumpGasStruct (
159 // Make sure the array of address sizes corresponding to each GAS fit in the
160 // Debug Device Information structure
161 if ((*AddrSizeOffset
+ (*GasCount
* sizeof (UINT32
))) > Length
) {
162 IncrementErrorCount ();
164 L
"ERROR: Invalid GAS count. GasCount = %d. RemainingBufferLength = %d. " \
165 L
"Parsing of the Debug Device Information structure aborted.\n",
167 Length
- *AddrSizeOffset
174 Offset
= *AddrSizeOffset
;
175 while ((Index
++ < *GasCount
) &&
178 PrintFieldName (4, L
"Address Size");
179 Print (L
"0x%x\n", *((UINT32
*)(Ptr
+ Offset
)));
180 Offset
+= sizeof (UINT32
);
185 Offset
= *NameSpaceStringOffset
;
186 PrintFieldName (4, L
"NameSpace String");
187 while ((Index
++ < *NameSpaceStringLength
) &&
190 Print (L
"%c", *(Ptr
+ Offset
));
197 if (*OEMDataOffset
!= 0) {
199 Offset
= *OEMDataOffset
;
200 PrintFieldName (4, L
"OEM Data");
201 while ((Index
++ < *OEMDataLength
) &&
204 Print (L
"%x ", *(Ptr
+ Offset
));
205 if ((Index
& 7) == 0) {
206 Print (L
"\n%-*s ", OUTPUT_FIELD_COLUMN_WIDTH
, L
"");
217 This function parses the ACPI DBG2 table.
218 When trace is enabled this function parses the DBG2 table and
219 traces the ACPI table fields.
221 This function also performs validation of the ACPI table fields.
223 @param [in] Trace If TRUE, trace the ACPI fields.
224 @param [in] Ptr Pointer to the start of the buffer.
225 @param [in] AcpiTableLength Length of the ACPI table.
226 @param [in] AcpiTableRevision Revision of the ACPI table.
233 IN UINT32 AcpiTableLength
,
234 IN UINT8 AcpiTableRevision
250 PARSER_PARAMS (Dbg2Parser
)
253 // Check if the values used to control the parsing logic have been
254 // successfully read.
255 if ((OffsetDbgDeviceInfo
== NULL
) ||
256 (NumberDbgDeviceInfo
== NULL
))
258 IncrementErrorCount ();
260 L
"ERROR: Insufficient table length. AcpiTableLength = %d\n",
266 Offset
= *OffsetDbgDeviceInfo
;
269 while (Index
++ < *NumberDbgDeviceInfo
) {
270 // Parse the Debug Device Information Structure header to obtain Length
276 AcpiTableLength
- Offset
,
277 PARSER_PARAMS (DbgDevInfoHeaderParser
)
280 // Check if the values used to control the parsing logic have been
281 // successfully read.
282 if (DbgDevInfoLen
== NULL
) {
283 IncrementErrorCount ();
285 L
"ERROR: Insufficient remaining table buffer length to read the " \
286 L
"Debug Device Information structure's 'Length' field. " \
287 L
"RemainingTableBufferLength = %d.\n",
288 AcpiTableLength
- Offset
293 // Validate Debug Device Information Structure length
294 if ((*DbgDevInfoLen
== 0) ||
295 ((Offset
+ (*DbgDevInfoLen
)) > AcpiTableLength
))
297 IncrementErrorCount ();
299 L
"ERROR: Invalid Debug Device Information Structure length. " \
300 L
"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
308 DumpDbgDeviceInfo (Ptr
+ Offset
, (*DbgDevInfoLen
));
309 Offset
+= (*DbgDevInfoLen
);