]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c
ShellPkg/AcpiView: ERST Parser
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Erst / ErstParser.c
1 /** @file
2 ERST table parser
3
4 Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
5 Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 @par Reference(s):
9 - ACPI 6.5 Specification - August 2022
10 **/
11
12 #include <IndustryStandard/Acpi.h>
13 #include <Library/UefiLib.h>
14 #include "AcpiParser.h"
15 #include "AcpiTableParser.h"
16
17 // Local variables
18 STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
19 STATIC UINT32 *InstructionEntryCount;
20
21 /**
22 An array of strings describing the Erst actions
23 **/
24 STATIC CONST CHAR16 *ErstActionTable[] = {
25 L"BEGIN_WRITE_OPERATION",
26 L"BEGIN_READ_OPERATION",
27 L"BEGIN_CLEAR_OPERATION",
28 L"END_OPERATION",
29 L"SET_RECORD_OFFSET",
30 L"EXECUTE_OPERATION",
31 L"CHECK_BUSY_STATUS",
32 L"GET_COMMAND_STATUS",
33 L"GET_RECORD_IDENTIFIER",
34 L"SET_RECORD_IDENTIFIER",
35 L"GET_RECORD_COUNT",
36 L"BEGIN_DUMMY_WRITE_OPERATION",
37 L"RESERVED",
38 L"GET_ERROR_LOG_ADDRESS_RANGE",
39 L"GET_ERROR_LOG_ADDRESS_RANGE_LENGTH",
40 L"GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES",
41 L"GET_EXECUTE_OPERATION_TIMINGS"
42 };
43
44 /**
45 An array of strings describing the Erst instructions
46 **/
47 STATIC CONST CHAR16 *ErstInstructionTable[] = {
48 L"READ_REGISTER",
49 L"READ_REGISTER_VALUE",
50 L"WRITE_REGISTER",
51 L"WRITE_REGISTER_VALUE",
52 L"NOOP",
53 L"LOAD_VAR1",
54 L"LOAD_VAR2",
55 L"STORE_VAR1",
56 L"ADD",
57 L"SUBTRACT",
58 L"ADD_VALUE",
59 L"SUBTRACT_VALUE",
60 L"STALL",
61 L"STALL_WHILE_TRUE",
62 L"SKIP_NEXT_INSTRUCTION_IF_TRUE",
63 L"GOTO",
64 L"SET_SRC_ADDRESS_BASE",
65 L"SET_DST_ADDRESS_BASE",
66 L"MOVE_DATA"
67 };
68
69 /**
70 Validate Erst action.
71
72 @param [in] Ptr Pointer to the start of the field data.
73 @param [in] Context Pointer to context specific information e.g. this
74 could be a pointer to the ACPI table header.
75 **/
76 STATIC
77 VOID
78 EFIAPI
79 ValidateErstAction (
80 IN UINT8 *Ptr,
81 IN VOID *Context
82 )
83 {
84 if (*Ptr > EFI_ACPI_6_4_ERST_GET_EXECUTE_OPERATION_TIMINGS) {
85 IncrementErrorCount ();
86 Print (L"\nError: 0x%02x is not a valid action encoding", *Ptr);
87 }
88 }
89
90 /**
91 Validate Erst instruction.
92
93 @param [in] Ptr Pointer to the start of the field data.
94 @param [in] Context Pointer to context specific information e.g. this
95 could be a pointer to the ACPI table header.
96 **/
97 STATIC
98 VOID
99 EFIAPI
100 ValidateErstInstruction (
101 IN UINT8 *Ptr,
102 IN VOID *Context
103 )
104 {
105 if (*Ptr > EFI_ACPI_6_4_ERST_MOVE_DATA) {
106 IncrementErrorCount ();
107 Print (L"\nError: 0x%02x is not a valid instruction encoding", *Ptr);
108 }
109 }
110
111 /**
112 Validate Erst flags.
113
114 @param [in] Ptr Pointer to the start of the field data.
115 @param [in] Context Pointer to context specific information e.g. this
116 could be a pointer to the ACPI table header.
117 **/
118 STATIC
119 VOID
120 EFIAPI
121 ValidateErstFlags (
122 IN UINT8 *Ptr,
123 IN VOID *Context
124 )
125 {
126 if ((*Ptr & 0xfe) != 0) {
127 IncrementErrorCount ();
128 Print (L"\nError: Reserved Flag bits not set to 0");
129 }
130 }
131
132 /**
133 Looks up and prints the string corresponding to the index.
134
135 @param [in] Table Lookup table.
136 @param [in] Index Entry to print.
137 @param [in] NumEntries Number of valid entries in the table.
138 **/
139 STATIC
140 VOID
141 EFIAPI
142 FormatByte (
143 IN CONST CHAR16 *Table[],
144 IN UINT8 Index,
145 IN UINT8 NumEntries
146 )
147 {
148 CONST CHAR16 *String;
149
150 if (Index < NumEntries) {
151 String = Table[Index];
152 } else {
153 String = L"**INVALID**";
154 }
155
156 Print (
157 L"0x%02x (%s)",
158 Index,
159 String
160 );
161 }
162
163 /**
164 Prints the Erst Action.
165
166 @param [in] Format Optional format string for tracing the data.
167 @param [in] Ptr Pointer to the Action byte.
168 **/
169 STATIC
170 VOID
171 EFIAPI
172 DumpErstAction (
173 IN CONST CHAR16 *Format OPTIONAL,
174 IN UINT8 *Ptr
175 )
176 {
177 FormatByte (ErstActionTable, *Ptr, ARRAY_SIZE (ErstActionTable));
178 }
179
180 /**
181 Prints the Erst Instruction.
182
183 @param [in] Format Optional format string for tracing the data.
184 @param [in] Ptr Pointer to the Instruction byte.
185 **/
186 STATIC
187 VOID
188 EFIAPI
189 DumpErstInstruction (
190 IN CONST CHAR16 *Format OPTIONAL,
191 IN UINT8 *Ptr
192 )
193 {
194 FormatByte (ErstInstructionTable, *Ptr, ARRAY_SIZE (ErstInstructionTable));
195 }
196
197 /**
198 An ACPI_PARSER array describing the ACPI ERST Table.
199 **/
200 STATIC CONST ACPI_PARSER ErstParser[] = {
201 PARSE_ACPI_HEADER (&AcpiHdrInfo),
202 { L"Serialization Header Size", 4, 36, L"0x%x", NULL, NULL, NULL, NULL },
203 { L"Reserved", 4, 40, L"0x%x", NULL, NULL, NULL, NULL },
204 { L"Instruction Entry Count", 4, 44, L"0x%x", NULL, (VOID **)&InstructionEntryCount, NULL, NULL }
205 };
206
207 /**
208 An ACPI_PARSER array describing the Serialization Instruction Entry structure.
209 **/
210 STATIC CONST ACPI_PARSER SerializationInstructionEntryParser[] = {
211 { L"Serialization Action", 1, 0, L"0x%x", DumpErstAction, NULL, ValidateErstAction, NULL },
212 { L"Instruction", 1, 1, L"0x%x", DumpErstInstruction, NULL, ValidateErstInstruction, NULL },
213 { L"Flags", 1, 2, L"0x%x", NULL, NULL, ValidateErstFlags, NULL },
214 { L"Reserved", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
215 { L"Register Region", 12, 4, NULL, DumpGas, NULL, NULL, NULL },
216 { L"Value", 8, 16, L"0x%llx", NULL, NULL, NULL, NULL },
217 { L"Mask", 8, 24, L"0x%llx", NULL, NULL, NULL, NULL }
218 };
219
220 /**
221 This function parses the ACPI ERST table.
222 When trace is enabled this function parses the ERST table and
223 traces the ACPI table fields.
224
225 This function also performs validation of the ACPI table fields.
226
227 @param [in] Trace If TRUE, trace the ACPI fields.
228 @param [in] Ptr Pointer to the start of the buffer.
229 @param [in] AcpiTableLength Length of the ACPI table.
230 @param [in] AcpiTableRevision Revision of the ACPI table.
231 **/
232 VOID
233 EFIAPI
234 ParseAcpiErst (
235 IN BOOLEAN Trace,
236 IN UINT8 *Ptr,
237 IN UINT32 AcpiTableLength,
238 IN UINT8 AcpiTableRevision
239 )
240 {
241 UINT32 Offset;
242
243 if (!Trace) {
244 return;
245 }
246
247 Offset = ParseAcpi (
248 Trace,
249 0,
250 "ERST",
251 Ptr,
252 AcpiTableLength,
253 PARSER_PARAMS (ErstParser)
254 );
255
256 if (sizeof (EFI_ACPI_6_4_ERST_SERIALIZATION_INSTRUCTION_ENTRY)*(*InstructionEntryCount) != (AcpiTableLength - Offset)) {
257 IncrementErrorCount ();
258 Print (
259 L"ERROR: Invalid InstructionEntryCount. " \
260 L"Count = %d. Offset = %d. AcpiTableLength = %d.\n",
261 *InstructionEntryCount,
262 Offset,
263 AcpiTableLength
264 );
265 return;
266 }
267
268 while (Offset < AcpiTableLength) {
269 Offset += ParseAcpi (
270 Trace,
271 2,
272 "Serialization Action",
273 Ptr + Offset,
274 (AcpiTableLength - Offset),
275 PARSER_PARAMS (SerializationInstructionEntryParser)
276 );
277 }
278 }