Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
[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 - 2021, 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                                     && !ACPI_CNTL_EXCEPTION(status)) {
268                                         if (status == AE_AML_NO_RETURN_VALUE) {
269                                                 ACPI_EXCEPTION((AE_INFO, status,
270                                                                 "Invoked method did not return a value"));
271                                         }
272
273                                         ACPI_EXCEPTION((AE_INFO, status,
274                                                         "GetPredicate Failed"));
275                                         return_ACPI_STATUS(status);
276                                 }
277
278                                 status =
279                                     acpi_ps_next_parse_state(walk_state, op,
280                                                              status);
281                         }
282
283                         acpi_ps_pop_scope(parser_state, &op,
284                                           &walk_state->arg_types,
285                                           &walk_state->arg_count);
286                         ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
287                                           "Popped scope, Op=%p\n", op));
288                 } else if (walk_state->prev_op) {
289
290                         /* We were in the middle of an op */
291
292                         op = walk_state->prev_op;
293                         walk_state->arg_types = walk_state->prev_arg_types;
294                 }
295         }
296 #endif
297
298         /* Iterative parsing loop, while there is more AML to process: */
299
300         while ((parser_state->aml < parser_state->aml_end) || (op)) {
301                 ASL_CV_CAPTURE_COMMENTS(walk_state);
302
303                 aml_op_start = parser_state->aml;
304                 if (!op) {
305                         status =
306                             acpi_ps_create_op(walk_state, aml_op_start, &op);
307                         if (ACPI_FAILURE(status)) {
308                                 /*
309                                  * ACPI_PARSE_MODULE_LEVEL means that we are loading a table by
310                                  * executing it as a control method. However, if we encounter
311                                  * an error while loading the table, we need to keep trying to
312                                  * load the table rather than aborting the table load. Set the
313                                  * status to AE_OK to proceed with the table load.
314                                  */
315                                 if ((walk_state->
316                                      parse_flags & ACPI_PARSE_MODULE_LEVEL)
317                                     && ((status == AE_ALREADY_EXISTS)
318                                         || (status == AE_NOT_FOUND))) {
319                                         status = AE_OK;
320                                 }
321                                 if (status == AE_CTRL_PARSE_CONTINUE) {
322                                         continue;
323                                 }
324
325                                 if (status == AE_CTRL_PARSE_PENDING) {
326                                         status = AE_OK;
327                                 }
328
329                                 if (status == AE_CTRL_TERMINATE) {
330                                         return_ACPI_STATUS(status);
331                                 }
332
333                                 status =
334                                     acpi_ps_complete_op(walk_state, &op,
335                                                         status);
336                                 if (ACPI_FAILURE(status)) {
337                                         return_ACPI_STATUS(status);
338                                 }
339                                 if (acpi_ns_opens_scope
340                                     (acpi_ps_get_opcode_info
341                                      (walk_state->opcode)->object_type)) {
342                                         /*
343                                          * If the scope/device op fails to parse, skip the body of
344                                          * the scope op because the parse failure indicates that
345                                          * the device may not exist.
346                                          */
347                                         ACPI_INFO(("Skipping parse of AML opcode: %s (0x%4.4X)", acpi_ps_get_opcode_name(walk_state->opcode), walk_state->opcode));
348
349                                         /*
350                                          * Determine the opcode length before skipping the opcode.
351                                          * An opcode can be 1 byte or 2 bytes in length.
352                                          */
353                                         opcode_length = 1;
354                                         if ((walk_state->opcode & 0xFF00) ==
355                                             AML_EXTENDED_OPCODE) {
356                                                 opcode_length = 2;
357                                         }
358                                         walk_state->parser_state.aml =
359                                             walk_state->aml + opcode_length;
360
361                                         walk_state->parser_state.aml =
362                                             acpi_ps_get_next_package_end
363                                             (&walk_state->parser_state);
364                                         walk_state->aml =
365                                             walk_state->parser_state.aml;
366                                 }
367
368                                 continue;
369                         }
370
371                         acpi_ex_start_trace_opcode(op, walk_state);
372                 }
373
374                 /*
375                  * Start arg_count at zero because we don't know if there are
376                  * any args yet
377                  */
378                 walk_state->arg_count = 0;
379
380                 switch (op->common.aml_opcode) {
381                 case AML_BYTE_OP:
382                 case AML_WORD_OP:
383                 case AML_DWORD_OP:
384                 case AML_QWORD_OP:
385
386                         break;
387
388                 default:
389
390                         ASL_CV_CAPTURE_COMMENTS(walk_state);
391                         break;
392                 }
393
394                 /* Are there any arguments that must be processed? */
395
396                 if (walk_state->arg_types) {
397
398                         /* Get arguments */
399
400                         status =
401                             acpi_ps_get_arguments(walk_state, aml_op_start, op);
402                         if (ACPI_FAILURE(status)) {
403                                 status =
404                                     acpi_ps_complete_op(walk_state, &op,
405                                                         status);
406                                 if (ACPI_FAILURE(status)) {
407                                         return_ACPI_STATUS(status);
408                                 }
409                                 if ((walk_state->control_state) &&
410                                     ((walk_state->control_state->control.
411                                       opcode == AML_IF_OP)
412                                      || (walk_state->control_state->control.
413                                          opcode == AML_WHILE_OP))) {
414                                         /*
415                                          * If the if/while op fails to parse, we will skip parsing
416                                          * the body of the op.
417                                          */
418                                         parser_state->aml =
419                                             walk_state->control_state->control.
420                                             aml_predicate_start + 1;
421                                         parser_state->aml =
422                                             acpi_ps_get_next_package_end
423                                             (parser_state);
424                                         walk_state->aml = parser_state->aml;
425
426                                         ACPI_ERROR((AE_INFO,
427                                                     "Skipping While/If block"));
428                                         if (*walk_state->aml == AML_ELSE_OP) {
429                                                 ACPI_ERROR((AE_INFO,
430                                                             "Skipping Else block"));
431                                                 walk_state->parser_state.aml =
432                                                     walk_state->aml + 1;
433                                                 walk_state->parser_state.aml =
434                                                     acpi_ps_get_next_package_end
435                                                     (parser_state);
436                                                 walk_state->aml =
437                                                     parser_state->aml;
438                                         }
439                                         ACPI_FREE(acpi_ut_pop_generic_state
440                                                   (&walk_state->control_state));
441                                 }
442                                 op = NULL;
443                                 continue;
444                         }
445                 }
446
447                 /* Check for arguments that need to be processed */
448
449                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
450                                   "Parseloop: argument count: %8.8X\n",
451                                   walk_state->arg_count));
452
453                 if (walk_state->arg_count) {
454                         /*
455                          * There are arguments (complex ones), push Op and
456                          * prepare for argument
457                          */
458                         status = acpi_ps_push_scope(parser_state, op,
459                                                     walk_state->arg_types,
460                                                     walk_state->arg_count);
461                         if (ACPI_FAILURE(status)) {
462                                 status =
463                                     acpi_ps_complete_op(walk_state, &op,
464                                                         status);
465                                 if (ACPI_FAILURE(status)) {
466                                         return_ACPI_STATUS(status);
467                                 }
468
469                                 continue;
470                         }
471
472                         op = NULL;
473                         continue;
474                 }
475
476                 /*
477                  * All arguments have been processed -- Op is complete,
478                  * prepare for next
479                  */
480                 walk_state->op_info =
481                     acpi_ps_get_opcode_info(op->common.aml_opcode);
482                 if (walk_state->op_info->flags & AML_NAMED) {
483                         if (op->common.aml_opcode == AML_REGION_OP ||
484                             op->common.aml_opcode == AML_DATA_REGION_OP) {
485                                 /*
486                                  * Skip parsing of control method or opregion body,
487                                  * because we don't have enough info in the first pass
488                                  * to parse them correctly.
489                                  *
490                                  * Completed parsing an op_region declaration, we now
491                                  * know the length.
492                                  */
493                                 op->named.length =
494                                     (u32) (parser_state->aml - op->named.data);
495                         }
496                 }
497
498                 if (walk_state->op_info->flags & AML_CREATE) {
499                         /*
500                          * Backup to beginning of create_XXXfield declaration (1 for
501                          * Opcode)
502                          *
503                          * body_length is unknown until we parse the body
504                          */
505                         op->named.length =
506                             (u32) (parser_state->aml - op->named.data);
507                 }
508
509                 if (op->common.aml_opcode == AML_BANK_FIELD_OP) {
510                         /*
511                          * Backup to beginning of bank_field declaration
512                          *
513                          * body_length is unknown until we parse the body
514                          */
515                         op->named.length =
516                             (u32) (parser_state->aml - op->named.data);
517                 }
518
519                 /* This op complete, notify the dispatcher */
520
521                 if (walk_state->ascending_callback != NULL) {
522                         walk_state->op = op;
523                         walk_state->opcode = op->common.aml_opcode;
524
525                         status = walk_state->ascending_callback(walk_state);
526                         status =
527                             acpi_ps_next_parse_state(walk_state, op, status);
528                         if (status == AE_CTRL_PENDING) {
529                                 status = AE_OK;
530                         } else
531                             if ((walk_state->
532                                  parse_flags & ACPI_PARSE_MODULE_LEVEL)
533                                 && (ACPI_AML_EXCEPTION(status)
534                                     || status == AE_ALREADY_EXISTS
535                                     || status == AE_NOT_FOUND)) {
536                                 /*
537                                  * ACPI_PARSE_MODULE_LEVEL flag means that we
538                                  * are currently loading a table by executing
539                                  * it as a control method. However, if we
540                                  * encounter an error while loading the table,
541                                  * we need to keep trying to load the table
542                                  * rather than aborting the table load (setting
543                                  * the status to AE_OK continues the table
544                                  * load). If we get a failure at this point, it
545                                  * means that the dispatcher got an error while
546                                  * trying to execute the Op.
547                                  */
548                                 status = AE_OK;
549                         }
550                 }
551
552                 status = acpi_ps_complete_op(walk_state, &op, status);
553                 if (ACPI_FAILURE(status)) {
554                         return_ACPI_STATUS(status);
555                 }
556
557         }                       /* while parser_state->Aml */
558
559         status = acpi_ps_complete_final_op(walk_state, op, status);
560         return_ACPI_STATUS(status);
561 }