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