]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Dbg2 / Dbg2Parser.c
CommitLineData
a6eaba4d 1/** @file\r
ee4dc24f
RN
2 DBG2 table parser\r
3\r
b8504826 4 Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.\r
56ba3746 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
ee4dc24f
RN
6\r
7 @par Reference(s):\r
8 - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.\r
9**/\r
10\r
11#include <IndustryStandard/DebugPort2Table.h>\r
12#include <Library/UefiLib.h>\r
13#include "AcpiParser.h"\r
14#include "AcpiTableParser.h"\r
15\r
16// Local variables pointing to the table fields\r
47d20b54
MK
17STATIC CONST UINT32 *OffsetDbgDeviceInfo;\r
18STATIC CONST UINT32 *NumberDbgDeviceInfo;\r
19STATIC CONST UINT16 *DbgDevInfoLen;\r
20STATIC CONST UINT8 *GasCount;\r
21STATIC CONST UINT16 *NameSpaceStringLength;\r
22STATIC CONST UINT16 *NameSpaceStringOffset;\r
23STATIC CONST UINT16 *OEMDataLength;\r
24STATIC CONST UINT16 *OEMDataOffset;\r
25STATIC CONST UINT16 *BaseAddrRegOffset;\r
26STATIC CONST UINT16 *AddrSizeOffset;\r
27STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
ee4dc24f 28\r
a6eaba4d 29/**\r
8ff68cd5 30 This function validates the NameSpace string length.\r
ee4dc24f
RN
31\r
32 @param [in] Ptr Pointer to the start of the buffer.\r
33 @param [in] Context Pointer to context specific information e.g. this\r
34 could be a pointer to the ACPI table header.\r
a6eaba4d 35**/\r
ee4dc24f
RN
36STATIC\r
37VOID\r
38EFIAPI\r
39ValidateNameSpaceStrLen (\r
47d20b54
MK
40 IN UINT8 *Ptr,\r
41 IN VOID *Context\r
8ff68cd5
KK
42 )\r
43{\r
47d20b54 44 UINT16 NameSpaceStrLen;\r
ee4dc24f 45\r
47d20b54 46 NameSpaceStrLen = *(UINT16 *)Ptr;\r
ee4dc24f 47\r
8ff68cd5
KK
48 if (NameSpaceStrLen < 2) {\r
49 IncrementErrorCount ();\r
50 Print (\r
51 L"\nERROR: NamespaceString Length = %d. If no Namespace device exists, " \\r
47d20b54 52 L"NamespaceString[] must contain a period '.'",\r
8ff68cd5
KK
53 NameSpaceStrLen\r
54 );\r
55 }\r
56}\r
ee4dc24f
RN
57\r
58/// An ACPI_PARSER array describing the ACPI DBG2 table.\r
47d20b54 59STATIC CONST ACPI_PARSER Dbg2Parser[] = {\r
ee4dc24f 60 PARSE_ACPI_HEADER (&AcpiHdrInfo),\r
47d20b54
MK
61 { L"OffsetDbgDeviceInfo", 4, 36, L"0x%x", NULL,\r
62 (VOID **)&OffsetDbgDeviceInfo, NULL, NULL },\r
63 { L"NumberDbgDeviceInfo", 4, 40, L"%d", NULL,\r
64 (VOID **)&NumberDbgDeviceInfo, NULL, NULL }\r
ee4dc24f
RN
65};\r
66\r
ffb18f77
KK
67/// An ACPI_PARSER array describing the debug device information structure\r
68/// header.\r
47d20b54
MK
69STATIC CONST ACPI_PARSER DbgDevInfoHeaderParser[] = {\r
70 { L"Revision", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },\r
71 { L"Length", 2, 1, L"%d", NULL, (VOID **)&DbgDevInfoLen, NULL, NULL }\r
ffb18f77
KK
72};\r
73\r
ee4dc24f 74/// An ACPI_PARSER array describing the debug device information.\r
47d20b54
MK
75STATIC CONST ACPI_PARSER DbgDevInfoParser[] = {\r
76 { L"Revision", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },\r
77 { L"Length", 2, 1, L"%d", NULL, NULL, NULL, NULL },\r
78\r
79 { L"Generic Address Registers Count", 1, 3, L"0x%x", NULL,\r
80 (VOID **)&GasCount, NULL, NULL },\r
81 { L"NameSpace String Length", 2, 4, L"%d", NULL,\r
82 (VOID **)&NameSpaceStringLength, ValidateNameSpaceStrLen, NULL },\r
83 { L"NameSpace String Offset", 2, 6, L"0x%x", NULL,\r
84 (VOID **)&NameSpaceStringOffset, NULL, NULL },\r
85 { L"OEM Data Length", 2, 8, L"%d", NULL, (VOID **)&OEMDataLength,\r
86 NULL, NULL },\r
87 { L"OEM Data Offset", 2, 10, L"0x%x", NULL, (VOID **)&OEMDataOffset,\r
88 NULL, NULL },\r
89\r
90 { L"Port Type", 2, 12, L"0x%x", NULL, NULL, NULL, NULL },\r
91 { L"Port SubType", 2, 14, L"0x%x", NULL, NULL, NULL, NULL },\r
92 { L"Reserved", 2, 16, L"%x", NULL, NULL, NULL, NULL },\r
93\r
94 { L"Base Address Register Offset", 2, 18, L"0x%x", NULL,\r
95 (VOID **)&BaseAddrRegOffset, NULL, NULL },\r
96 { L"Address Size Offset", 2, 20, L"0x%x", NULL,\r
97 (VOID **)&AddrSizeOffset, NULL, NULL }\r
ee4dc24f
RN
98};\r
99\r
a6eaba4d
DB
100/**\r
101 This function parses the debug device information structure.\r
ee4dc24f 102\r
ffb18f77
KK
103 @param [in] Ptr Pointer to the start of the buffer.\r
104 @param [in] Length Length of the debug device information structure.\r
a6eaba4d 105**/\r
ee4dc24f
RN
106STATIC\r
107VOID\r
108EFIAPI\r
109DumpDbgDeviceInfo (\r
47d20b54
MK
110 IN UINT8 *Ptr,\r
111 IN UINT16 Length\r
ee4dc24f
RN
112 )\r
113{\r
114 UINT16 Index;\r
ffb18f77 115 UINT16 Offset;\r
ee4dc24f
RN
116\r
117 ParseAcpi (\r
118 TRUE,\r
119 2,\r
120 "Debug Device Info",\r
121 Ptr,\r
ffb18f77 122 Length,\r
ee4dc24f
RN
123 PARSER_PARAMS (DbgDevInfoParser)\r
124 );\r
125\r
ccb4c38a
KK
126 // Check if the values used to control the parsing logic have been\r
127 // successfully read.\r
128 if ((GasCount == NULL) ||\r
129 (NameSpaceStringLength == NULL) ||\r
130 (NameSpaceStringOffset == NULL) ||\r
131 (OEMDataLength == NULL) ||\r
132 (OEMDataOffset == NULL) ||\r
133 (BaseAddrRegOffset == NULL) ||\r
47d20b54
MK
134 (AddrSizeOffset == NULL))\r
135 {\r
ccb4c38a
KK
136 IncrementErrorCount ();\r
137 Print (\r
138 L"ERROR: Insufficient Debug Device Information Structure length. " \\r
47d20b54 139 L"Length = %d.\n",\r
ccb4c38a
KK
140 Length\r
141 );\r
142 return;\r
143 }\r
144\r
ffb18f77 145 // GAS\r
47d20b54 146 Index = 0;\r
ffb18f77
KK
147 Offset = *BaseAddrRegOffset;\r
148 while ((Index++ < *GasCount) &&\r
47d20b54
MK
149 (Offset < Length))\r
150 {\r
ee4dc24f 151 PrintFieldName (4, L"BaseAddressRegister");\r
ffb18f77
KK
152 Offset += (UINT16)DumpGasStruct (\r
153 Ptr + Offset,\r
154 4,\r
155 Length - Offset\r
156 );\r
157 }\r
158\r
159 // Make sure the array of address sizes corresponding to each GAS fit in the\r
160 // Debug Device Information structure\r
161 if ((*AddrSizeOffset + (*GasCount * sizeof (UINT32))) > Length) {\r
162 IncrementErrorCount ();\r
163 Print (\r
164 L"ERROR: Invalid GAS count. GasCount = %d. RemainingBufferLength = %d. " \\r
47d20b54 165 L"Parsing of the Debug Device Information structure aborted.\n",\r
ffb18f77
KK
166 *GasCount,\r
167 Length - *AddrSizeOffset\r
168 );\r
169 return;\r
170 }\r
171\r
172 // Address Size\r
47d20b54 173 Index = 0;\r
ffb18f77
KK
174 Offset = *AddrSizeOffset;\r
175 while ((Index++ < *GasCount) &&\r
47d20b54
MK
176 (Offset < Length))\r
177 {\r
ee4dc24f 178 PrintFieldName (4, L"Address Size");\r
47d20b54 179 Print (L"0x%x\n", *((UINT32 *)(Ptr + Offset)));\r
ffb18f77 180 Offset += sizeof (UINT32);\r
ee4dc24f
RN
181 }\r
182\r
183 // NameSpace String\r
47d20b54 184 Index = 0;\r
ffb18f77 185 Offset = *NameSpaceStringOffset;\r
ee4dc24f 186 PrintFieldName (4, L"NameSpace String");\r
ffb18f77 187 while ((Index++ < *NameSpaceStringLength) &&\r
47d20b54
MK
188 (Offset < Length))\r
189 {\r
ffb18f77
KK
190 Print (L"%c", *(Ptr + Offset));\r
191 Offset++;\r
ee4dc24f 192 }\r
47d20b54 193\r
ee4dc24f
RN
194 Print (L"\n");\r
195\r
196 // OEM Data\r
ffb18f77 197 if (*OEMDataOffset != 0) {\r
47d20b54 198 Index = 0;\r
ffb18f77
KK
199 Offset = *OEMDataOffset;\r
200 PrintFieldName (4, L"OEM Data");\r
201 while ((Index++ < *OEMDataLength) &&\r
47d20b54
MK
202 (Offset < Length))\r
203 {\r
ffb18f77
KK
204 Print (L"%x ", *(Ptr + Offset));\r
205 if ((Index & 7) == 0) {\r
206 Print (L"\n%-*s ", OUTPUT_FIELD_COLUMN_WIDTH, L"");\r
207 }\r
47d20b54 208\r
ffb18f77 209 Offset++;\r
ee4dc24f 210 }\r
47d20b54 211\r
ffb18f77 212 Print (L"\n");\r
ee4dc24f 213 }\r
ee4dc24f
RN
214}\r
215\r
a6eaba4d
DB
216/**\r
217 This function parses the ACPI DBG2 table.\r
ee4dc24f
RN
218 When trace is enabled this function parses the DBG2 table and\r
219 traces the ACPI table fields.\r
220\r
221 This function also performs validation of the ACPI table fields.\r
222\r
223 @param [in] Trace If TRUE, trace the ACPI fields.\r
224 @param [in] Ptr Pointer to the start of the buffer.\r
225 @param [in] AcpiTableLength Length of the ACPI table.\r
226 @param [in] AcpiTableRevision Revision of the ACPI table.\r
a6eaba4d 227**/\r
ee4dc24f
RN
228VOID\r
229EFIAPI\r
230ParseAcpiDbg2 (\r
47d20b54
MK
231 IN BOOLEAN Trace,\r
232 IN UINT8 *Ptr,\r
233 IN UINT32 AcpiTableLength,\r
234 IN UINT8 AcpiTableRevision\r
ee4dc24f
RN
235 )\r
236{\r
47d20b54
MK
237 UINT32 Offset;\r
238 UINT32 Index;\r
ee4dc24f
RN
239\r
240 if (!Trace) {\r
241 return;\r
242 }\r
243\r
244 Offset = ParseAcpi (\r
245 TRUE,\r
246 0,\r
247 "DBG2",\r
248 Ptr,\r
249 AcpiTableLength,\r
250 PARSER_PARAMS (Dbg2Parser)\r
251 );\r
ee4dc24f 252\r
ccb4c38a
KK
253 // Check if the values used to control the parsing logic have been\r
254 // successfully read.\r
255 if ((OffsetDbgDeviceInfo == NULL) ||\r
47d20b54
MK
256 (NumberDbgDeviceInfo == NULL))\r
257 {\r
ccb4c38a
KK
258 IncrementErrorCount ();\r
259 Print (\r
260 L"ERROR: Insufficient table length. AcpiTableLength = %d\n",\r
261 AcpiTableLength\r
262 );\r
263 return;\r
264 }\r
265\r
ffb18f77 266 Offset = *OffsetDbgDeviceInfo;\r
47d20b54 267 Index = 0;\r
ffb18f77
KK
268\r
269 while (Index++ < *NumberDbgDeviceInfo) {\r
ffb18f77
KK
270 // Parse the Debug Device Information Structure header to obtain Length\r
271 ParseAcpi (\r
272 FALSE,\r
273 0,\r
274 NULL,\r
275 Ptr + Offset,\r
276 AcpiTableLength - Offset,\r
277 PARSER_PARAMS (DbgDevInfoHeaderParser)\r
ee4dc24f 278 );\r
ffb18f77 279\r
ccb4c38a
KK
280 // Check if the values used to control the parsing logic have been\r
281 // successfully read.\r
282 if (DbgDevInfoLen == NULL) {\r
283 IncrementErrorCount ();\r
284 Print (\r
285 L"ERROR: Insufficient remaining table buffer length to read the " \\r
47d20b54
MK
286 L"Debug Device Information structure's 'Length' field. " \\r
287 L"RemainingTableBufferLength = %d.\n",\r
ccb4c38a
KK
288 AcpiTableLength - Offset\r
289 );\r
290 return;\r
291 }\r
292\r
b8504826
KK
293 // Validate Debug Device Information Structure length\r
294 if ((*DbgDevInfoLen == 0) ||\r
47d20b54
MK
295 ((Offset + (*DbgDevInfoLen)) > AcpiTableLength))\r
296 {\r
ffb18f77
KK
297 IncrementErrorCount ();\r
298 Print (\r
b8504826 299 L"ERROR: Invalid Debug Device Information Structure length. " \\r
47d20b54 300 L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",\r
ffb18f77 301 *DbgDevInfoLen,\r
b8504826
KK
302 Offset,\r
303 AcpiTableLength\r
ffb18f77
KK
304 );\r
305 return;\r
306 }\r
307\r
308 DumpDbgDeviceInfo (Ptr + Offset, (*DbgDevInfoLen));\r
309 Offset += (*DbgDevInfoLen);\r
ee4dc24f
RN
310 }\r
311}\r