]> git.proxmox.com Git - mirror_edk2.git/blob - 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
1 /** @file
2 DBG2 table parser
3
4 Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 @par Reference(s):
8 - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.
9 **/
10
11 #include <IndustryStandard/DebugPort2Table.h>
12 #include <Library/UefiLib.h>
13 #include "AcpiParser.h"
14 #include "AcpiTableParser.h"
15
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;
28
29 /**
30 This function validates the NameSpace string length.
31
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.
35 **/
36 STATIC
37 VOID
38 EFIAPI
39 ValidateNameSpaceStrLen (
40 IN UINT8 *Ptr,
41 IN VOID *Context
42 )
43 {
44 UINT16 NameSpaceStrLen;
45
46 NameSpaceStrLen = *(UINT16 *)Ptr;
47
48 if (NameSpaceStrLen < 2) {
49 IncrementErrorCount ();
50 Print (
51 L"\nERROR: NamespaceString Length = %d. If no Namespace device exists, " \
52 L"NamespaceString[] must contain a period '.'",
53 NameSpaceStrLen
54 );
55 }
56 }
57
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 }
65 };
66
67 /// An ACPI_PARSER array describing the debug device information structure
68 /// header.
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 }
72 };
73
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 },
78
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,
86 NULL, NULL },
87 { L"OEM Data Offset", 2, 10, L"0x%x", NULL, (VOID **)&OEMDataOffset,
88 NULL, NULL },
89
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 },
93
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 }
98 };
99
100 /**
101 This function parses the debug device information structure.
102
103 @param [in] Ptr Pointer to the start of the buffer.
104 @param [in] Length Length of the debug device information structure.
105 **/
106 STATIC
107 VOID
108 EFIAPI
109 DumpDbgDeviceInfo (
110 IN UINT8 *Ptr,
111 IN UINT16 Length
112 )
113 {
114 UINT16 Index;
115 UINT16 Offset;
116
117 ParseAcpi (
118 TRUE,
119 2,
120 "Debug Device Info",
121 Ptr,
122 Length,
123 PARSER_PARAMS (DbgDevInfoParser)
124 );
125
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))
135 {
136 IncrementErrorCount ();
137 Print (
138 L"ERROR: Insufficient Debug Device Information Structure length. " \
139 L"Length = %d.\n",
140 Length
141 );
142 return;
143 }
144
145 // GAS
146 Index = 0;
147 Offset = *BaseAddrRegOffset;
148 while ((Index++ < *GasCount) &&
149 (Offset < Length))
150 {
151 PrintFieldName (4, L"BaseAddressRegister");
152 Offset += (UINT16)DumpGasStruct (
153 Ptr + Offset,
154 4,
155 Length - Offset
156 );
157 }
158
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 ();
163 Print (
164 L"ERROR: Invalid GAS count. GasCount = %d. RemainingBufferLength = %d. " \
165 L"Parsing of the Debug Device Information structure aborted.\n",
166 *GasCount,
167 Length - *AddrSizeOffset
168 );
169 return;
170 }
171
172 // Address Size
173 Index = 0;
174 Offset = *AddrSizeOffset;
175 while ((Index++ < *GasCount) &&
176 (Offset < Length))
177 {
178 PrintFieldName (4, L"Address Size");
179 Print (L"0x%x\n", *((UINT32 *)(Ptr + Offset)));
180 Offset += sizeof (UINT32);
181 }
182
183 // NameSpace String
184 Index = 0;
185 Offset = *NameSpaceStringOffset;
186 PrintFieldName (4, L"NameSpace String");
187 while ((Index++ < *NameSpaceStringLength) &&
188 (Offset < Length))
189 {
190 Print (L"%c", *(Ptr + Offset));
191 Offset++;
192 }
193
194 Print (L"\n");
195
196 // OEM Data
197 if (*OEMDataOffset != 0) {
198 Index = 0;
199 Offset = *OEMDataOffset;
200 PrintFieldName (4, L"OEM Data");
201 while ((Index++ < *OEMDataLength) &&
202 (Offset < Length))
203 {
204 Print (L"%x ", *(Ptr + Offset));
205 if ((Index & 7) == 0) {
206 Print (L"\n%-*s ", OUTPUT_FIELD_COLUMN_WIDTH, L"");
207 }
208
209 Offset++;
210 }
211
212 Print (L"\n");
213 }
214 }
215
216 /**
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.
220
221 This function also performs validation of the ACPI table fields.
222
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.
227 **/
228 VOID
229 EFIAPI
230 ParseAcpiDbg2 (
231 IN BOOLEAN Trace,
232 IN UINT8 *Ptr,
233 IN UINT32 AcpiTableLength,
234 IN UINT8 AcpiTableRevision
235 )
236 {
237 UINT32 Offset;
238 UINT32 Index;
239
240 if (!Trace) {
241 return;
242 }
243
244 Offset = ParseAcpi (
245 TRUE,
246 0,
247 "DBG2",
248 Ptr,
249 AcpiTableLength,
250 PARSER_PARAMS (Dbg2Parser)
251 );
252
253 // Check if the values used to control the parsing logic have been
254 // successfully read.
255 if ((OffsetDbgDeviceInfo == NULL) ||
256 (NumberDbgDeviceInfo == NULL))
257 {
258 IncrementErrorCount ();
259 Print (
260 L"ERROR: Insufficient table length. AcpiTableLength = %d\n",
261 AcpiTableLength
262 );
263 return;
264 }
265
266 Offset = *OffsetDbgDeviceInfo;
267 Index = 0;
268
269 while (Index++ < *NumberDbgDeviceInfo) {
270 // Parse the Debug Device Information Structure header to obtain Length
271 ParseAcpi (
272 FALSE,
273 0,
274 NULL,
275 Ptr + Offset,
276 AcpiTableLength - Offset,
277 PARSER_PARAMS (DbgDevInfoHeaderParser)
278 );
279
280 // Check if the values used to control the parsing logic have been
281 // successfully read.
282 if (DbgDevInfoLen == NULL) {
283 IncrementErrorCount ();
284 Print (
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
289 );
290 return;
291 }
292
293 // Validate Debug Device Information Structure length
294 if ((*DbgDevInfoLen == 0) ||
295 ((Offset + (*DbgDevInfoLen)) > AcpiTableLength))
296 {
297 IncrementErrorCount ();
298 Print (
299 L"ERROR: Invalid Debug Device Information Structure length. " \
300 L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
301 *DbgDevInfoLen,
302 Offset,
303 AcpiTableLength
304 );
305 return;
306 }
307
308 DumpDbgDeviceInfo (Ptr + Offset, (*DbgDevInfoLen));
309 Offset += (*DbgDevInfoLen);
310 }
311 }