]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c
ShellPkg/UefiShellAcpiViewCommandLib: Fix ECC issues
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Gtdt / GtdtParser.c
CommitLineData
a6eaba4d 1/** @file\r
ee4dc24f
RN
2 GTDT table parser\r
3\r
4 Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13 @par Reference(s):\r
14 - ACPI 6.2 Specification - Errata A, September 2017\r
15 **/\r
16\r
17#include <IndustryStandard/Acpi.h>\r
18#include <Library/UefiLib.h>\r
19#include "AcpiParser.h"\r
20#include "AcpiTableParser.h"\r
21\r
22// Local variables\r
23STATIC CONST UINT32* GtdtPlatformTimerCount;\r
24STATIC CONST UINT32* GtdtPlatformTimerOffset;\r
25STATIC CONST UINT8* PlatformTimerType;\r
26STATIC CONST UINT16* PlatformTimerLength;\r
27STATIC CONST UINT32* GtBlockTimerCount;\r
28STATIC CONST UINT32* GtBlockTimerOffset;\r
29STATIC CONST UINT16* GtBlockLength;\r
30STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
31\r
a6eaba4d
DB
32/**\r
33 This function validates the GT Block timer count.\r
ee4dc24f
RN
34\r
35 @param [in] Ptr Pointer to the start of the field data.\r
36 @param [in] Context Pointer to context specific information e.g. this\r
37 could be a pointer to the ACPI table header.\r
a6eaba4d 38**/\r
ee4dc24f
RN
39STATIC\r
40VOID\r
41EFIAPI\r
42ValidateGtBlockTimerCount (\r
43 IN UINT8* Ptr,\r
44 IN VOID* Context\r
45 );\r
46\r
a6eaba4d
DB
47/**\r
48 An ACPI_PARSER array describing the ACPI GTDT Table.\r
49**/\r
ee4dc24f
RN
50STATIC CONST ACPI_PARSER GtdtParser[] = {\r
51 PARSE_ACPI_HEADER (&AcpiHdrInfo),\r
52 {L"CntControlBase Physical Address", 8, 36, L"0x%lx", NULL, NULL,\r
53 NULL, NULL},\r
54 {L"Reserved", 4, 44, L"0x%x", NULL, NULL, NULL, NULL},\r
55 {L"Secure EL1 timer GSIV", 4, 48, L"0x%x", NULL, NULL, NULL, NULL},\r
56 {L"Secure EL1 timer FLAGS", 4, 52, L"0x%x", NULL, NULL, NULL, NULL},\r
57\r
58 {L"Non-Secure EL1 timer GSIV", 4, 56, L"0x%x", NULL, NULL, NULL, NULL},\r
59 {L"Non-Secure EL1 timer FLAGS", 4, 60, L"0x%x", NULL, NULL, NULL, NULL},\r
60\r
61 {L"Virtual timer GSIV", 4, 64, L"0x%x", NULL, NULL, NULL, NULL},\r
62 {L"Virtual timer FLAGS", 4, 68, L"0x%x", NULL, NULL, NULL, NULL},\r
63\r
64 {L"Non-Secure EL2 timer GSIV", 4, 72, L"0x%x", NULL, NULL, NULL, NULL},\r
65 {L"Non-Secure EL2 timer FLAGS", 4, 76, L"0x%x", NULL, NULL, NULL, NULL},\r
66\r
67 {L"CntReadBase Physical address", 8, 80, L"0x%lx", NULL, NULL, NULL, NULL},\r
68 {L"Platform Timer Count", 4, 88, L"%d", NULL,\r
69 (VOID**)&GtdtPlatformTimerCount, NULL, NULL},\r
70 {L"Platform Timer Offset", 4, 92, L"0x%x", NULL,\r
71 (VOID**)&GtdtPlatformTimerOffset, NULL, NULL}\r
72};\r
73\r
a6eaba4d
DB
74/**\r
75 An ACPI_PARSER array describing the Platform timer header.\r
76**/\r
ee4dc24f
RN
77STATIC CONST ACPI_PARSER GtPlatformTimerHeaderParser[] = {\r
78 {L"Type", 1, 0, NULL, NULL, (VOID**)&PlatformTimerType, NULL, NULL},\r
79 {L"Length", 2, 1, NULL, NULL, (VOID**)&PlatformTimerLength, NULL, NULL},\r
80 {L"Reserved", 1, 3, NULL, NULL, NULL, NULL, NULL}\r
81};\r
82\r
a6eaba4d
DB
83/**\r
84 An ACPI_PARSER array describing the Platform GT Block.\r
85**/\r
ee4dc24f
RN
86STATIC CONST ACPI_PARSER GtBlockParser[] = {\r
87 {L"Type", 1, 0, L"%d", NULL, NULL, NULL, NULL},\r
88 {L"Length", 2, 1, L"%d", NULL, (VOID**)&GtBlockLength, NULL, NULL},\r
89 {L"Reserved", 1, 3, L"%x", NULL, NULL, NULL, NULL},\r
90 {L"Physical address (CntCtlBase)", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL},\r
91 {L"Timer Count", 4, 12, L"%d", NULL, (VOID**)&GtBlockTimerCount,\r
92 ValidateGtBlockTimerCount, NULL},\r
93 {L"Timer Offset", 4, 16, L"%d", NULL, (VOID**)&GtBlockTimerOffset, NULL,\r
94 NULL}\r
95};\r
96\r
a6eaba4d
DB
97/**\r
98 An ACPI_PARSER array describing the GT Block timer.\r
99**/\r
ee4dc24f
RN
100STATIC CONST ACPI_PARSER GtBlockTimerParser[] = {\r
101 {L"Frame Number", 1, 0, L"%d", NULL, NULL, NULL, NULL},\r
102 {L"Reserved", 3, 1, L"%x %x %x", Dump3Chars, NULL, NULL, NULL},\r
103 {L"Physical address (CntBaseX)", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL},\r
104 {L"Physical address (CntEL0BaseX)", 8, 12, L"0x%lx", NULL, NULL, NULL,\r
105 NULL},\r
106 {L"Physical Timer GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},\r
107 {L"Physical Timer Flags", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},\r
108 {L"Virtual Timer GSIV", 4, 28, L"0x%x", NULL, NULL, NULL, NULL},\r
109 {L"Virtual Timer Flags", 4, 32, L"0x%x", NULL, NULL, NULL, NULL},\r
110 {L"Common Flags", 4, 36, L"0x%x", NULL, NULL, NULL, NULL}\r
111};\r
112\r
a6eaba4d
DB
113/**\r
114 An ACPI_PARSER array describing the Platform Watchdog.\r
115**/\r
ee4dc24f
RN
116STATIC CONST ACPI_PARSER SBSAGenericWatchdogParser[] = {\r
117 {L"Type", 1, 0, L"%d", NULL, NULL, NULL, NULL},\r
118 {L"Length", 2, 1, L"%d", NULL, NULL, NULL, NULL},\r
119 {L"Reserved", 1, 3, L"%x", NULL, NULL, NULL, NULL},\r
120 {L"RefreshFrame Physical address", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL},\r
121 {L"ControlFrame Physical address", 8, 12, L"0x%lx", NULL, NULL, NULL, NULL},\r
122 {L"Watchdog Timer GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},\r
123 {L"Watchdog Timer Flags", 4, 24, L"0x%x", NULL, NULL, NULL, NULL}\r
124};\r
125\r
a6eaba4d
DB
126/**\r
127 This function validates the GT Block timer count.\r
ee4dc24f
RN
128\r
129 @param [in] Ptr Pointer to the start of the field data.\r
130 @param [in] Context Pointer to context specific information e.g. this\r
131 could be a pointer to the ACPI table header.\r
a6eaba4d 132**/\r
ee4dc24f
RN
133STATIC\r
134VOID\r
135EFIAPI\r
136ValidateGtBlockTimerCount (\r
137 IN UINT8* Ptr,\r
138 IN VOID* Context\r
139 )\r
140{\r
141 UINT32 BlockTimerCount = *(UINT32*)Ptr;\r
142 if (BlockTimerCount > 8) {\r
143 IncrementErrorCount ();\r
144 Print (\r
145 L"\nERROR: Timer Count = %d. Max Timer Count is 8.",\r
146 BlockTimerCount\r
147 );\r
148 }\r
149}\r
150\r
a6eaba4d
DB
151/**\r
152 This function parses the Platform GT Block.\r
ee4dc24f
RN
153\r
154 @param [in] Ptr Pointer to the start of the GT Block data.\r
155 @param [in] Length Length of the GT Block structure.\r
a6eaba4d 156**/\r
ee4dc24f
RN
157STATIC\r
158VOID\r
159DumpGTBlock (\r
160 IN UINT8* Ptr,\r
161 IN UINT16 Length\r
162 )\r
163{\r
164 UINT32 Index;\r
165 UINT32 Offset;\r
166 UINT16 GTBlockTimerLength;\r
167\r
168 Offset = ParseAcpi (\r
169 TRUE,\r
170 2,\r
171 "GT Block",\r
172 Ptr,\r
173 Length,\r
174 PARSER_PARAMS (GtBlockParser)\r
175 );\r
176 GTBlockTimerLength = (*GtBlockLength - Offset) / (*GtBlockTimerCount);\r
177 Length -= Offset;\r
178\r
179 if (*GtBlockTimerCount != 0) {\r
180 Ptr += (*GtBlockTimerOffset);\r
181 Index = 0;\r
182 while ((Index < (*GtBlockTimerCount)) && (Length >= GTBlockTimerLength)) {\r
183 Offset = ParseAcpi (\r
184 TRUE,\r
185 2,\r
186 "GT Block Timer",\r
187 Ptr,\r
188 GTBlockTimerLength,\r
189 PARSER_PARAMS (GtBlockTimerParser)\r
190 );\r
191 // Increment by GT Block Timer structure size\r
192 Ptr += Offset;\r
193 Length -= Offset;\r
194 Index++;\r
195 }\r
196\r
197 if (Length != 0) {\r
198 IncrementErrorCount ();\r
199 Print (\r
200 L"ERROR:GT Block Timer length mismatch. Unparsed %d bytes.\n",\r
201 Length\r
202 );\r
203 }\r
204 }\r
205}\r
206\r
a6eaba4d
DB
207/**\r
208 This function parses the Platform Watchdog timer.\r
ee4dc24f
RN
209\r
210 @param [in] Ptr Pointer to the start of the watchdog timer data.\r
211 @param [in] Length Length of the watchdog timer structure.\r
a6eaba4d 212**/\r
ee4dc24f
RN
213STATIC\r
214VOID\r
215DumpWatchdogTimer (\r
216 IN UINT8* Ptr,\r
217 IN UINT16 Length\r
218 )\r
219{\r
220 ParseAcpi (\r
221 TRUE,\r
222 2,\r
223 "SBSA Generic Watchdog",\r
224 Ptr,\r
225 Length,\r
226 PARSER_PARAMS (SBSAGenericWatchdogParser)\r
227 );\r
228}\r
229\r
a6eaba4d
DB
230/**\r
231 This function parses the ACPI GTDT table.\r
ee4dc24f
RN
232 When trace is enabled this function parses the GTDT table and\r
233 traces the ACPI table fields.\r
234\r
235 This function also parses the following platform timer structures:\r
236 - GT Block timer\r
237 - Watchdog timer\r
238\r
239 This function also performs validation of the ACPI table fields.\r
240\r
241 @param [in] Trace If TRUE, trace the ACPI fields.\r
242 @param [in] Ptr Pointer to the start of the buffer.\r
243 @param [in] AcpiTableLength Length of the ACPI table.\r
244 @param [in] AcpiTableRevision Revision of the ACPI table.\r
a6eaba4d 245**/\r
ee4dc24f
RN
246VOID\r
247EFIAPI\r
248ParseAcpiGtdt (\r
249 IN BOOLEAN Trace,\r
250 IN UINT8* Ptr,\r
251 IN UINT32 AcpiTableLength,\r
252 IN UINT8 AcpiTableRevision\r
253 )\r
254{\r
255 UINT32 Index;\r
256 UINT8* TimerPtr;\r
257\r
258 if (!Trace) {\r
259 return;\r
260 }\r
261\r
262 ParseAcpi (\r
263 TRUE,\r
264 0,\r
265 "GTDT",\r
266 Ptr,\r
267 AcpiTableLength,\r
268 PARSER_PARAMS (GtdtParser)\r
269 );\r
270\r
271 if (*GtdtPlatformTimerCount != 0) {\r
272 TimerPtr = Ptr + (*GtdtPlatformTimerOffset);\r
273 Index = 0;\r
274 do {\r
275 // Parse the Platform Timer Header\r
276 ParseAcpi (\r
277 FALSE,\r
278 0,\r
279 NULL,\r
280 TimerPtr,\r
281 4, // GT Platform Timer structure header length.\r
282 PARSER_PARAMS (GtPlatformTimerHeaderParser)\r
283 );\r
284 switch (*PlatformTimerType) {\r
285 case EFI_ACPI_6_2_GTDT_GT_BLOCK:\r
286 DumpGTBlock (TimerPtr, *PlatformTimerLength);\r
287 break;\r
288 case EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG:\r
289 DumpWatchdogTimer (TimerPtr, *PlatformTimerLength);\r
290 break;\r
291 default:\r
292 IncrementErrorCount ();\r
293 Print (\r
294 L"ERROR: INVALID Platform Timer Type = %d\n",\r
295 *PlatformTimerType\r
296 );\r
297 break;\r
298 } // switch\r
299 TimerPtr += (*PlatformTimerLength);\r
300 Index++;\r
301 } while (Index < *GtdtPlatformTimerCount);\r
302 }\r
303}\r