Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[linux-2.6-microblaze.git] / drivers / acpi / acpica / psloop.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: psloop - Main AML parse loop
5  *
6  * Copyright (C) 2000 - 2020, Intel Corp.
7  *
8  *****************************************************************************/
9
10 /*
11  * Parse the AML and build an operation tree as most interpreters, (such as
12  * Perl) do. Parsing is done by hand rather than with a YACC generated parser
13  * to tightly constrain stack and dynamic memory usage. Parsing is kept
14  * flexible and the code fairly compact by parsing based on a list of AML
15  * opcode templates in aml_op_info[].
16  */
17
18 #include <acpi/acpi.h>
19 #include "accommon.h"
20 #include "acinterp.h"
21 #include "acparser.h"
22 #include "acdispat.h"
23 #include "amlcode.h"
24 #include "acconvert.h"
25 #include "acnamesp.h"
26
27 #define _COMPONENT          ACPI_PARSER
28 ACPI_MODULE_NAME("psloop")
29
30 /* Local prototypes */
31 static acpi_status
32 acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
33                       u8 * aml_op_start, union acpi_parse_object *op);
34
35 /*******************************************************************************
36  *
37  * FUNCTION:    acpi_ps_get_arguments
38  *
39  * PARAMETERS:  walk_state          - Current state
40  *              aml_op_start        - Op start in AML
41  *              op                  - Current Op
42  *
43  * RETURN:      Status
44  *
45  * DESCRIPTION: Get arguments for passed Op.
46  *
47  ******************************************************************************/
48
49 static acpi_status
50 acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
51                       u8 * aml_op_start, union acpi_parse_object *op)
52 {
53         acpi_status status = AE_OK;
54         union acpi_parse_object *arg = NULL;
55
56         ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state);
57
58         ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
59                           "Get arguments for opcode [%s]\n",
60                           op->common.aml_op_name));
61
62         switch (op->common.aml_opcode) {
63         case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
64         case AML_WORD_OP:       /* AML_WORDDATA_ARG */
65         case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
66         case AML_QWORD_OP:      /* AML_QWORDATA_ARG */
67         case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */
68
69                 /* Fill in constant or string argument directly */
70
71                 acpi_ps_get_next_simple_arg(&(walk_state->parser_state),
72                                             GET_CURRENT_ARG_TYPE(walk_state->
73                                                                  arg_types),
74                                             op);
75                 break;
76
77         case AML_INT_NAMEPATH_OP:       /* AML_NAMESTRING_ARG */
78
79                 status = acpi_ps_get_next_namepath(walk_state,
80                                                    &(walk_state->parser_state),
81                                                    op,
82                                                    ACPI_POSSIBLE_METHOD_CALL);
83                 if (ACPI_FAILURE(status)) {
84                         return_ACPI_STATUS(status);
85                 }
86
87                 walk_state->arg_types = 0;
88                 break;
89
90         default:
91                 /*
92                  * Op is not a constant or string, append each argument to the Op
93                  */
94                 while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
95                        !walk_state->arg_count) {
96                         walk_state->aml = walk_state->parser_state.aml;
97
98                         switch (op->common.aml_opcode) {
99                         case AML_METHOD_OP:
100                         case AML_BUFFER_OP:
101                         case AML_PACKAGE_OP:
102                         case AML_VARIABLE_PACKAGE_OP:
103                         case AML_WHILE_OP:
104
105                                 break;
106
107                         default:
108
109                                 ASL_CV_CAPTURE_COMMENTS(walk_state);
110                                 break;
111                         }
112
113                         status =
114                             acpi_ps_get_next_arg(walk_state,
115                                                  &(walk_state->parser_state),
116                                                  GET_CURRENT_ARG_TYPE
117                                                  (walk_state->arg_types), &arg);
118                         if (ACPI_FAILURE(status)) {
119                                 return_ACPI_STATUS(status);
120                         }
121
122                         if (arg) {
123                                 acpi_ps_append_arg(op, arg);
124                         }
125
126                         INCREMENT_ARG_LIST(walk_state->arg_types);
127                 }
128
129                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
130                                   "Final argument count: %8.8X pass %u\n",
131                                   walk_state->arg_count,
132                                   walk_state->pass_number));
133
134                 /* Special processing for certain opcodes */
135
136                 switch (op->common.aml_opcode) {
137                 case AML_METHOD_OP:
138                         /*
139                          * Skip parsing of control method because we don't have enough
140                          * info in the first pass to parse it correctly.
141                          *
142                          * Save the length and address of the body
143                          */
144                         op->named.data = walk_state->parser_state.aml;
145                         op->named.length = (u32)
146                             (walk_state->parser_state.pkg_end -
147                              walk_state->parser_state.aml);
148
149                         /* Skip body of method */
150
151                         walk_state->parser_state.aml =
152                             walk_state->parser_state.pkg_end;
153                         walk_state->arg_count = 0;
154                         break;
155
156                 case AML_BUFFER_OP:
157                 case AML_PACKAGE_OP:
158                 case AML_VARIABLE_PACKAGE_OP:
159
160                         if ((op->common.parent) &&
161                             (op->common.parent->common.aml_opcode ==
162                              AML_NAME_OP)
163                             && (walk_state->pass_number <=
164                                 ACPI_IMODE_LOAD_PASS2)) {
165                                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
166                                                   "Setup Package/Buffer: Pass %u, AML Ptr: %p\n",
167                                                   walk_state->pass_number,
168                                                   aml_op_start));
169
170                                 /*
171                                  * Skip parsing of Buffers and Packages because we don't have
172                                  * enough info in the first pass to parse them correctly.
173                                  */
174                                 op->named.data = aml_op_start;
175                                 op->named.length = (u32)
176                                     (walk_state->parser_state.pkg_end -
177                                      aml_op_start);
178
179                                 /* Skip body */
180
181                                 walk_state->parser_state.aml =
182                                     walk_state->parser_state.pkg_end;
183                                 walk_state->arg_count = 0;
184                         }
185                         break;
186
187                 case AML_WHILE_OP:
188
189                         if (walk_state->control_state) {
190                                 walk_state->control_state->control.package_end =
191                                     walk_state->parser_state.pkg_end;
192                         }
193                         break;
194
195                 default:
196
197                         /* No action for all other opcodes */
198
199                         break;
200                 }
201
202                 break;
203         }
204
205         return_ACPI_STATUS(AE_OK);
206 }
207
208 /*******************************************************************************
209  *
210  * FUNCTION:    acpi_ps_parse_loop
211  *
212  * PARAMETERS:  walk_state          - Current state
213  *
214  * RETURN:      Status
215  *
216  * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
217  *              a tree of ops.
218  *
219  ******************************************************************************/
220
221 acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
222 {
223         acpi_status status = AE_OK;
224         union acpi_parse_object *op = NULL;     /* current op */
225         struct acpi_parse_state *parser_state;
226         u8 *aml_op_start = NULL;
227         u8 opcode_length;
228
229         ACPI_FUNCTION_TRACE_PTR(ps_parse_loop, walk_state);
230
231         if (walk_state->descending_callback == NULL) {
232                 return_ACPI_STATUS(AE_BAD_PARAMETER);
233         }
234
235         parser_state = &walk_state->parser_state;
236         walk_state->arg_types = 0;
237
238 #ifndef ACPI_CONSTANT_EVAL_ONLY
239
240         if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
241
242                 /* We are restarting a preempted control method */
243
244                 if (acpi_ps_has_completed_scope(parser_state)) {
245                         /*
246                          * We must check if a predicate to an IF or WHILE statement
247                          * was just completed
248                          */
249                         if ((parser_state->scope->parse_scope.op) &&
250                             ((parser_state->scope->parse_scope.op->common.
251                               aml_opcode == AML_IF_OP)
252                              || (parser_state->scope->parse_scope.op->common.
253                                  aml_opcode == AML_WHILE_OP))
254                             && (walk_state->control_state)
255                             && (walk_state->control_state->common.state ==
256                                 ACPI_CONTROL_PREDICATE_EXECUTING)) {
257                                 /*
258                                  * A predicate was just completed, get the value of the
259                                  * predicate and branch based on that value
260                                  */
261                                 walk_state->op = NULL;
262                                 status =
263                                     acpi_ds_get_predicate_value(walk_state,
264                                                                 ACPI_TO_POINTER
265                                                                 (TRUE));
266                                 if (ACPI_FAILURE(status)
267                                     && ((status & AE_CODE_MASK) !=
268                                         AE_CODE_CONTROL)) {
269                                         if (status == AE_AML_NO_RETURN_VALUE) {
270                                                 ACPI_EXCEPTION((AE_INFO, status,
271                                                                 "Invoked method did not return a value"));
272                                         }
273
274                                         ACPI_EXCEPTION((AE_INFO, status,
275                                                         "GetPredicate Failed"));
276                                         return_ACPI_STATUS(status);
277                                 }
278
279                                 status =
280                                     acpi_ps_next_parse_state(walk_state, op,
281                                                              status);
282                         }
283
284                         acpi_ps_pop_scope(parser_state, &op,
285                                           &walk_state->arg_types,
286                                           &walk_state->arg_count);
287                         ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
288                                           "Popped scope, Op=%p\n", op));
289                 } else if (walk_state->prev_op) {
290
291                         /* We were in the middle of an op */
292
293                         op = walk_state->prev_op;
294                         walk_state->arg_types = walk_state->prev_arg_types;
295                 }
296         }
297 #endif
298
299         /* Iterative parsing loop, while there is more AML to process: */
300
301         while ((parser_state->aml < parser_state->aml_end) || (op)) {
302                 ASL_CV_CAPTURE_COMMENTS(walk_state);
303
304                 aml_op_start = parser_state->aml;
305                 if (!op) {
306                         status =
307                             acpi_ps_create_op(walk_state, aml_op_start, &op);
308                         if (ACPI_FAILURE(status)) {
309                                 /*
310                                  * ACPI_PARSE_MODULE_LEVEL means that we are loading a table by
311                                  * executing it as a control method. However, if we encounter
312                                  * an error while loading the table, we need to keep trying to
313                                  * load the table rather than aborting the table load. Set the
314                                  * status to AE_OK to proceed with the table load.
315                                  */
316                                 if ((walk_state->
317                                      parse_flags & ACPI_PARSE_MODULE_LEVEL)
318                                     && ((status == AE_ALREADY_EXISTS)
319                                         || (status == AE_NOT_FOUND))) {
320                                         status = AE_OK;
321                                 }
322                                 if (status == AE_CTRL_PARSE_CONTINUE) {
323                                         continue;
324                                 }
325
326                                 if (status == AE_CTRL_PARSE_PENDING) {
327                                         status = AE_OK;
328                                 }
329
330                                 if (status == AE_CTRL_TERMINATE) {
331                                         return_ACPI_STATUS(status);
332                                 }
333
334                                 status =
335                                     acpi_ps_complete_op(walk_state, &op,
336                                                         status);
337                                 if (ACPI_FAILURE(status)) {
338                                         return_ACPI_STATUS(status);
339                                 }
340                                 if (acpi_ns_opens_scope
341                                     (acpi_ps_get_opcode_info
342                                      (walk_state->opcode)->object_type)) {
343                                         /*
344                                          * If the scope/device op fails to parse, skip the body of
345                                          * the scope op because the parse failure indicates that
346                                          * the device may not exist.
347                                          */
348                                         ACPI_INFO(("Skipping parse of AML opcode: %s (0x%4.4X)", acpi_ps_get_opcode_name(walk_state->opcode), walk_state->opcode));
349
350                                         /*
351                                          * Determine the opcode length before skipping the opcode.
352                                          * An opcode can be 1 byte or 2 bytes in length.
353                                          */
354                                         opcode_length = 1;
355                                         if ((walk_state->opcode & 0xFF00) ==
356                                             AML_EXTENDED_OPCODE) {
357                                                 opcode_length = 2;
358                                         }
359                                         walk_state->parser_state.aml =
360                                             walk_state->aml + opcode_length;
361
362                                         walk_state->parser_state.aml =
363                                             acpi_ps_get_next_package_end
364                                             (&walk_state->parser_state);
365                                         walk_state->aml =
366                                             walk_state->parser_state.aml;
367                                 }
368
369                                 continue;
370                         }
371
372                         acpi_ex_start_trace_opcode(op, walk_state);
373                 }
374
375                 /*
376                  * Start arg_count at zero because we don't know if there are
377                  * any args yet
378                  */
379                 walk_state->arg_count = 0;
380
381                 switch (op->common.aml_opcode) {
382                 case AML_BYTE_OP:
383                 case AML_WORD_OP:
384                 case AML_DWORD_OP:
385                 case AML_QWORD_OP:
386
387                         break;
388
389                 default:
390
391                         ASL_CV_CAPTURE_COMMENTS(walk_state);
392                         break;
393                 }
394
395                 /* Are there any arguments that must be processed? */
396
397                 if (walk_state->arg_types) {
398
399                         /* Get arguments */
400
401                         status =
402                             acpi_ps_get_arguments(walk_state, aml_op_start, op);
403                         if (ACPI_FAILURE(status)) {
404                                 status =
405                                     acpi_ps_complete_op(walk_state, &op,
406                                                         status);
407                                 if (ACPI_FAILURE(status)) {
408                                         return_ACPI_STATUS(status);
409                                 }
410                                 if ((walk_state->control_state) &&
411                                     ((walk_state->control_state->control.
412                                       opcode == AML_IF_OP)
413                                      || (walk_state->control_state->control.
414                                          opcode == AML_WHILE_OP))) {
415                                         /*
416                                          * If the if/while op fails to parse, we will skip parsing
417                                          * the body of the op.
418                                          */
419                                         parser_state->aml =
420                                             walk_state->control_state->control.
421                                             aml_predicate_start + 1;
422                                         parser_state->aml =
423                                             acpi_ps_get_next_package_end
424                                             (parser_state);
425                                         walk_state->aml = parser_state->aml;
426
427                                         ACPI_ERROR((AE_INFO,
428                                                     "Skipping While/If block"));
429                                         if (*walk_state->aml == AML_ELSE_OP) {
430                                                 ACPI_ERROR((AE_INFO,
431                                                             "Skipping Else block"));
432                                                 walk_state->parser_state.aml =
433                                                     walk_state->aml + 1;
434                                                 walk_state->parser_state.aml =
435                                                     acpi_ps_get_next_package_end
436                                                     (parser_state);
437                                                 walk_state->aml =
438                                                     parser_state->aml;
439                                         }
440                                         ACPI_FREE(acpi_ut_pop_generic_state
441                                                   (&walk_state->control_state));
442                                 }
443                                 op = NULL;
444                                 continue;
445                         }
446                 }
447
448                 /* Check for arguments that need to be processed */
449
450                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
451                                   "Parseloop: argument count: %8.8X\n",
452                                   walk_state->arg_count));
453
454                 if (walk_state->arg_count) {
455                         /*
456                          * There are arguments (complex ones), push Op and
457                          * prepare for argument
458                          */
459                         status = acpi_ps_push_scope(parser_state, op,
460                                                     walk_state->arg_types,
461                                                     walk_state->arg_count);
462                         if (ACPI_FAILURE(status)) {
463                                 status =
464                                     acpi_ps_complete_op(walk_state, &op,
465                                                         status);
466                                 if (ACPI_FAILURE(status)) {
467                                         return_ACPI_STATUS(status);
468                                 }
469
470                                 continue;
471                         }
472
473                         op = NULL;
474                         continue;
475                 }
476
477                 /*
478                  * All arguments have been processed -- Op is complete,
479                  * prepare for next
480                  */
481                 walk_state->op_info =
482                     acpi_ps_get_opcode_info(op->common.aml_opcode);
483                 if (walk_state->op_info->flags & AML_NAMED) {
484                         if (op->common.aml_opcode == AML_REGION_OP ||
485                             op->common.aml_opcode == AML_DATA_REGION_OP) {
486                                 /*
487                                  * Skip parsing of control method or opregion body,
488                                  * because we don't have enough info in the first pass
489                                  * to parse them correctly.
490                                  *
491                                  * Completed parsing an op_region declaration, we now
492                                  * know the length.
493                                  */
494                                 op->named.length =
495                                     (u32) (parser_state->aml - op->named.data);
496                         }
497                 }
498
499                 if (walk_state->op_info->flags & AML_CREATE) {
500                         /*
501                          * Backup to beginning of create_XXXfield declaration (1 for
502                          * Opcode)
503                          *
504                          * body_length is unknown until we parse the body
505                          */
506                         op->named.length =
507                             (u32) (parser_state->aml - op->named.data);
508                 }
509
510                 if (op->common.aml_opcode == AML_BANK_FIELD_OP) {
511                         /*
512                          * Backup to beginning of bank_field declaration
513                          *
514                          * body_length is unknown until we parse the body
515                          */
516                         op->named.length =
517                             (u32) (parser_state->aml - op->named.data);
518                 }
519
520                 /* This op complete, notify the dispatcher */
521
522                 if (walk_state->ascending_callback != NULL) {
523                         walk_state->op = op;
524                         walk_state->opcode = op->common.aml_opcode;
525
526                         status = walk_state->ascending_callback(walk_state);
527                         status =
528                             acpi_ps_next_parse_state(walk_state, op, status);
529                         if (status == AE_CTRL_PENDING) {
530                                 status = AE_OK;
531                         } else
532                             if ((walk_state->
533                                  parse_flags & ACPI_PARSE_MODULE_LEVEL)
534                                 && (ACPI_AML_EXCEPTION(status)
535                                     || status == AE_ALREADY_EXISTS
536                                     || status == AE_NOT_FOUND)) {
537                                 /*
538                                  * ACPI_PARSE_MODULE_LEVEL flag means that we
539                                  * are currently loading a table by executing
540                                  * it as a control method. However, if we
541                                  * encounter an error while loading the table,
542                                  * we need to keep trying to load the table
543                                  * rather than aborting the table load (setting
544                                  * the status to AE_OK continues the table
545                                  * load). If we get a failure at this point, it
546                                  * means that the dispatcher got an error while
547                                  * trying to execute the Op.
548                                  */
549                                 status = AE_OK;
550                         }
551                 }
552
553                 status = acpi_ps_complete_op(walk_state, &op, status);
554                 if (ACPI_FAILURE(status)) {
555                         return_ACPI_STATUS(status);
556                 }
557
558         }                       /* while parser_state->Aml */
559
560         status = acpi_ps_complete_final_op(walk_state, op, status);
561         return_ACPI_STATUS(status);
562 }